基于Python+OpenCV检测图像中数字3的内部轮廓质心
检测数字3内部轮廓的质心解决方案
你已经选对了核心方向——用cv2.RETR_TREE获取轮廓层级关系,这是定位数字3内部空洞轮廓的关键。我帮你完善代码,实现内部轮廓质心的检测和可视化:
import cv2 import numpy as np # 读取图像 im = cv2.imread("three.png") if im is None: print("Error: 无法读取图像,请检查文件路径是否正确!") exit() # 转灰度图 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # 反相二值化(OTSU自动确定阈值),确保数字为黑色,背景为白色 ret, thresh = cv2.threshold(imgray, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) # 寻找轮廓及层级关系 _, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) hierarchy = hierarchy[0] # 提取层级数组的有效部分 # 遍历所有轮廓,筛选内部轮廓并计算质心 for idx, cnt in enumerate(contours): # 内部轮廓的标志:存在父轮廓(hierarchy的第4个元素为父轮廓索引,不为-1) if hierarchy[idx][3] != -1: # 计算轮廓的矩 M = cv2.moments(cnt) # 避免除以0的情况(防止空轮廓) if M["m00"] != 0: cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) else: cX, cY = 0, 0 # 绘制内部轮廓(绿色) cv2.drawContours(im, [cnt], -1, (0, 255, 0), 2) # 绘制质心(红色实心圆) cv2.circle(im, (cX, cY), 3, (0, 0, 255), -1) # 标注质心坐标 cv2.putText(im, f"({cX}, {cY})", (cX - 25, cY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) # 显示结果 cv2.imshow("Inner Contour Centroids", im) cv2.waitKey(0) cv2.destroyAllWindows() # 可选:保存结果图像 # cv2.imwrite("three_centroid_result.png", im)
关键细节解释
- 轮廓层级筛选:
cv2.RETR_TREE会返回每个轮廓的层级信息hierarchy,每个轮廓对应的层级项是[next, prev, child, parent]。我们通过判断parent != -1来筛选出内部轮廓(也就是数字3的两个空洞轮廓)。 - 质心计算:
cv2.moments()计算轮廓的几何矩,其中m10/m00是质心的x坐标,m01/m00是y坐标。加入M["m00"] != 0的判断,避免处理空轮廓时出现除以0的错误。 - 可视化验证:代码会用绿色绘制内部轮廓,红色实心圆标记质心,并标注坐标,方便你直观确认结果是否正确。
内容的提问来源于stack exchange,提问作者lucians
相关产品推荐
相关产品推荐

