You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV-Python轮廓角点提取、绘制及YOLO训练数据生成问题

问题解决:完整提取矩形轮廓角点并生成YOLO格式标注

问题背景

现有二值掩码图,需提取图中5个矩形轮廓的20个角点,生成YOLO训练用txt文件,并绘制出目标轮廓。当前代码仅提取到16个角点,无法满足需求。

问题根源

原代码使用cv2.goodFeaturesToTrack检测角点,该方法依赖图像特征点响应值,在边缘不清晰或凸包绘制存在偏差时易漏检。而目标是规则矩形,直接对轮廓做多边形逼近获取顶点更可靠。

修正后的完整代码

1. 角点提取与轮廓绘制

import cv2
import numpy as np

filename = 'train_data/label/1112.jpg'
inputImage = cv2.imread(filename)
inputImageCopy = inputImage.copy()
grayInput = cv2.cvtColor(inputImageCopy, cv2.COLOR_BGR2GRAY)
_, binaryImage = cv2.threshold(grayInput, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cannyImage = cv2.Canny(binaryImage, 120, 255, 1)

contours, hierarchy = cv2.findContours(cannyImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 存储每个矩形的四个角点,格式为 [[(x1,y1), (x2,y2), (x3,y3), (x4,y4)], ...]
rectCornersList = []

minArea = 1000
for c in contours:
    # 计算轮廓面积,过滤小轮廓
    contourArea = cv2.contourArea(c)
    if contourArea < minArea:
        continue
    
    # 多边形逼近,epsilon设为轮廓周长的2%,确保得到矩形的四个顶点
    epsilon = 0.02 * cv2.arcLength(c, True)
    contoursPoly = cv2.approxPolyDP(c, epsilon, True)
    
    # 只处理四边形(矩形)
    if len(contoursPoly) == 4:
        # 转换为整数坐标
        corners = np.intp(contoursPoly).reshape(-1, 2)
        rectCornersList.append(corners)
        
        # 绘制轮廓(和目标图一致)
        cv2.drawContours(inputImageCopy, [corners], 0, (0, 255, 0), 2)
        # 绘制角点
        for (x, y) in corners:
            cv2.circle(inputImageCopy, (x, y), 5, (0, 0, 255), -1)

# 显示绘制结果
cv2.imshow("Result Contours", inputImageCopy)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 生成YOLO格式标注文件

YOLO多边形标注格式为:class_id x1 y1 x2 y2 ... xn yn,其中坐标需归一化到0-1范围(相对于图像宽高)。

# 获取图像宽高
imgHeight, imgWidth = inputImage.shape[:2]

with open('output1112.txt', 'w') as file:
    for corners in rectCornersList:
        # 归一化坐标
        normalized = []
        for (x, y) in corners:
            nx = x / imgWidth
            ny = y / imgHeight
            normalized.append(str(nx))
            normalized.append(str(ny))
        # 写入文件,类别ID为0
        file.write(f"0 {' '.join(normalized)}\n")

关键改进点

  • 替换角点检测方法:用cv2.approxPolyDP直接从轮廓逼近得到矩形的四个顶点,避免特征点漏检,确保每个矩形稳定提取4个角点。
  • 按轮廓分组角点:每个轮廓对应一组角点,避免原代码中按顺序分组的错误逻辑。
  • 加入归一化处理:符合YOLO训练要求的坐标格式,原代码直接保存像素坐标不符合标准。
  • 可视化验证:绘制轮廓和角点,直观确认结果是否匹配目标图。

内容的提问来源于stack exchange,提问作者LE Doan Phuoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:05:20