Opencv入门系列二
1.加法
图像加法:将图像矩阵对应位置进行加法的运算。
处理方法:可以使用运算符 + 和 cv2.add() 函数 。由于8位(uint8)表示像素值有 0-255 。故存在加法导致溢出255的情况,两种方法在处理溢出有不同的机制。
1.1 方法1:使用运算符 +
运算符+:result = mod(img1+img2,256)总是取余数。
imgAdd = Img3 + Img4 #图像对应位置相加
处理机制如下
1.2 方法2:使用cv2.add()
cv2.add()实现两个图像矩阵的加法运算,其语法格式为:
imgAdd = cv2.add(Img1,Img2) #图像对应位置相加
imgAdd1 = cv2.add(4,Img2) #图像各位置加4
imgAdd2 = cv2.add(Img1,4) #图像各位置加4
处理机制如下:
实验程序 1
import cv2
import numpy as np
#随机创建两个图像矩阵
Img3 = np.random.randint(0,255,size = [250,250],dtype=np.uint8)
Img4 = np.random.randint(0,255,size = [250,250],dtype=np.uint8)
# 实验add方法和 +的区别
imgAdd = Img3 + Img4
imgAdd2 = cv2.add(Img3,Img4)
cv2.imshow("Img3",Img3)
cv2.imshow("Img4",Img4)
cv2.imshow("ImgAdd1",imgAdd)
cv2.imshow("ImgAdd2",imgAdd2)
# 实验add方法参数为数字
imgAdd3= cv2.add(4,Img4)
imgAdd4= cv2.add(Img4,4)
print(Img4)
print(imgAdd3)
print(imgAdd4)
cv2.waitKey(0)
1.3 方法3 :加权加法cv2.addWeighted()
cv2.addWeighted()用来实现图像的加权加法,用于图像的混合、融合。其语法格式如:
对应数学公式如下:
可以理解为:结果图像=图像1×系数1+图像2×系数2+亮度调节量
- src1:图像1
- alpha:图像1的权值
- src2:图形2
- beta:图像2的权值
- gamma:常数(通常是用来调节图像的亮度)
实验程序 2
使用cv2.addWeighted()将两个用np.ones()创建的图像进行加权加法
import cv2
import numpy as np
imgOnes1 = np.ones((3,3),dtype=np.uint8)*10 #创建一个大小为[3,3]的灰度图像,全部填充10
imgOnes2 = np.ones((3,3),dtype=np.uint8)*5 #创建一个大小为[3,3]的灰度图像,全部填充5
print(imgOnes1)
print(imgOnes2)
imgAddWeighted = cv2.addWeighted(imgOnes1,0.4,imgOnes2,0.6,3)#将两幅图像进行融合
print(imgAddWeighted)
cv2.imshow("imgAddWeighted",imgAddWeighted)
cv2.waitKey(0)
由结果可知:10×0.4 + 5×0.6 + 3 = 10
通常我们还可以用cv2.addWeighed()实现两幅图像的融合。
np.ones()
np.ones((m,n),dtype=np.uint8)*value #创建一个大小为[m,n]的灰度图像,全部填充value value=1时可以省略
2.逻辑运算
2.1 按位逻辑与cv2.bitwise_and()
按位逻辑与:按位指的是二进制情况下。
cv2.bitwise_and()实现按位逻辑与操作,其语法如下:
● dst表示按位与操作后的图像
● src1表示算子图像1
● src2表示算子图像2
● mask表示可选操作掩码,8位单通道array。
掩膜图像:像素值只有0和255的图像。0-为黑色,255-为白色。
应用:
① 对灰度图像进行掩模处理,
② 还经常需要针对BGR模式的彩色图像使用掩模提取指定部分。由于按位与操作要求参与运算的数据有相同的通道,所以无法直接将彩色图像与单通道的掩模图像进行按位与操作。一般情况下,可以通过将掩模图像转换为BGR模式的彩色图像,让彩色图像与掩模图像进行按位与操作,实现掩模运算。
22 按位逻辑或cv2.bitwise_or()
cv2.bitwise_or()实现按位逻辑或操作,其语法如下:
● dst表示按位或操作后的图像
● src1表示算子图像1
● src2表示算子图像2
● mask表示可选操作掩码,8位单通道array。
2.3 按位逻辑非cv2.bitwise_not()
cv2.bitwise_not()实现按位逻辑非操作,其语法如下:
● dst表示按位非操作后的图像
● src表示算子图像
● mask表示可选操作掩码,8位单通道array。
2.4按位逻辑异或cv2.bitwise_xor()
cv2.bitwise_xor()实现按位逻辑异或操作,其语法如下:
● dst表示按位异或操作后的图像
● src1表示算子图像1
● src2表示算子图像2
● mask表示可选操作掩码,8位单通道array。
2.5掩膜mask参数
当使用掩模参数时,操作只会在掩模值为非零的像素点上执行。如下掩码
仅有值为1的部分参与运算。(当然1可以是任何非0数值),掩码为0部分计算值总是0。
进行img3 = cv2.add(img1,img2,mask=mask)操作时,结果如下:
前面的掩膜图像(即只有0和255)是在实现按位逻辑与掩膜的一种特殊方法。
3. 位平面分解
位平面分解:每一个像素点为一个8位的像素值,将其0-255可以化为8位二进制数。将整个图形中每个像素点第n位二进制数提出来作为一个图像的过程,称之为位平面分解。
二进制形式如下:
①:a7-a1对应了不同的权重,权重的大小体现出对应位与原图的相关性大小。a7最大(第七层),a1最小(第一层)。
②:灰度图像仅仅只有一个通道,一个像素点仅仅只有八位,所以一副灰度图像有且仅有 八个位平面。但在BGR三个通道,故有24个位平面。通常将层数相同的三个通道组合起来作为一副分解出的BGR彩色位平面图像。
③:通过按位逻辑运算可以实现位平面的分解
3.1 逻辑分解法
按位与提取法:
1&任何数字 = 任何数字
0&任何数字 = 0
故我们可以找到一个算子来提取第n位,这个算子mat需要满足提取位为1,其他位为0。如下:
通过按位与提取法提取的位平面result通常只含有0和(1,2,4,8,16,32,64,128)中两个数字,在低层位平面中由于像素值差别太小,无法分辨出颜色,此时要进行阈值处理。
阈值处理:将大于0的值上升为255。具体语法为:
程序示例
位平面分解示例如下:
import cv2
import numpy as np
loadImg = cv2.imread("Resources/lena.png",0)
print(loadImg)
w,h = loadImg.shape #获取图片大小
mat = np.zeros((w,h,8),dtype=np.uint8)#创建算子
for init in range(8):#初始化算子为1,2,4,8,16,32,64,128
mat[:,:,init] = 2**init
print(mat[:,:,init])
cv2.imshow("imgLoad",loadImg)
result = np.zeros((w,h,8),dtype=np.uint8)
for i in range(8):
result[:,:,i] = cv2.bitwise_and(loadImg,mat[:,:,i]) #提取第r位位平面
mask = result[:,:,i]>0 #提取掩码用于阈值处理
result[mask] = 255 #阈值处理
cv2.imshow(str(i),result[:,:,i]) #显示出来
cv2.waitKey(0)
cv2.destroyAllWindows()
4.图像的加密和解密
原理:
假如有a,b两个整型数,我们可以用
a=a^b;
b=b^a;
a=a^b;
任何一位二进制数同 1 异或都会改变状态
任何一位二进制数同 0 异或都保持不变
● a:明文,原始数据。● b:密钥。● c:密文,通过xor(a, b)实现
a^c = b 异或得到密文
b^c = a 密文再次异或解密
● 加密过程:将明文a与密钥b进行按位异或,完成加密,得到密文c。
● 解密过程:将密文c与密钥b进行按位异或,完成解密,得到明文a。