文章目录
- 2.2.1 按位与 cv2.bitwise_and()
- 2.2.2 按位或 cv2.bitwise_or()
- 2.2.3 按位取反 cv2.bitwise_not()
- 2.2.4 按位异或 cv2.bitwise_xor()
1.图像的掩模
掩模,即掩码(mask)。用计算机处理图像时,常常是有的内容需要处理,有的内容不需要处理。通过掩模,可以实现将我们不需要处理的部分暂时“遮住”,以保证其保持不变。而仅仅操作其暴露出来的部分。整个操作过程就像做手术时医生使用的“手术洞巾”。
掩模过程通常使用二值图像表示,像素值0表示纯黑色,其区域表示我们不需要操作的部分。像素值为255的纯白色部分表示我们想要操作的部分。(某些情况也可以用0,1作为掩模值)。掩模对象通过操作numpy数组创建,没有专有方法。
以下边这幅名画《思考的男人》为例,我们对其进行掩模操作测试。
此图片长1080,高810,途中正在饭桌上思考的男人,名叫莱纳。
我们的目的是尽可能地覆盖莱纳上半身之外的大多部分,下边界以右边瓶子瓶口为界限。
在莱纳所坐位置用一个矩形将其框出,该矩形四个点的坐标大致为
A.(568, 28) B.(1044, 28)
C.(568, 430) D.(1044, 430)
(坐标可以通过画图工具估计。)
掩码代码如下:
import cv2 import numpy as np mask = np.zeros((810, 1080, 1), np.uint8) mask[28:430, 568:1044, :] = 255 cv2.imshow("mas", mask) cv2.waitKey() cv2.destroyAllWindows()
程序执行效果如下:
此即该图片的掩模图像:
2.图像的运算
2.1 图像的加法运算
两幅图像相加即相同位置的像素值之间一 一相加。图像的相加通常有两种方法,一种是使用“+”符号连接两个数组,另一种则是使用add() 方法。
2.1.1 “+”方法
使用“+”这种方法我们在做图像处理时通常不会采用,因为相加后的像素值精彩会出现大于255的情况。而大于255的像素值,则会取该值除以255后的余数,即取模。因此原图中白色的衣服,经过加法运算后反而颜色变暗了。
import cv2 img = cv2.imread("pic.jpg") result_pic = img + img cv2.imshow("+", result_pic) cv2.waitKey() cv2.destroyAllWindows()
2.1.2 cv2.add()方法
cv2.add()相加得到的图像,如果存在像素值大于255,取255。 这一点相比使用加号要好得多,明显更利于我们的图像处理。
使用cv2.add()方法,该方法语法如下:
add(src1, src2, mask=None, dtype=None)
- src1 与 src2 即需要相加的两幅图像
- mask是可选参数,掩模对象。默认没有
- dtype 图像深度。
import cv2 img = cv2.imread("trump.jpg") result_pic = cv2.add(img, img) cv2.imshow("add", result_pic) cv2.waitKey() cv2.destroyAllWindows()
2.1.3 使用掩模遮盖相加结果
图像相加时,可以讲掩模图像也作为参数传进去,对相加结果进行掩模。
import cv2 import numpy as np img = cv2.imread("pic.jpg") # 细节 m = np.zeros((810, 1080, 1), np.uint8) m[28:430, 568:1044, :] = 255 image5 = cv2.add(img, img, mask=m) cv2.imshow("use mask", image5) cv2.waitKey() cv2.destroyAllWindows()
图像处理结果:
值得注意的是,这里有一个非非非非非非非非非常重要的细节,很多人都会在这里被卡壳(很显然博主也被卡了)。就是掩模对象是灰度图像,不是说看起来是灰度图像,而是数组要是灰度图像的数组,即创建的到时候m = np.zeros((a, b, 1), np.uint8)中 (a, b, 1)最后一个数字是1,不能顺手写成3。 否者就会有下面的报错:
image5 = cv2.add(img, img, mask=m)
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:706: error: (-215:Assertion failed) (mtype == CV_8UC1 || mtype == CV_8SC1) && _mask.sameSize(*psrc1) in function ‘cv::arithm_op’
意思是mask的size有问题。
2.2 图像的位运算
位运算是二进制数字特有的运算,图像的像素数组中的十进制数字也可以转化为二进制数字,然后就可以进行位运算了。
OpenCV提供了以下位运算方法
- cv2.bitwise_and() 按位与
- cv2.bitwise_or() 按位或
- cv2.bitwise_not() 按位取反
- cv2.bitwise_xor() 按位异或
其中
cvbitwise_and() 与 bitwise_or() 方法都有三个参数,scr1,scr2,mask,即图像1,图像2与掩码
cv2.bitwise_not() 与 cv2.bitwise_xor()方法都有两个参数,scr与mask,即图像与掩码。
2.2.1 按位与 cv2.bitwise_and()
让掩模与目标图像做与运算,同样可以达到掩模遮盖图像的处理效果。
这里做一个十字掩模为例。
import cv2 import numpy as np img1 = cv2.imread("pic.jpg") mask = np.zeros(img1.shape, np.uint8) # 横着的白色区域 mask[490:600, :, :] = 255 # 竖着的白色区域 mask[:, 470:545, :] = 255 img2 = cv2.bitwise_and(img1, mask) cv2.imshow("img", img2) cv2.waitKey() cv2.destroyAllWindows()