OpenCV-将蒙版应用于彩色图像
image-processing
opencv
python
4
0

如何在最新的python绑定(cv2)中将蒙版应用于彩色图像?在以前的python绑定中,最简单的方法是使用cv.Copy例如

cv.Copy(dst, src, mask)

但是此功能在cv2绑定中不可用。有没有不使用样板代码的解决方法?

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

所描述的其他方法采用二进制掩码。如果要使用实值单通道灰度图像作为遮罩(例如,从Alpha通道),可以将其扩展为三个通道,然后将其用于插值:

assert len(mask.shape) == 2 and issubclass(mask.dtype.type, np.floating)
assert len(foreground_rgb.shape) == 3
assert len(background_rgb.shape) == 3

alpha3 = np.stack([mask]*3, axis=2)
blended = alpha3 * foreground_rgb + (1. - alpha3) * background_rgb

请注意, mask必须在0..1范围内,操作才能成功。还假设1.0编码仅保留前景,而0.0意味着仅保留背景。

如果蒙版的形状可能为(h, w, 1) ,这将有助于:

alpha3 = np.squeeze(np.stack([np.atleast_3d(mask)]*3, axis=2))

在这里, np.atleast_3d(mask)使遮罩(h, w, 1)(h, w)并且np.squeeze(...)将结果从(h, w, 3, 1) (h, w) np.squeeze(...)(h, w, 3)

收藏
评论

好吧,如果您希望背景不是纯黑色,这是一个解决方案。我们只需要反转遮罩并将其应用到相同大小的背景图像 ,然后将背景和前景结合起来即可。该解决方案的一个优点是背景可以是任何东西(甚至是其他图像)。

本示例是从Hough Circle Transform修改而来的。第一个图像是OpenCV徽标,第二个图像是原始蒙版,第三个是背景+前景组合。

涂上口罩并获得自定义的背景

# http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghcircles/py_houghcircles.html
import cv2
import numpy as np

# load the image
img = cv2.imread('E:\\FOTOS\\opencv\\opencv_logo.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# detect circles
gray = cv2.medianBlur(cv2.cvtColor(img, cv2.COLOR_RGB2GRAY), 5)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=50, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))

# draw mask
mask = np.full((img.shape[0], img.shape[1]), 0, dtype=np.uint8)  # mask is only 
for i in circles[0, :]:
    cv2.circle(mask, (i[0], i[1]), i[2], (255, 255, 255), -1)

# get first masked value (foreground)
fg = cv2.bitwise_or(img, img, mask=mask)

# get second masked value (background) mask must be inverted
mask = cv2.bitwise_not(mask)
background = np.full(img.shape, 255, dtype=np.uint8)
bk = cv2.bitwise_or(background, background, mask=mask)

# combine foreground+background
final = cv2.bitwise_or(fg, bk)

注意:最好使用opencv方法,因为它们已经过优化。

收藏
评论

在这里,如果您已经有遮罩图像,则可以使用cv2.bitwise_and函数。

检查以下代码:

img = cv2.imread('lena.jpg')
mask = cv2.imread('mask.png',0)
res = cv2.bitwise_and(img,img,mask = mask)

对于lena图像和矩形蒙版,输出将如下所示。

在此处输入图片说明

收藏
评论
import cv2 as cv

im_color = cv.imread("lena.png", cv.IMREAD_COLOR)
im_gray = cv.cvtColor(im_color, cv.COLOR_BGR2GRAY)

此时,您将获得彩色和灰色图像。我们在这里处理8-bituint8图像。这意味着图像可以具有[0, 255]范围内的像素值,并且这些值必须是整数。

左颜色,右灰色

让我们进行二进制阈值操作。它将创建黑白蒙版图像。黑色区域的值为0 ,白色区域的值为255

_, mask = cv.threshold(im_gray, thresh=180, maxval=255, type=cv.THRESH_BINARY)
im_thresh_gray = cv.bitwise_and(im_gray, mask)

遮罩可以在下面的左侧看到。右边的图像是在灰色图像和蒙版之间应用bitwise_and操作的结果。发生的是,蒙版的像素值为零(黑色)的空间位置在结果图像中变为像素值为零。蒙版的像素值为255(白色)的位置,结果图像将保留其原始灰度值。

左掩码,右位wise_and_with_mask

要将蒙版应用于原始彩色图像,我们需要将蒙版转换为3通道图像,因为原始彩色图像是3通道图像。

mask3 = cv.cvtColor(mask, cv.COLOR_GRAY2BGR)  # 3 channel mask

然后,我们可以使用相同的bitwise_and函数将此蒙版应用于原始彩色图像。

im_thresh_color = cv.bitwise_and(im_color, mask3)

mask3从码图像下方左侧,并im_thresh_color是它的权利。

左掩码3通道,右位wise_and_with_3通道掩码

您可以绘制结果并亲自查看。

cv.imshow("original image", im_color)
cv.imshow("binary mask", mask)
cv.imshow("3 channel mask", mask3)
cv.imshow("im_thresh_gray", im_thresh_gray)
cv.imshow("im_thresh_color", im_thresh_color)
cv.waitKey(0)

我在这里找到的原始图像是lenacolor.png

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号