图像预处理-图像掩膜

文章发布时间:

最后更新时间:

文章总字数:
1.3k

预计阅读时间:
5 分钟

一.掩膜简介

掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置为1(或白色255),而其他区域被设置为0(黑色),并且目标区域可以根据HSV的颜色范围进行修改。

二.制作掩膜

mask=cv.inRange(img,color_low,color_high)

cv2.inRange 用于进行多通道图像(尤其是彩色图像)的阈值操作。

首先要把彩图(RGB)转换为HSV颜色空间,然后用之前HSV取值范围来取出特定颜色,即(img,(hmin,smin,vmin),(hmax,smax,vmax)),一般后两个参数传用np创建的数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 导入opencv和numpy
import cv2 as cv
import numpy as np

# 读取图片
img = cv.imread('../images/demo.png')

# 图太大了修改一下大小
img_re = cv.resize(img, (480,480))
# 显示原图
cv.imshow('tym_1', img_re)

# 转换为HSV格式
img_hsv = cv.cvtColor(img_re, cv.COLOR_BGR2HSV)

# 设定绿色颜色范围
lower_green = np.array([35, 43, 46])
higer_green = np.array([77, 255, 255])

# 创建掩膜
mask = cv.inRange(img_hsv, lower_green, higer_green)

# 显示掩膜
cv.imshow('tym_2', mask)
cv.waitKey(0)
cv.destroyAllWindows()

结果:

这里掩膜和掩膜后图像出现右下角的白色(绿色)轮廓,我认为是这里的四个颜色区域的边缘并没有严格使用该区域的颜色,右下角黄色区域的边缘含有绿色,所以会在掩膜和掩膜后图像中显示。

注意:掩膜虽然是用HSV颜色空间创建出来的,但本质上还是二值化图像,只有两种值。

三.与运算

图像处理中,与运算被用来对图像的像素值进行操作,也就是将两个图像中所有的对应像素值一一进行与运算,从而得到新的图像。

通常来说,掩膜上白色部分的像素值都是 (255,255,255) ,而255是unit8的最大值(2^8),此时将其与原图(例如:111,123,132)做与运算,就是将值转换为二进制做与运算,而255转换后全是1,所以与运算后就得到原区域。

cv2.bitwise_and(src1,src2[,mask])

参数:

  • src1:通常是输入的原始图像。

  • src2:它可以是另一个图像、一个常数值或者与 src1 相同的图像。

    • 应用掩膜时,这个参数经常就是src1本身;即对同一个图像进行操作。

    • 若对两个不同的图像执行按位与操作(例如,将两张图片的某些部分组合在一起),可以分别将它们作为 src1 和 src2。

  • mask:掩膜(可选)。输入数组元素只有在该掩膜非零时才被处理。是一个8位单通道的数组,尺寸必须与 src1 和 src2 相同。

通过掩膜与原图的与运算,就可提取出图像中被掩膜覆盖的区域(扣图)。但这个函数需要我们传入更多参数,前面必须传入 src1 和 src2 两图,所以进行掩膜与运算时把 src2 输入成第一张图就行了,相当于原图自己做与操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 导入opencv和numpy
import cv2 as cv
import numpy as np

# 读取图片
img = cv.imread('../images/demo.png')

# 图太大了修改一下大小
img_re = cv.resize(img, (480,480))
# 显示原图
cv.imshow('tym_1', img_re)

# 转换为HSV格式
img_hsv = cv.cvtColor(img_re, cv.COLOR_BGR2HSV)

# 设定绿色颜色范围
lower_green = np.array([35, 43, 46])
higer_green = np.array([77, 255, 255])

# 创建掩膜
mask = cv.inRange(img_hsv, lower_green, higer_green)

# 与运算得到掩膜后图像
res = cv.bitwise_and(img_re, img_re, mask = mask)

# 显示掩膜后图像
cv.imshow('tym_2', res)
cv.waitKey(0)
cv.destroyAllWindows()

结果:

这里提一嘴,转化为HSV的图片显示会跟我们想象的不一样,比如这里的:

怎么变HSV颜色空间就全是黄色和红色呢?这是因为可视化工具支持的是RGB颜色空间的显示,比如在原图中白色区域的像素值为(255,255,255),转化为HSV空间后值应该为表中对应的(0,0,255),但是这在BGR存储顺序中是红色,所以显示的就是红色。

四.颜色替换

掩膜原图的大小相同,并且像素位置一一对应,可以通过布尔索引得到掩膜中白色区域的坐标,并将其带入到原图像(RGB颜色空间)中。

1
2
3
4
5
6
7
# 修改掩膜后指定颜色为蓝色
img_re[mask == 255] = (255,0,0)

# 显示修改颜色后的图像
cv.imshow('tym_4', img_re)
cv.waitKey(0)
cv.destroyAllWindows()

结果:

由于掩膜是二值化图像,所以只有 255 和 0 两种值,可以用布尔索引将掩膜中的目标区域(白色)坐标提取出来。然后原图是RGB颜色空间的,所以又使用(B,G,R)的赋值方式修改像素值。

还有一种颜色替换方法,直接用HSV空间修改颜色,再转换为RGB格式展示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import cv2 as cv
import numpy as np
img = cv.imread('../images/demo.png')
hsv_img = cv.cvtColor(img,cv.COLOR_BGR2HSV)
lower_green = np.array([40,40,40])
upper_green = np.array([80, 255, 255])


mask = cv.inRange(hsv_img, lower_green, upper_green)

# 用数组存储蓝色的hsv值
blue_hsv = np.array([120, 255, 255])

# 将mask中为1的区域的hsv值替换为蓝色
hsv_img[mask > 0] = blue_hsv

# 将修改颜色后的HSV空间图片转换为RGB图片方便正确显示
mask_img = cv.cvtColor(hsv_img, cv.COLOR_HSV2BGR)

cv.imshow('原图',img)
cv.imshow('yjy',mask_img)

cv.waitKey(0)
cv.destroyAllWindows()