[英]How to remove a contour inside contour in Python OpenCV?
OpenCV in Python provides the following code: Python 中的 OpenCV 提供以下代码:
regions, hierarchy = cv2.findContours(binary_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for region in regions:
x, y, w, h = cv2.boundingRect(region)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 1)
This gives some contours within contour.这给出了轮廓内的一些轮廓。 How to remove them in Python?
如何在 Python 中删除它们?
For that, you should take a look at this tutorial on how to use the hierarchy
object returned by the method findContours
.为此,您应该查看本教程,了解如何使用
findContours
方法返回的hierarchy
对象。
The main point is that you should use cv2.RETR_TREE
instead of cv2.RETR_LIST
to get parent/child relationships between your clusters:要点是您应该使用
cv2.RETR_TREE
而不是cv2.RETR_LIST
来获取集群之间的父/子关系:
regions, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Then you can check whether a contour with index i
is inside another by checking if hierarchy[0,i,3]
equals -1 or not.然后,您可以通过检查
hierarchy[0,i,3]
是否等于 -1 来检查索引为i
的轮廓是否在另一个轮廓内。 If it is different from -1, then your contour is inside another.如果它不同于-1,那么你的轮廓在另一个里面。
In order to remove the contours inside a contour:为了删除轮廓内的轮廓:
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
However, in some cases you may observe that a big contour is formed on the whole image, and applying the above returns you that one big contour.但是,在某些情况下,您可能会观察到整个图像上形成了一个大轮廓,并且应用上述内容会返回一个大轮廓。
In order to avoid this, try inverting the image:为了避免这种情况,请尝试反转图像:
image = cv2.imread("Image Path")
image = 255 - image
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
This will give you the desired result.这将为您提供所需的结果。
UPDATE:更新:
The reason why hierarchy does not work if a big bounding box is approximated on the whole image is that the output of hierarchy[0,iteration,3]
is -1
only for the one bounding box drawn on the whole image, as all other bounding boxes are inside this big bounding box, and hierarchy[0,iteration,3]
is not equal to -1
for any of them.如果在整个图像上近似一个大边界框,层次结构不起作用的原因是,
hierarchy[0,iteration,3]
的输出仅对于绘制在整个图像上的一个边界框为-1
,与所有其他边界一样框在这个大边界框内,其中任何一个的hierarchy[0,iteration,3]
都不等于-1
。 Thus, inverting the image will be required in order to comply with the following:因此,将需要反转图像以符合以下要求:
In OpenCV, finding contours is like finding white object from black background.
在 OpenCV 中,寻找轮廓就像从黑色背景中寻找白色物体。 So remember, object to be found should be white and background should be black.
所以请记住,要找到的对象应该是白色的,背景应该是黑色的。
However, as pointed out by @Jeru, this is not a generalized solution and one must visualize the image before inverting it.但是,正如@Jeru 所指出的,这不是一个通用的解决方案,必须在反转图像之前将其可视化。 Consider this image:
考虑这张图片:
Running跑步
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
results in结果是
Now, only displaying the contour with hierarchy[0,iteration,3] = -1
results in现在,仅显示具有
hierarchy[0,iteration,3] = -1
的轮廓会导致
which is not correct.这是不正确的。 If we want to obtain the rectangle containing the shapes and the text shapes , we can do
如果我们想获得包含形状和文本形状的矩形,我们可以这样做
image = 255 - image
shapes, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
In this case we get:在这种情况下,我们得到:
Code:代码:
import cv2
from easyocr import Reader
import math
shape_number = 2
image = cv2.imread("Image Path")
deep_copy = image.copy()
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(image_gray, 210, 255, cv2.THRESH_BINARY)
thresh = 255 - thresh
shapes, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image=deep_copy, contours=shapes, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
for iteration, shape in enumerate(shapes):
if hierarchy[0,iteration,3] == -1:
print(hierarchy[0,iteration,3])
print(iteration)
cv2.imshow('Shapes', deep_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
img_output, contours, hierarchy = cv2.findContours(blank_image_firstImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
这将删除子轮廓
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.