3.4 掩模
OpenCV中的很多函数都会指定一个掩模,也被称为掩码,例如:
计算结果=cv2.add(参数1,参数2,掩模)
当使用掩模参数时,操作只会在掩模值为非空的像素点上执行,并将其他像素点的值置为0。
例如,img1、img2、mask和img3的原始值分别为:
经过img3=cv2.add(img1, img2, mask=mask)运算后,得到img3为:
在运算过程中,img3计算的是在掩模mask控制下的“img1+img2”结果。在计算时,掩码为1的部分对应“img1+img2”,其他部分的像素值均为“0”。
需要说明的是,在运算前,数组img3内就存在值,这仅仅是为了说明问题用的,实际上img3是根据函数cv2.add()所生成的新数组,与原来的值并没有关系。
【例3.10】演示掩码的使用。
根据题目要求,编写程序如下:
import cv2 import numpy as np img1=np.ones((4,4), dtype=np.uint8)*3 img2=np.ones((4,4), dtype=np.uint8)*5 mask=np.zeros((4,4), dtype=np.uint8) mask[2:4,2:4]=1 img3=np.ones((4,4), dtype=np.uint8)*66 print("img1=\n", img1) print("img2=\n", img2) print("mask=\n", mask) print("初始值img3=\n", img3) img3=cv2.add(img1, img2, mask=mask) print("求和后img3=\n", img3)
运行上述程序,得到如下输出结果:
img1= [[3 3 3 3] [3 3 3 3] [3 3 3 3] [3 3 3 3]] img2= [[5 5 5 5] [5 5 5 5] [5 5 5 5] [5 5 5 5]] mask= [[0 0 0 0] [0 0 0 0] [0 0 1 1] [0 0 1 1]] 初始值img3= [[66 66 66 66] [66 66 66 66] [66 66 66 66] [66 66 66 66]] 求和后img3= [[0 0 0 0] [0 0 0 0] [0 0 8 8] [0 0 8 8]]
上述例题介绍的是在cv2.add()函数中使用掩模的情况,在位运算中也都含有掩模参数。在3.3.1节中,我们介绍了直接使用按位与运算对原始图像与掩模进行计算的方式。在将彩色图像与掩模进行计算时,由于按位与操作要求参与运算的数据应该有相同的通道,所以无法直接将彩色图像与单通道的掩模图像进行按位与操作。我们通过将掩模图像转换为BGR模式的彩色图像,让彩色图像与(彩色)掩模图像进行按位与操作,从而实现掩模运算。
实际上,在函数中所使用的掩模参数可以是8位单通道图像。所以,可以将掩模图像作为按位与函数cv2.bitwise_and( src1, src2[, mask]] )中参数mask的值,完成掩模运算。此时,让待处理的彩色图像同时作为函数cv2.bitwise_and( src1, src2[, mask]] )的参数src1和参数src2,使用掩模图像作为掩模参数,完成按位与运算,即可得到由掩模控制的彩色图像。
需要注意的是,任何数值与自身进行按位与计算的结果,得到的仍旧是自身的值。例如,在表3-11中,数值198与自身进行按位与运算,得到的结果仍旧是198。
表3-11 数值与自身按位与运算示例
所以,在上述操作中,让待处理的彩色图像与自身进行按位与操作,得到的仍是彩色图像本身。而使用的掩模参数控制的是,在目标图像中,哪些区域的值是彩色图像的值、哪些区域的值是0。
【例3.11】构造一个掩模图像,将该掩模图像作为按位与函数的掩模参数,实现保留图像的指定部分。
import cv2 import numpy as np a=cv2.imread("lena.bmp",1) w, h, c=a.shape mask=np.zeros((w, h), dtype=np.uint8) mask[100:400,200:400]=255 mask[100:500,100:200]=255 c=cv2.bitwise_and(a, a, mask) print("a.shape=", a.shape) print("mask.shape=", mask.shape) cv2.imshow("a", a) cv2.imshow("mask", mask) cv2.imshow("c", c) cv2.waitKey() cv2.destroyAllWindows()
运行上述程序,输出结果如图3-8所示,其中左图为原始图像,中间的图为掩模图像,右图为原始图像与掩模图像进行按位与后的图像。由于本书为黑白印刷,所以为了更好地观察运行效果,请大家亲自上机运行程序。
图3-8 彩色图像按位与提取
除此以外,程序还将显示如下结果:
a.shape= (512, 512, 3) mask.shape= (512, 512)