【图像处理opencv】_图像基础

目录

0 程序环境与所学函数

1 自定义图像

2 三种常见图像相互转换

3 通道分离与合并

4 两图像的加减乘除

5 图像线性变换和非线性变换

​6 图像融合


0 程序环境与所学函数

本章程序运行需要导入下面三个库,并定义了一个显示图像的函数

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def show(img):
    if img.ndim == 2:
        plt.imshow(img, cmap='gray')
    else:
        plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.show()

所学函数

## 1. 图像读取
img = cv.imread()

## 2. 彩色图转灰度图
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

## 3. 二值化图像(灰度图转二值图)
_, img_bin = cv.threshold(img_gray, th1, th2, cv.THRESH_BINARY)

## 4. 保存图像
cv.imwrite('pic/bear_gray.jpg', img_gray)

## 5. 通道分离
b, g, r = cv.split(img)

## 6. 通道合并
img_new = cv.merge([b, g, r])

## 7. 两图像相加、相减、相乘、相除
img = cv.add(img1, img2)
img = cv.subtract(img1, img2)
img = cv.multiply(img1, img2)
img = cv.divide(img1, img2)

1 自定义图像

二值图:只有两种取值。

对于计算机来说,图像是一个个数组,数组里面一个数字代表一个像素,0表示黑色,1表示白色

灰度图:对应于一个二维数组,8位灰度图,每个像素有256种取值

真彩色:对应于一个三维数组,(x,y,3)---3表示rgb三通道,r,g,b通道各有8位

假彩色:8位表示256种颜色

程序参考:

b = np.array([
    [0, 127, 255],
    [255, 0, 255],
    [10, 50, 100]
], dtype=np.uint8)

g = b.T
r = b - g

# show(b)
show(cv.merge([b, g, r]))

# cv.imwrite()

2 三种常见图像相互转换

# 读取彩色图
img = cv.imread('pic/bear500x333.jpg')
# print(img)
show(img)

# 读取灰度图
# img_gray = cv.imread('pic/cat200x192.jpg', 0)
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
show(img_gray)

# 二值化图像

thresh= 125    #自定义一个阈值
gray4[gray4 > thresh] = 255 # 表示gray4中大于阈值的点都赋值为255
gray4[gray4 <= thresh] = 0  # 表示gray4中小于阈值的点都赋值为0
show(gray4)


_, img_bin = cv.threshold(img_gray, 150, 255, cv.THRESH_BINARY) #函数表示将灰度图转化为二值图,将图像数组中小于150的值变成0,将值高于150的值变成255,前面有返回值,可以设为ignore
show(img_bin)

# 保存图像
cv.imwrite('pic/bear_gray.jpg', img_gray)
cv.imwrite('pic/bear_bin.jpg', img_bin)

3 通道分离与合并

# 分离BGR通道
# r = img[:,:,0]
b, g, r = cv.split(img)
# b.shape
show(r)

# 合并BGR通道
img_new = cv.merge([b, g, r])
show(img_new)

# rgb转灰度图
img_gray2 = 0.114*b + 0.587*g + 0.299*r
# img_gray2 = (0.299*r + 0.587*g + 0.114*b).astype(np.uint8)
show(img_gray2)

4 两图像的加减乘除

读入两幅图像

bg = cv.imread('pic/line500x500.jpg', 0)
ob = cv.imread('pic/hedgehog500x500.jpg', 0)

show(np.hstack([bg, ob]))

显示如下:

 图像相加:混合图像,添加噪声

# 图像相加
# img_add = cv.add(bg*0.5, ob*0.5)
img_add = bg * 0.5 + ob * 0.5
show(img_add)

#img = cv.addWeighted(img1, alpha, img2, beta, gamma)
img_add2= cv.addWeighted(obj,0.5,bg,0.5,0) #会转换图像数据类型为uint8型而cv.add()不会
show(img_add2)

如果不添加权重,两幅图相加,数值可能会大于255,进入循环成其他数值,造成与预期不符,添加权重后则不会出现这种情况。

 显示结果

 图像相减:消除背景、差影法(比较差异、运动跟踪)

#图像减法
img_sub = (img_add - bg*0.5)*2   # *2之后恢复成原来的前景图
#img_sub = np.uint8((img_add-bg*0.5)*2)  强制转换为无符号8整型
img_sub2 = cv.subtract(img_add,bg*0.5)

show(np.hstack([img_sub,img_sub2]))

显示结果

图像相乘:掩膜

# 图像乘法
mask = mask/255  #这一行只能运行一次,如果多此运行则会不断迭代相除,造成与预期不符发生
img_nul = obj * mask
img_mul2 = cv.multiply(obj*1.0,mask)  #这个函数只能对同类型数组进行操作,转化为浮点数
show(np.hstack([mask,obj,img_mul,img_mul2]))

显示结果

图像相除:校正设备、比较差异

#除法
#img_div = obj / noise
img_div = obj / (np.float64(noise)+1) #避免了除0的情况
#img_div2 = cv.divide(obj,noise)
img_div2 = cv.divide(obj,noise+1)
show(np.hstack([obj,noise,img_div,img_div2]))

显示结果

5 图像线性变换和非线性变换

原理:

 先读入一幅灰度图像并显示其类型

img = cv.imread('pic/cat500x480.jpg',0) # 0表示读取灰度图
show(img)
img.dtype

显示结果:图像数组内值为8位无符号整型

 先按照下面线性函数定义显示以下

b = 20
k = 2
img2 = b + k * img

show(img2)

显示结果:

我们运行不会得到自己想要的结果,因为是无符号八位的,经过线性变换后,可能超过255,会循环成一些我们不希望出现的值。做如下改进:

#改进:
b = 20
k = 2
img2 = b + k * img.astype(np.int32) # astype 按照类型 np.int32型
img2 = np.clip(img2,0,255) #截断函数,小于等于0的变成0,大于等于255的变成255
show(img2)

 opencv里面函数实现 :img= cv.convertScaleAbs(img,alpha=1,beta=0),这个函数将数组内小于等于0的值变为0,大于等于255的值变为255,s=b+kr,alpha相当于k,beta相当于b,程序如下

img3 = cv.convertScaleAbs(img,alpha=2,beta=3)
show(img3)

结果显示:

非线性变换---对数变换

img4 = 10 + np.log(img.astype(np.float32)+1)/0.1 #防止出现除0的情况出现

show(img4)

结果显示

 非线性变换---指数变换(伽马变换)

img01 = img / 255   #每运行一次就会更改一次,这一行运行一次就好,不然会与预期不符

img05 = np.power(img01,0.5)*255
img15 = np.power(img01,1.5)*255

show(np.hstack([img05,img,img15]))

结果显示:指数小于1的图像变亮,指数大于1的图像变暗,与原理图示相符合。

6 图像融合

读取图像并显示:

A = cv.imread('pic/petal500x500.jpg')
B = cv.imread('pic/hedgehog500x500.jpg')
M = cv.imread('pic/mask500x500.jpg')

show(np.hstack([A,B,M]))

显示

相关操作

M = M/255              #注意,这行程序只能运行一遍,多次运行造成与预期不符
As = A * (1 - M) 
Bs =B * M

show(np.uint8(np.hstack([As,Bs])))

结果显示:

 进行融合

nice = cv.add(As,Bs*0.8)
show(nice.astype(np.uint8))

最终融合结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯丰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值