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

OpenCV完美正方形检测:如何排除近似矩形的类正方形?

嘿,我来帮你搞定这个类正方形误判的问题!

你提到的处理流程我get到了:先是二值边缘图经过HoughLines得到了直线掩码图,再通过convexhull处理得到规整后的二值形状图,现在用approxPolyDP检测四边形状时,把那些近似矩形的类正方形也误判成了正方形,想要精准排除它们对吧?

问题出在approxPolyDP只能帮你筛选出四边多边形,但没法区分正方形和“接近正方形的矩形”,我们需要在筛选出四边轮廓后,加入额外的几何特征校验来精准过滤。

解决方案:多维度校验区分正方形与近似矩形

我给你整理了几个实用的校验维度,组合使用效果最好:

1. 核心:长宽比校验

正方形的长宽比几乎等于1,而哪怕是接近正方形的矩形,长宽比也会偏离这个值。具体步骤:

  • 对每个四边轮廓,用boundingRect获取它的外接矩形宽(w)和高(h)
  • 计算长宽比:ratio = min(w,h)/max(w,h)
  • 设置一个阈值(比如0.95,越接近1要求越严格),只有当ratio >= 阈值时,才保留为候选正方形

举个OpenCV-Python的代码示例:

import cv2
import numpy as np

# 假设你已经提取到了轮廓contours,img是待绘制的图像
for cnt in contours:
    # 用approxPolyDP做多边形近似
    epsilon = 0.02 * cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, epsilon, True)
    
    # 先筛选出四边形状
    if len(approx) == 4:
        # 获取外接矩形
        x, y, w, h = cv2.boundingRect(approx)
        # 计算长宽比
        aspect_ratio = min(w, h) / max(w, h)
        
        # 只保留长宽比接近1的形状
        if aspect_ratio >= 0.95:
            cv2.drawContours(img, [approx], 0, (0,255,0), 2)  # 标记正方形
        else:
            continue  # 排除近似矩形的类正方形

2. 辅助:内角角度校验

如果你的场景里还有一些非矩形的四边形状(比如平行四边形)被误判,那可以加上角度校验——正方形的四个内角都是严格接近90°的:

  • 计算轮廓四个顶点处的内角,确保每个角都在90°±5°的范围内(阈值可调整)

角度计算的代码片段:

def get_inner_angle(p1, p2, p3):
    # 计算p2点处的内角(p1-p2-p3的夹角)
    v1 = np.array(p1) - np.array(p2)
    v2 = np.array(p3) - np.array(p2)
    # 计算余弦值并转角度
    cos_val = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
    angle = np.arccos(np.clip(cos_val, -1, 1)) * 180 / np.pi
    # 返回锐角/直角(避免钝角干扰)
    return min(angle, 180 - angle)

# 在筛选四边形状后加入角度校验
if len(approx) == 4:
    pts = approx.reshape(4, 2)
    angles = []
    for i in range(4):
        angle = get_inner_angle(pts[i], pts[(i+1)%4], pts[(i+2)%4])
        angles.append(angle)
    
    # 检查所有角度是否接近90°
    if all(85 <= angle <= 95 for angle in angles):
        # 再结合长宽比校验
        x, y, w, h = cv2.boundingRect(approx)
        aspect_ratio = min(w,h)/max(w,h)
        if aspect_ratio >= 0.95:
            cv2.drawContours(img, [approx], 0, (0,255,0), 2)

3. 阈值调整小技巧

  • 如果你的图像边缘有轻微噪声或检测误差,可以适当降低长宽比阈值(比如调到0.9),或者放宽角度误差范围(比如±10°)
  • 最好先统计你数据里真实正方形的长宽比和角度范围,再设置对应的阈值,这样更贴合你的实际场景

内容的提问来源于stack exchange,提问作者U.S.Swap

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:24:52