英文:
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,
I wish to make all the pixels in between the contours white some thing like below,
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)
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)
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论