如何使用同一图片的二进制蒙版图像裁剪图像以去除python中的背景?

Naw*_*ain 7 python opencv image image-processing computer-vision

我尝试使用以下代码获取蒙版图像的边缘:

import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('ISIC_0000000_segmentation.png',0)
edges = cv2.Canny(img,0,255)

plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(edges, cmap='gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show
Run Code Online (Sandbox Code Playgroud)

我得到的是这样的:

在此处输入图片说明 但由于某种原因,边缘并不光滑。

我的计划是使用边缘图像裁剪以下图片:

有谁知道如何使边缘图像更好,以及如何使用它来裁剪正常图像?

编辑:@Mark Setchell 提出了一个很好的观点:如果我可以直接使用蒙版图像来裁剪图像,那就太好了。

另外:也许可以将正常图像精确地放置在蒙版图像上,以便蒙版上的黑色区域覆盖正常图片上的蓝色区域。

编辑:@Mark Setchell 引入了将 normale 图像与蒙版图像相乘的想法,因此背景将导致 0(黑色),其余部分将保持其颜色。当我的蒙版图像是 .png 并且我的正常图片是 .jpg 时,会不会有问题?

编辑:我编写了以下代码来尝试将两张图片相乘:

# Importing Image and ImageChops module from PIL package  
from PIL import Image, ImageChops 

# creating a image1 object 
im1 = Image.open("ISIC_0000000.jpg") 

# creating a image2 object 
im2 = Image.open("ISIC_0000000_segmentation.png") 

# applying multiply method 
im3 = ImageChops.multiply(im1, im2) 

im3.show()
Run Code Online (Sandbox Code Playgroud)

但我收到错误: ValueError: images do not match

有谁知道我该如何解决这个问题?

nat*_*ncy 4

如果我理解正确的话,你想要提取对象并删除背景。为此,您只需cv2.bitwise_and()使用蒙版和原始输入图像进行简单的操作即可。

有谁知道如何使边缘图像更好以及如何使用它来裁剪正常图像?

要从图像中提取背景,不需要边缘图像,阈值图像可用于仅删除图像中所需的部分。您可以使用蒙版图像直接放下图像并去除背景。获得二元掩模的其他方法包括使用固定阈值、自适应阈值或 Canny 边缘检测。下面是一个简单的示例,使用 Otsu 阈值来获取二进制掩码,然后进行按位与运算。

这是删除背景后的结果

如果您希望删除的背景为白色,您还可以将蒙版上的所有像素都设置为白色

注意:根据您想要的结果“平滑”程度,您可以在阈值处理之前对图像应用任何模糊以平滑边缘。这可以包括平均、高斯、中值或双边滤波。


代码

import cv2

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Remove background using bitwise-and operation
result = cv2.bitwise_and(image, image, mask=thresh)
result[thresh==0] = [255,255,255] # Turn background white

cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey()
Run Code Online (Sandbox Code Playgroud)