OpenCV-对彩色图像应用遮罩

2024-05-12 13:19:51 发布

您现在位置:Python中文网/ 问答频道 /正文

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

cv.Copy(dst, src, mask)

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


Tags: 方法函数代码srcmask样板cv2cv
3条回答

在这里,如果已经有了掩码图像,就可以使用cv2.bitwise_and函数。

检查以下代码:

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

对于lena图像和矩形遮罩,输出如下。

enter image description here

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

此示例是从Hough Circle Transform修改的。第一个图像是OpenCV徽标,第二个是原始遮罩,第三个是背景+前景的组合。

apply mask and get a customized background

# 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方法,因为它们是经过优化的。

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]的范围内,并且值必须是整数。

left-color,right-gray

让我们做一个二值阈值运算。它创建一个黑白蒙面图像。黑色区域有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(白色)的位置,生成的图像保留其原始灰度值。

left-mask,right-bitwise_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在右边。

left-mask-3channel,right-bitwise_and_with_3channel-mask

你可以画出结果,自己看。

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,我找到了here

相关问题 更多 >