cv2.findContours检测图像边框致物体外轮廓无法显示的技术求助
问题解决:排除图像边框轮廓,正确显示物体外轮廓
核心问题原因
cv2.findContours会将图像的边缘(黑色背景与图像边界的交界)识别为最外层轮廓,而你只处理hierachy[0][i][3] == -1的最外层轮廓,导致真正需要的iPhone外轮廓(作为该边框轮廓的子轮廓)无法显示,仅能看到屏幕这类独立的子轮廓。
两种简单解决方案
方案1:预处理时添加内部填充边框
在读取图像后,给图像边缘填充1像素的白色(与二值化背景色一致),让原图像边界不再形成闭合轮廓:
bild = cv2.imread('iphone.jpg',0) # 添加1像素白色边框,填充色与二值化背景统一 bild = cv2.copyMakeBorder(bild, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=255)
后续再执行阈值化和轮廓检测,原图像边缘就不会被识别为轮廓。
方案2:过滤匹配图像尺寸的轮廓
在遍历轮廓时,直接跳过与图像尺寸完全匹配的边框轮廓:
for i, aktuelleKontur in enumerate(konturen): # 判断是否为图像边框轮廓 x, y, w, h = cv2.boundingRect(aktuelleKontur) if x == 0 and y == 0 and w == bild.shape[1] and h == bild.shape[0]: continue # 原有的层级判断逻辑 if hierachy[0][i][3] == -1: # 后续处理代码
修改后的完整代码(方案2示例)
import cv2 import numpy as np font = cv2.FONT_HERSHEY_COMPLEX bild = cv2.imread('iphone.jpg',0) returnSchwellWert, binäresBild = cv2.threshold(bild, 80, 255, cv2.THRESH_BINARY) konturen, hierachy = cv2.findContours(binäresBild, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) for i, aktuelleKontur in enumerate(konturen): # 过滤图像边框轮廓 x, y, w, h = cv2.boundingRect(aktuelleKontur) if x == 0 and y == 0 and w == bild.shape[1] and h == bild.shape[0]: continue if hierachy[0][i][3] == -1: # 用cv2.boundingRect简化长宽计算,替代手动遍历排序 x_rect, y_rect, xLength, yHight = cv2.boundingRect(aktuelleKontur) n = aktuelleKontur.ravel() idx=0 for j in n : if(idx % 2 == 0): x = n[idx] y = n[idx + 1] offsetXforText = 32 offsetYforText = 10 offsetforText = 20 if(idx == 0): cv2.putText(bild, "Laenge: ", (x - offsetXforText, y + offsetYforText - offsetforText), font, 0.5, (255, 0, 0)) cv2.putText(bild, str(xLength), (x + offsetXforText, y + offsetYforText - offsetforText), font, 0.5, (255, 0, 0)) cv2.putText(bild, "Hoehe: ", (x - offsetXforText, y - offsetYforText - offsetforText), font, 0.5, (255, 0, 0)) cv2.putText(bild, str(yHight), (x + offsetXforText, y - offsetYforText - offsetforText), font, 0.5, (255, 0, 0)) idx += 1 cv2.drawContours(bild, [aktuelleKontur], 0, (0, 0, 255), 1) cv2.imshow("Bild mit markierten Konturen", bild) cv2.waitKey(0) cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Simon Dengler
相关产品推荐
相关产品推荐

