[英]How to remove a contour inside contour in Python OpenCV?
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)
這給出了輪廓內的一些輪廓。 如何在 Python 中刪除它們?
為此,您應該查看本教程,了解如何使用findContours
方法返回的hierarchy
對象。
要點是您應該使用cv2.RETR_TREE
而不是cv2.RETR_LIST
來獲取集群之間的父/子關系:
regions, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
然后,您可以通過檢查hierarchy[0,i,3]
是否等於 -1 來檢查索引為i
的輪廓是否在另一個輪廓內。 如果它不同於-1,那么你的輪廓在另一個里面。
為了刪除輪廓內的輪廓:
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
但是,在某些情況下,您可能會觀察到整個圖像上形成了一個大輪廓,並且應用上述內容會返回一個大輪廓。
為了避免這種情況,請嘗試反轉圖像:
image = cv2.imread("Image Path")
image = 255 - image
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
這將為您提供所需的結果。
更新:
如果在整個圖像上近似一個大邊界框,層次結構不起作用的原因是, hierarchy[0,iteration,3]
的輸出僅對於繪制在整個圖像上的一個邊界框為-1
,與所有其他邊界一樣框在這個大邊界框內,其中任何一個的hierarchy[0,iteration,3]
都不等於-1
。 因此,將需要反轉圖像以符合以下要求:
在 OpenCV 中,尋找輪廓就像從黑色背景中尋找白色物體。 所以請記住,要找到的對象應該是白色的,背景應該是黑色的。
但是,正如@Jeru 所指出的,這不是一個通用的解決方案,必須在反轉圖像之前將其可視化。 考慮這張圖片:
跑步
shapes, hierarchy = cv2.findContours(image=image, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)
結果是
現在,僅顯示具有hierarchy[0,iteration,3] = -1
的輪廓會導致
這是不正確的。 如果我們想獲得包含形狀和文本形狀的矩形,我們可以這樣做
image = 255 - image
shapes, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
在這種情況下,我們得到:
代碼:
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.