【问题标题】:How to remove the white border/edge around a figure in an image using python?如何使用python删除图像中图形周围的白色边框/边缘?
【发布时间】:2019-11-11 11:23:25
【问题描述】:

我想删除黑色掩模和所述主体图像 P>之间的白色边界

图像输入例子:

与厚度1图像输出:

与厚度2图像输出:

我尝试了一些游戏与模糊和阈值,我在这里找到 我还用这些代码来查找和绘制轮廓 P>

    thickness = 3
    image = cv2.imread('../finetune/22.png')
    blank_mask = np.zeros(image.shape, dtype=np.uint8)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    cnts = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    cv2.drawContours(image, cnts, -1, (255,0,0), thickness)
    cv2.imshow('image', image)
    cv2.imwrite('../finetune/22-'+str(thickness)+'r.png',image)
    cv2.waitKey()

但是,我发现轮廓是所述黑色掩膜的边缘,而不是白线 我使用了与厚度和它的工作原理很好,但在每个图像上该轮廓是不同的,也厚度不整个数字等于 P>

什么是去除它的最佳精确的方式? P>

【问题讨论】:

  • 什么大约收缩轮廓,并将它作为掩模以后?跨度>
  • 你能不能请附上期望的输出。 SPAN>
  • 请参阅我的文章在stackoverflow.com/questions/58097626/…抗锯齿边界 SPAN>
  • 由nathancy波纹管送到显示然而,它并没有帮助我为我根本问题我希望的结果答案,我会后一个答案来解释它 SPAN>

标签: python image opencv image-processing computer-vision


【解决方案1】:

这里有两种方法:

方法#1: cv2.erode()

您可以使用侵蚀来侵蚀掉白色前景对象的边界。本质上,这个想法是使用内核执行 2D 卷积。可以使用cv2.getStructuingElement() 创建内核,您可以在其中传递要创建的所需内核的形状和大小。典型的内核是cv2.MORPH_RECTcv2.MORPH_ELLIPSEcv2.MORPH_CROSS。如果内核下的所有像素都是1,则内核滑过图像,其中一个像素被认为是1,否则它被侵蚀为0。最终效果是边界上的所有像素都将被丢弃,具体取决于内核的形状和大小。前景的厚度减小,可用于去除小的白噪声或分离对象。您可以使用要执行的迭代次数来调整侵蚀的强度。

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
erode = cv2.erode(image, kernel, iterations=1)

方法#1:cv2.morphologyEx()打开

与腐蚀相反的是膨胀,它可以增强图像。通常,在腐蚀之后执行拨号以“标准化”形态操作的效果。 OpenCV 将这些步骤组合成一个称为形态打开的单一操作。打开只是腐蚀后膨胀的另一个名称,与仅腐蚀相比,通常会给您更平滑的结果。

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)

结果

您可以试验内核形状和迭代次数。要去除更多的噪声,请增加内核大小和迭代次数,而要去除较少的噪声,请减小内核大小和迭代次数。

import cv2

image = cv2.imread('1.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=3)

cv2.imshow('opening', opening)
cv2.waitKey()

【讨论】:

  • 太好了,这正是我正在寻找的结果!!!!但是,它并没有帮助我解决我的根本问题...请参阅下面的答案,了解有关我的根本问题的更多信息
【解决方案2】:

nathancy 发送的以下答案准确显示了我想要达到的结果,但它对我的根本问题没有帮助

当我使用 drawContours 时,我可以在我的面具上绘制轮廓并改进它

所以这是关于我的问题的更多信息:

使用图像分割方法获得蒙版后,我想更改背景(在示例中我使用黑色背景),但新背景和图形之间仍有白色轮廓

原图:

https://drive.google.com/open?id=1P39VCEe2FTqkD6JbdM4ueMr_71C6nI42

面具:

https://drive.google.com/open?id=1LTHaclsDOxRJCI9t5bLg3PeanseRR9bc

输出:

https://drive.google.com/open?id=1-uQx77-fmMf_9qFSgNMBvo77Q6Ag8qEZ

这是我使用的代码:

    image = cv2.imread('../finetune/1.png')
    mask = cv2.imread('../finetune/1mask.png')

    output = np.zeros(image.shape, dtype=np.uint8)

    output[np.where(mask == 255)] = image[np.where(mask == 255)]

    cv2.imshow("output",output)
    cv2.imwrite('../finetune/1.output.png',output)

帮助上面的答案,我可以再次获取轮廓并协调创建新蒙版,但我确信有更好的优雅方式来做到这一点

澄清一下,我想改进蒙版以防止在我将它放在新背景上时出现白色边框

【讨论】:

  • 您可以使用我在stackoverflow.com/questions/58097626/…使用的技术简单地对蒙版边缘进行抗锯齿处理
  • 腐蚀蒙版,然后按位腐蚀原始输入图像。假设您的遮罩变量是mask,您可以通过将遮罩上的所有背景像素更改为您想要的颜色来更改背景
猜你喜欢
  • 2017-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多