在Python中查找两个轮廓之间的二进制图像中的所有像素。

huangapple go评论54阅读模式
英文:

Find all pixels bounded between two contours in a binary image in Python

问题

我有一个二进制图像,如下所示,其中有两个以白色显示的轮廓,

我希望将轮廓之间的所有像素变为白色,类似于下面这样,

如何使用Python中的Numpy、OpenCV或Scipy来实现这一点?

我目前使用的是如下所示的FloodFill,

但在这里,我需要提供一个seed值。我有成千上万张这样的图像,其中两个轮廓可以在任何地方移动。如何自动化处理多张图像的过程。

我猜OpenCV的FloodFill也会有相同的限制。

英文:

I have a binary image, like the one shown below, which has two contours shown in white,

在Python中查找两个轮廓之间的二进制图像中的所有像素。

I wish to make all the pixels in between the contours white some thing like below,

在Python中查找两个轮廓之间的二进制图像中的所有像素。

How can I do this in Python using Numpy or OpenCV or Scipy?

I currently use FloodFill as shown below,

from PIL import Image, ImageDraw
# read image
seed = [377,273]
rep_value = (255, 255, 0)
ImageDraw.floodfill(img, seed, rep_value, thresh=50)
img.save(f'cloud_floodfill_{seed}.png')

But here I need to provide a seed value. I have thousands of images like this one where the two contours can be translated anywhere. How to automate the process for several images.

I guess OpenCV's FloodFill will also have the same limitation.

答案1

得分: 4

Approach:

  • findContours(查找轮廓)
  • walk the hierarchy(遍历层次结构)
  • make new contours list(创建新轮廓列表)
  • draw it(绘制它)

The hierarchy for this specific configuration(对于这个特定配置),when walked, will contain:

  • outline outer contour(外部轮廓轮廓)
  • outline inner contour(内部轮廓轮廓)
  • "inline" outer contour("内联"外轮廓)
  • inline inner contour(内联内轮廓)

You want an area between the outline inner contour and inline outer contour(您想要在内部轮廓和外联轮廓之间的区域).

contours, hierarchy = cv.findContours(im, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# hierarchy is a vector<Vec4i> -> row vector of Vec4i, so (1,N,4), weird shape
hierarchy = hierarchy.squeeze(0) # remove that 1-dimension
composite = im.copy()

outline_outer = 0
outline_inner = hierarchy[outline_outer, 2]
inline_outer = hierarchy[outline_inner, 2]

new_contours = [contours[outline_inner], contours[inline_outer]]

cv.drawContours(image=composite, contours=new_contours, contourIdx=-1, color=255, thickness=cv.FILLED)

在Python中查找两个轮廓之间的二进制图像中的所有像素。

在Python中查找两个轮廓之间的二进制图像中的所有像素。

This illustration was done by drawing into a BGR version, with red, and then overlaying the source to make it look pretty(这个插图是通过在BGR版本上用红色绘制,然后叠加源图像来制作的,使其看起来漂亮).

The approach can be extended to arbitrary numbers and nestings. It just takes more work to walk the hierarchy(这种方法可以扩展到任意数量和嵌套中,只需更多的工作来遍历层次结构). Edit: a similar question asked for this extension

英文:

Approach:

  • findContours
  • walk the hierarchy
  • make new contours list
  • draw it

The hierarchy for this specific configuration, when walked, will contain:

  • outline outer contour
  • outline inner contour
  • "inline" outer contour
  • inline inner contour

You want an area between the outline inner contour and inline outer contour.

contours, hierarchy = cv.findContours(im, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# hierarchy is a vector<Vec4i> -> row vector of Vec4i, so (1,N,4), weird shape
hierarchy = hierarchy.squeeze(0) # remove that 1-dimension
composite = im.copy()

outline_outer = 0
outline_inner = hierarchy[outline_outer, 2]
inline_outer = hierarchy[outline_inner, 2]

new_contours = [contours[outline_inner], contours[inline_outer]]

cv.drawContours(image=composite, contours=new_contours, contourIdx=-1, color=255, thickness=cv.FILLED)

在Python中查找两个轮廓之间的二进制图像中的所有像素。

在Python中查找两个轮廓之间的二进制图像中的所有像素。

This illustration was done by drawing into a BGR version, with red, and then overlaying the source to make it look pretty.

The approach can be extended to arbitrary numbers and nestings. It just takes more work to walk the hierarchy. Edit: a similar question asked for this extension

huangapple
  • 本文由 发表于 2023年4月4日 12:52:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925620.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定