9 图像掩膜
9.1 制作掩膜
掩膜(Mask)是一种在图像处理中常见的操作,它用于选择性地遮挡图像的某些部分,以实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置为1(或白色),而其他区域被设置为0(或黑色),并且目标区域可以根据HSV的颜色范围进行修改,如下图就是制作红色掩膜的过程:
通过这个掩膜,我们就可以对掩膜中的白色区域所对应的原图中的区域进行处理与操作。
mask=cv.inRange(img,color_low,color_high)
cv2.inRange用于进行多通道图像(尤其是彩色图像)的阈值操作。


9.2 与运算
我们在高中时学过逻辑运算中的"与"运算,其规则是当两个命题都是真 时,其结果才为真。而在图像处理中,"与"运算被用来对图像的像素值进行操作。具体来说,就是将两个图像中所有的对应像素值一一进行"与"运算,从而得到新的图像。从上面的图片我们可以看出,掩膜中有很多地方是黑色的,其像素值为0,那么在与原图像进行"与"运算的时候,得到的新图像的对应位置也是黑色的,如下图所示:

通过掩膜与原图的与运算,我们就可以提取出图像中被掩膜覆盖的区域(扣图)。
cv2.bitwise_and(src1,src2,mask=mask)
src1
:第一个输入数组。通常是输入的原始图像。
src2
:第二个输入数组。它可以是另一个图像、一个常数值或者与 src1
相同的图像,通常是它本身。
当应用掩膜时,这个参数经常就是src1
本身;即对同一个图像进行操作。
如果对两个不同的图像执行按位与操作(例如,将两张图片的某些部分组合在一起),可以分别将它们作为 src1
和 src2
输入到 cv2.bitwise_and()
函数中,创建复杂的图像效果或进行图像合成。
mask
:掩膜(可选)。输入数组元素只有在该掩膜非零时才被处理。是一个8位单通道的数组,尺寸必须与src1
和src2
相同。
返回值:输出数组,应用掩膜后的图像,与输入数组大小和类型相同。


通过掩膜图与原图金星相与操作,在上面获得的掩膜图上,黑色是0,其他地方不为0,与原图进行与操作,0的地方最后就还是0。
9.3 颜色替换
前一个实验中,我们已经能够识别到图像中的某一种颜色,那么我们就可以对识别到的颜色进行一个操作,比如将其替换成别的颜色,其原理就是在得到原图的掩膜之后,对掩膜中的白色区域所对应的原图中的区域进行一个像素值的修改即可。
9.3.1 制作掩膜
掩膜(Mask)是一种在图像处理中常见的操作,它用于选择性地遮挡图像的某些部分,以实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置为1(或白色),而其他区域被设置为0(或黑色),并且目标区域则可以根据HSV的颜色范围进行修改。
通过这个掩膜,我们就可以对掩膜中的白色区域所对应的原图中的区域(也就是原图中的红色区域)进行像素值的修改,从而完成颜色替换的功能。
9.3.2 颜色替换
由于掩膜与原图的大小相同,并且像素位置一一对应,那么我们就可以得到掩膜中白色(也就是像素值为255)区域的坐标,并将其带入到原图像中,即可得到原图中的红色区域的坐标,然后就可以修改像素值了,这样就完成了颜色的替换,如下图所示:
-
mask_image_np == 255
: 这一部分实际上是在生成一个布尔数组,其形状与mask_image_np
相同。 -
image_np[...] = (0, 255, 0)
: 这里使用了NumPy的高级索引功能。
10 ROI切割
ROI:Region of Interest,翻译过来就是感兴趣的区域。什么意思呢?比如对于一个人的照片,假如我们要检测眼睛,因为眼睛肯定在脸上,所以我们感兴趣的只有脸这部分,其他都不care,所以可以单独把脸截取出来,这样就可以大大节省计算量,提高运行速度。
还记得Numpy这个库吗?我们在使用OpenCV进行读取图像时,图像数据会被存储为Numpy数组,这也意味着我们可以使用Numpy数组的一些操作来对图像数据进行处理,比如切片。而本实验的原理也是基于Numpy数组的切片操作来完成的,因此在对应的组件中就需要填我们要切割的ROI区域的坐标来完成ROI切割操作。
注意:在OpenCV中,坐标的x轴的正方向是水平向右,y轴的正方向是垂直向下,与数学上的二维坐标并不相同。
在计算机视觉中,当我们使用OpenCV读取RGB三通道图像时,它会被转换成一个三维的Numpy数组。这个数组里的每个元素值都表示图像的一个像素值。这个三维数组的第一个维度(即轴0)通常代表图像的高度,第二个维度(即轴1)代表图像的宽度,而第三个维度(即轴2)代表图像的三个颜色通道(B、G、R,OpenCV读取到的图像以BGR的方式存储)所对应的像素值。
因此,我们可以通过指定切片的范围来选择特定的高度和宽度区域。这样,我们就能够获取这个区域内的所有像素值,即得到了这个区域的图像块,通过Numpy的切片操作,我们就完成了ROI切割的操作。这种提取ROI的方法允许我们仅获取感兴趣区域内的像素,而忽略其他不相关的部分,从而大大减少数据处理和存储的负担。

