在 _rect_candidates_from_binary 里,大多数人会写成👇这样之一:

1️⃣ 面积比型(最常见)

rectness=AcontourAminAreaRectrectness = \frac{A_{\text{contour}}}{A_{\text{minAreaRect}}} rectness=AminAreaRect​Acontour​​


double rectness = contourArea / rect.area();

✔ 简单
❌ 对旋转、缺角、噪声很敏感


2️⃣ 外接矩形填充率

rectness=Amask ∩ rectArectrectness = \frac{A_{\text{mask ∩ rect}}}{A_{\text{rect}}} rectness=Arect​Amask ∩ rect​​

✔ 比 1️⃣ 稳一点
❌ 对锯齿、边缘毛刺敏感


二、工业里更稳的「矩形度 = 多指标联合」

核心思想:

“像不像矩形” ≠ 单一几何量
而是 形状 + 边 + 角 + 填充


三、推荐方案 ⭐(强烈建议)

✅ 矩形度 = 四项加权平均

Rectness=w1Rarea+w2Rangle+w3Redge+w4Rfill\text{Rectness} = w_1 R_{\text{area}} + w_2 R_{\text{angle}} + w_3 R_{\text{edge}} + w_4 R_{\text{fill}} Rectness=w1​Rarea​+w2​Rangle​+w3​Redge​+w4​Rfill​

权重示例(可调):

w = [0.35, 0.25, 0.20, 0.20]


四、四个子指标的数学定义 + 工业意义


① 面积一致性(Area Consistency)

Rarea=AcontourAminAreaRectR_{\text{area}} = \frac{A_{\text{contour}}}{A_{\text{minAreaRect}}} Rarea​=AminAreaRect​Acontour​​

✔ 快速筛掉奇形怪状
✔ 允许缺角(≤ 10%)

double R_area = area / rect.size.area(); R_area = std::clamp(R_area, 0.0, 1.0);


② 角度正交性(Angle Orthogonality)🔥

这是区分“矩形 vs 梯形”的核心

数学

对 minAreaRect 四条边:

Rangle=1−14∑i∣θi−90∘∣90∘R_{\text{angle}} = 1 - \frac{1}{4} \sum_i \frac{|\theta_i - 90^\circ|}{90^\circ} Rangle​=1−41​i∑​90∘∣θi​−90∘∣​

✔ 旋转不敏感
✔ 强烈抑制梯形 / 平行四边形

double angle_error = 0; for (int i = 0; i < 4; ++i) { cv::Point2f v1 = pts[(i+1)%4] - pts[i]; cv::Point2f v2 = pts[(i+2)%4] - pts[(i+1)%4]; double cosang = std::abs(v1.dot(v2)) / (cv::norm(v1) * cv::norm(v2) + 1e-6); double ang = std::acos(std::clamp(cosang, -1.0, 1.0)); angle_error += std::abs(CV_PI/2 - ang); } double R_angle = 1.0 - angle_error / (2 * CV_PI); R_angle = std::clamp(R_angle, 0.0, 1.0);


③ 边缘直线性(Edge Straightness)

矩形的边应该是 直线

方法:

  • 将 contour 按 rect 四条边投影

  • 对每条边做直线拟合

  • 计算 RMS 偏差

Redge=1−14∑iσiLiR_{\text{edge}} = 1 - \frac{1}{4} \sum_i \frac{\sigma_i}{L_i} Redge​=1−41​i∑​Li​σi​​

✔ 抑制波浪边
✔ 抗噪声

double R_edge = std::min(1.0, rect.size.width / rect.size.height);

或

R_edge = std::min(R_edge, rect.size.height / rect.size.width);

(防止细长假矩形)


④ 填充完整性(Fill Ratio)⭐

Rfill=∑(mask∩rect)AcontourR_{\text{fill}} = \frac{\sum (mask \cap rect)}{A_{\text{contour}}} Rfill​=Acontour​∑(mask∩rect)​

✔ 能容忍局部缺损
✔ 抑制 U 形、C 形

double R_fill = area / (area + hole_area + 1e-6);


五、最终 Rectness 代码示例(可直接用)

double rectness = 0.35 * R_area + 0.25 * R_angle + 0.20 * R_edge + 0.20 * R_fill;

推荐阈值

MIN_RECTNESS = 0.72 ~ 0.80

(亮矩形建议 ≥ 0.78)


六、你这个项目里的专用优化建议

结合你前面的逻辑(圆内矩形):

🔥 额外加一项:径向一致性

Rradial=1−σ(dcorner)rR_{\text{radial}} = 1 - \frac{\sigma(d_{\text{corner}})}{r} Rradial​=1−rσ(dcorner​)​

✔ 矩形四角到圆心距离应接近
✔ 可强力抑制噪声连通块


Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐