rectness(矩形度)数学定义优化
在 _rect_candidates_from_binary 里,大多数人会写成👇这样之一:
1️⃣ 面积比型(最常见)
rectness=AcontourAminAreaRectrectness = \frac{A_{\text{contour}}}{A_{\text{minAreaRect}}} rectness=AminAreaRectAcontour
double rectness = contourArea / rect.area();
✔ 简单
❌ 对旋转、缺角、噪声很敏感
2️⃣ 外接矩形填充率
rectness=Amask ∩ rectArectrectness = \frac{A_{\text{mask ∩ rect}}}{A_{\text{rect}}} rectness=ArectAmask ∩ 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=w1Rarea+w2Rangle+w3Redge+w4Rfill
权重示例(可调):
w = [0.35, 0.25, 0.20, 0.20]
四、四个子指标的数学定义 + 工业意义
① 面积一致性(Area Consistency)
Rarea=AcontourAminAreaRectR_{\text{area}} = \frac{A_{\text{contour}}}{A_{\text{minAreaRect}}} Rarea=AminAreaRectAcontour
✔ 快速筛掉奇形怪状
✔ 允许缺角(≤ 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−41i∑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−41i∑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)
✔ 矩形四角到圆心距离应接近
✔ 可强力抑制噪声连通块
更多推荐
所有评论(0)