OpenCV轻松入门:面向Python
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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)