使用OpenCV与Python检测带连线的三角形顶点
解决方案:检测带连线的三角形顶点并标记
你已经完成了三角形的识别,接下来要实现带连线顶点的检测与标记,核心思路是:先提取三角形的顶点,再判断顶点是否存在额外连线(即是否与其他轮廓的端点重合/邻近),最后对符合条件的顶点绘制标记。
以下是修改后的完整代码:
import cv2 import numpy as np img = cv2.imread('image_name.png') img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 阈值处理生成二值图 ret, thresh = cv2.threshold(img1, 150, 255, 0) # 改用RETR_TREE模式检索所有层次轮廓,避免遗漏连线 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) print("Number of contours detected:", len(contours)) # 收集所有轮廓的端点(线条的首尾点) all_endpoints = [] for cnt in contours: if len(cnt) >= 2: start_point = tuple(cnt[0][0]) end_point = tuple(cnt[-1][0]) all_endpoints.append(start_point) all_endpoints.append(end_point) # 判断两点是否邻近(用于匹配顶点与连线端点) def is_near(point1, point2, threshold=5): return np.linalg.norm(np.array(point1) - np.array(point2)) < threshold # 遍历轮廓处理三角形 for cnt in contours: # 调整近似精度,更准确提取三角形顶点 approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True) if len(approx) == 3: # 绘制三角形轮廓 img = cv2.drawContours(img, [cnt], -1, (0,255,255), 3) # 提取三角形的三个顶点坐标 triangle_vertices = [tuple(p[0]) for p in approx] # 计算三角形中心,标注文字 M = cv2.moments(cnt) if M['m00'] != 0.0: x = int(M['m10']/M['m00']) y = int(M['m01']/M['m00']) cv2.putText(img, 'Triangle', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2) # 检测每个顶点是否带有连线 for vertex in triangle_vertices: has_connection = False # 检查该顶点是否匹配其他轮廓的端点(排除自身轮廓的端点) for endpoint in all_endpoints: if is_near(vertex, endpoint) and not is_near(vertex, tuple(cnt[0][0])): has_connection = True break # 有连线则绘制红色实心标记点 if has_connection: cv2.circle(img, vertex, 5, (0, 0, 255), -1) cv2.imwrite("Shapes_with_marked_vertices.png", img)
关键逻辑说明:
- 轮廓端点收集:遍历所有轮廓,提取每条线条的首尾端点,这些端点就是连线的潜在连接点。
- 邻近点判断:通过欧氏距离判断两个点是否足够接近,可调整
threshold参数适配不同图片的精度需求。 - 连线检测:对每个三角形顶点,检查它是否与其他轮廓的端点重合,排除自身轮廓的端点后,确认存在连线则标记。
内容的提问来源于stack exchange,提问作者Amit
相关产品推荐
相关产品推荐

