通道操作
根据需要对通道进行拆分和合并。
通道拆分
- 通过索引拆分
通过索引的方式,可以直接将各个通道从图像内提取出来。例如针对BGR 图像Img
额,,我一直想知道单提出来某个通道为什么是灰的。。。
- 通过函数拆分
import cv2
lena=cv2.imread("5.jpg")
b,g,r=cv2.split(lena) # 拆分通道,b=cv2.split(lena)[0] 一样的
cv2.imshow("B",b)
cv2.imshow("G",g)
cv2.imshow("R",r)
cv2.waitKey()
cv2.destroyAllWindows()
通道合并
按两种方式合并,,也挺好看的。。。
获取图像属性
- shape:如果是彩图,返回包含行数,列数,通道数的数组,如果是二值图或灰度图,仅返回行数和列数。可以通过返回值判断是否是彩图
- size:返回图像的像素数目,值为 行 X 列 X 通道数,灰度或二值图通道为1
- dtype :返回图像的数据类型
color=cv2.imread("5.jpg")
print("color.shape=",color.shape)
print("color.size=",color.size)
print("color.dtype=",color.dtype)
color.shape= (707, 500, 3)
color.size= 1060500
color.dtype= uint8
图像运算
很多复杂的图像处理功能就是通过基础的加法运算,位运算来完成的。
图像加法运算
可以通过 + or cv2.add() 来完成,对于灰度图,相加后像素值的范围可能超过255,以上两种对这种超过255的处理方式不一样。
加号运算符
mod() 是取模运算,mod(a+b,256) 表示 a+b 的和除以256取余数
上面的公式也可以直接写 𝑎 + 𝑏 = mod(𝑎 + 𝑏, 256) ,无论是否大于256,都是取模。
通过将数组的数值类型定义为dtype=np.uint8,可以保证数值范围在 [0-255] ,并且是由这个类型来决定取模运算。
cv2.add() 函数
这个进行求和运算,会得到像素值对应图像的饱和值,例如 8位灰度图像的饱和值就是255.
cv2.add() 的参数可以有三种形式:
- 计算结果=cv2.add(图像 1,图像 2),参与运算的图像大小和类型必须一致
- 计算结果=cv2.add(数值,图像) ,超过饱和值的,就是饱和值
- 计算结果=cv2.add(图像,数值),超过饱和值的就是饱和值
加号就是让更亮的像素点暗了,add 就是整体变亮。
图像加权和
就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,公式表示为
其中,saturate() 表示饱和值,加权和计算时,两个图像必须大小,类型相同,对具体是什么类型和通道没有限制,可以是任意类型,有任何数量的通道(灰度或彩图)。
opencv 使用函数cv2.addWeighted() 来实现图像的加权和(混合,融合) dst=cv2.addWeighted(src1, alpha, src2, beta, gamma)
但是其中 gamma 不可省略,可以是0.上式可以理解为 结果通向=图像1 X 系数1 + 图像2 X 系数2 + 亮度调节
a=cv2.imread("5.jpg")
b=cv2.imread("7.jpg")
result=cv2.addWeighted(a,0.6,b,0.4,0) # 按这个比例混合,
cv2.imshow("boat",a)
cv2.imshow("lena",b)
cv2.imshow("result",result)
cv2.waitKey()
cv2.destroyAllWindows()
按位逻辑运算
逻辑运算是一种非常重要的运算方式,图像处理过程种经常要按照位进行逻辑运算,简称位运算
按位与运算
都真则为真。将数值转换成二进制,对应位上进行按位与。
输出=cv2.bitwise_and( 数值1,数值2,[掩码] )
- 任何数值N 与 0 进行按位与,都是获得数值0.
- 任何数值N(这里仅考虑8位值)与数值255(1111 1111)进行位与 获得数值N本身。
根据上述特点,可以构造一副掩模图M,掩模图M 中只有两种值,0和255.将该掩模图与一副灰度图G 进行位与,在得到的图像R 中:
- 与掩模图M中的数值 255 对应位置上的值来源于灰度图G
- 掩模图M中的数值0的位置为黑色。
构造一个掩模图,使用按位与来保留图像中被掩膜指定的部分。
针对BGR模式的彩图使用掩膜提取指定部分,可以通过将掩模图转换成BGR 模式的彩图然后再与图像按位与,实现掩膜运算。
可以看到变成彩图了。。再构建b 时, a.shape 将掩模图转换成了三通道的彩图吧。。。
按位或运算
有一个是1 则为 1.
dst = cv2.bitwise_or( src1, src2[, mask]] )
按位非运算
取反操作
按位异或运算
就跟不带进位的加法运算一样。
掩模
Opencv中有很多函数都会指定一个掩模,也叫掩码,就是上面那个mask。还有 cv2.add( 参数1,参数2,掩模)
但是用掩模参数时,操作只会再掩模值为非空的像素点上执行,并将其他像素点的值置零。
上面为了使掩模图与彩图进行按位与运算,将掩模图转换成了三通道的彩图,实际上可以使用cv2.bitwise_and( src1, src2[, mask]] ) 的mask 参数,这个就可以是8位单通道图像,将要处理的彩图同时作为两个参数,使用掩模图作掩码参数,效果一样的。要注意,彩图自身按位与运算得到的还是本身,然后使用掩码来决定显示那部分。