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

Android绘图应用中OpenCV检测手绘圆、椭圆、五边形的问题

Android绘图应用:圆形、五边形及椭圆检测问题解决方案

核心问题分析

当前遇到的问题本质是:

  • 圆度特征无法区分五边形与圆/椭圆
  • SimpleBlobDetector的参数设置偏向圆形,导致椭圆被过滤,同时误判五边形为Blob

一、优先采用轮廓分析+多特征组合判断(推荐方案)

BlobDetector更适合实心无规则的 blob 识别,对有明确边缘的几何形状,基于轮廓的分析精度更高。具体步骤:

1. 图像预处理

先做灰度化、二值化、边缘检测,提取清晰轮廓:

Mat gray = new Mat();
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
Mat binary = new Mat();
Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU);
Mat edges = new Mat();
Imgproc.Canny(binary, edges, 50, 150);

2. 提取轮廓并计算特征

遍历每个轮廓,计算三个核心特征:

  • 顶点数:用approxPolyDP拟合轮廓得到近似多边形的顶点数量,直接区分五边形(固定5个顶点)
  • 圆度:公式为 4π*面积/(周长²),圆形接近1,五边形约0.9,椭圆随扁率在0.7~0.95之间
  • 惯性率:椭圆的惯性率(短轴/长轴的平方)远小于圆形,五边形的惯性率则和圆形接近

3. 形状匹配规则

List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(edges, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

for (MatOfPoint contour : contours) {
    // 计算面积和周长
    double area = Imgproc.contourArea(contour);
    double perimeter = Imgproc.arcLength(new MatOfPoint2f(contour.toArray()), true);
    if (perimeter == 0) continue;

    // 圆度
    double circularity = 4 * Math.PI * area / (perimeter * perimeter);
    // 轮廓近似,获取顶点数
    MatOfPoint2f contour2f = new MatOfPoint2f(contour.toArray());
    double epsilon = 0.03 * perimeter;
    MatOfPoint2f approx = new MatOfPoint2f();
    Imgproc.approxPolyDP(contour2f, approx, epsilon, true);
    int vertexCount = (int) approx.total();
    // 惯性率
    Moments moments = Imgproc.moments(contour);
    double mu20 = moments.get_mu20();
    double mu02 = moments.get_mu02();
    double inertiaRatio = Math.min(mu20, mu02) / Math.max(mu20, mu02);

    // 形状判断
    if (vertexCount == 5 && circularity >= 0.85) {
        // 五边形
        Imgproc.drawContours(src, Collections.singletonList(contour), -1, new Scalar(0, 255, 0), 2);
    } else if (vertexCount > 10) {
        if (circularity >= 0.95) {
            // 圆形
            Imgproc.drawContours(src, Collections.singletonList(contour), -1, new Scalar(255, 0, 0), 2);
        } else if (circularity >= 0.7 && inertiaRatio < 0.8) {
            // 椭圆
            Imgproc.drawContours(src, Collections.singletonList(contour), -1, new Scalar(0, 0, 255), 2);
        }
    }
}

二、SimpleBlobDetector参数调整(备选方案)

如果坚持使用BlobDetector,调整参数适配椭圆并过滤五边形:

blobDetectorParams.set_filterByInertia(true);
blobDetectorParams.set_filterByCircularity(true);
blobDetectorParams.set_filterByConvexity(true);
blobDetectorParams.set_filterByArea(true); // 开启面积过滤,排除异常尺寸

// 惯性率:过滤五边形(惯性率接近1),保留椭圆(惯性率较低)
blobDetectorParams.set_minInertiaRatio(0.3F);
blobDetectorParams.set_maxInertiaRatio(1.0F);

// 圆度:降低阈值让椭圆通过
blobDetectorParams.set_minCircularity(0.6F);
blobDetectorParams.set_maxCircularity(1.0F);

blobDetectorParams.set_minConvexity(0.87F);

blobDetectorParams.set_minThreshold(0);
blobDetectorParams.set_maxThreshold(300);
blobDetectorParams.set_thresholdStep(10);
blobDetectorParams.set_minRepeatability(1);

// 根据你的绘图尺寸设置合理的面积范围
blobDetectorParams.set_minArea(100.0F);
blobDetectorParams.set_maxArea(10000.0F);

注意事项

  • 预处理时可添加形态学操作(如Imgproc.dilate)平滑笔画边缘,减少轮廓噪声
  • 轮廓近似的epsilon参数需根据实际绘图调整,建议设为周长的0.02~0.05倍

内容的提问来源于stack exchange,提问作者gabry2298

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:10:33