简介;本文深入探讨了 OpenCV 中的图像运算知识。详细介绍了图像加法,包括使用 cv2.add 实现普通加法以及 cv2.addWeighted 进行加权和运算,并以实例展示操作过程。同时深入剖析位运算,阐述按位与运算在掩膜提取和位平面分解方面的应用,如用于图像修复、医学图像诊断辅助等;讲解按位异或运算原理及其在图像加密和解密中的独特作用,通过具体代码示例展示如何利用异或实现图像加密与还原,为读者全面掌握 OpenCV 图像运算技巧提供详实指南。
OpenCV 图像运算全解析:加法、位运算(与、异或)在图像处理中的奇妙应用
1 图像加法
1.1 add
加法运算 使用 cv2.add(图像,数值\图像)
这个函数的特点是:超出255的部分按255算
在我这个代码在的文件夹下有两张图片:blue_pig.JPG和pig.jpg
要实现这两张图片的加法。第一步就是使用cv2.resize使得两者图片的shape一致,然后在使用cv2.add函数进行加法运算
import numpy as np
import cv2
red = cv2.imread("pig.jpg")
blue = cv2.imread("blue_pig.JPG")
# print(red.shape)
# print(blue.shape)
height,width,channel = red.shape
blue = cv2.resize(blue,(width,height))
# print(blue.shape)
add_Image = cv2.add(blue,red)
cv2.imshow("add_image",add_Image)
cv2.waitKey()
cv2.destroyAllWindows
1.2 addWeighted
他的作用是实现两幅图像的加权和,每一张图像按设定好的比率完成加法
image = cv2.addWeighted(图片1,比率1,图片2 ,比率2,亮度调节值)
还是那两张图,我现在想要按照超人强7成,猪猪侠四成来进行加权和,gamma亮度调节值就是在灰度值上增大多少,目前没有这个需求但是这是个必选参数,不写会报错。
import numpy as np
import cv2
red = cv2.imread("pig.jpg")
blue = cv2.imread("blue_pig.JPG")
height,width,channel = red.shape
blue = cv2.resize(blue,(width,height))
add_Image = cv2.addWeighted(blue,0.7,red,0.4,gamma=1)
cv2.imshow("addWeighted_image",add_Image)
cv2.waitKey()
cv2.destroyAllWindows()
2 位运算
2.1 按位与运算
首先解释什么是与运算
0 and 1 = 0
0 and 0 = 0
1 and 0 = 0
1 and 1 = 1
只有两者均为1 的时候是真
其次,解释什么是按位与运算
因为灰度值他是从0-255,所以他需要8位二进制存储空间,
每一位分别进行与运算就是按位与运算
那么他的目的有两个:
目的1:进行掩膜,比如一张画损毁了一部分,要修复他,那怎么不影响未损毁位置呢,设计一张跟画相同大小的,没有损毁的位置在对应的新图上设计为0000 0000 ,损毁的部分设计为1111 1111。拿新图和原图进行与运算,就可以把要修复的部分提取出来了,他也叫做掩膜。案例请看2.1.1 掩膜
目的2 :位平面分割,假设对于一张单通道图像,那么他可以根据位运算,分解八张不同的位平面。位平面分解有很重要的意义。详解和案例请看2.1.2 位平面分解
2.1.1 掩膜
在这张图里,其余部分全是黑色的0,只有在选定区域才是跟255与运算得到的原图选定部分,这就是掩膜的作用
import numpy as np
import cv2
red = cv2.imread("pig.jpg")
height,width,channel = red.shape
new_image = np.zeros((height,width,channel),dtype = np.uint8)
new_image[300:600,50:350]=255
bit_and_image = cv2.bitwise_and(red,new_image)
cv2.imshow("bit_and",bit_and_image)
cv2.waitKey()
cv2.destroyAllWindows()
2.1.2 位平面分解
他可以有多中用途:比如图片的压缩,医生研究图像可以更清晰地观察骨骼结构(在高位平面可能更明显)和软组织细节(可能在低位平面也有体现),帮助医生进行疾病诊断,比如检测骨折
我从网上寻找了一张骨折的图
放在我们文件夹下起名叫stone.JPG
运行下面这段代码:
import numpy as np
import cv2
stone_image = cv2.imread("stone.JPG",flags = 0)
print(stone_image.shape)
height,width = stone_image.shape
x = np.zeros((height,width,8),dtype = np.uint8)
for i in range(8):
x[:,:,i] = 2**i
r = np.zeros((height,width,8),dtype = np.uint8)
for i in range(8):
r[:,:,i]=cv2.bitwise_and(stone_image,x[:,:,i])
mask = r[:,:,i]>0
r[mask] = 255
cv2.imshow(f"{str(i)}",r[:,:,i])
cv2.waitKey()
cv2.destroyAllWindows()
下面这八张图可以看到平面越高,获得的轮廓信息越重要,越低噪声越多
2.2 按位异或运算与加密和解密
首先什么是异或?
a b c
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0
1 xor 0 = 0
两者不同才能得到1
我们现在要着重观察 abc
xor(a,b) = c
换位思考
xor(a,c)=b
xor(b,c)=a
所以我们可以得到一个想法 比如我想对图片a进行加密,我只要让他跟图片b进行异或,得到图片c。我该怎么还原图片a呢?只需要xor(b,c)=a就可以还原了
2.2.1 按位异或运算
使用cv2.bit_xor()
2.2.2 图像加密
还拿猪猪侠pig.jpg进行加密,随机生成一个跟他相同shape的图片,然后使用异或进行加密,然后解密还原
import numpy as np
import cv2
pig = cv2.imread("pig.jpg",flags = 0)
height,width = pig.shape
x = np.random.randint(0,256,size = (height,width),dtype =np.uint8)
decode = cv2.bitwise_xor(x,pig)
encode = cv2.bitwise_xor(decode,x)
cv2.imshow("original",pig)
cv2.imshow("decode_image",decode)
cv2.imshow("encode_image",encode)
cv2.waitKey()
cv2.destroyAllWindows()
致谢
本文参考了一些博主的文章,博取了他们的长处,也结合了我的一些经验,对他们表达诚挚的感谢,使我对加法和位运算 的使用有更深入的了解,也推荐大家去阅读一下他们的文章。纸上学来终觉浅,明知此事要躬行:
OpenCV合并图片cv2.add、无缝连接图片cv2.addWeighted、图片克隆cv2.seamlessClone 效果对比、按位运算bitwise_and
【OpenCV 】第三章: 图像运算:加法运算、位运算、掩码、位平面分解、加密、数字水印、脸部打码