JavaCV中findContours未识别内部矩形,反而勾勒图像边缘问题求助
解决ROI内矩形/正方形检测失败的问题
我来帮你梳理下当前代码的核心问题:你直接对截取的ROI做反色后就提取轮廓,这会把整个ROI的边缘误识别为有效轮廓,而没有精准分离出内部的正方形。下面是几个具体的解决方向,一步步帮你修正问题:
1. 替换简单反色,用阈值分割精准分离前景背景
当前的Core.bitwise_not只是简单反转灰度,没有区分前景(正方形)和背景的灰度差异,导致ROI边缘被误识别。建议用Otsu自动阈值或自适应阈值生成二值图,精准提取正方形区域:
Mat gray = new Mat(); Mat binary = new Mat(); // 注意这里用你截取的areaOfInterest,而不是原始image cvtColor(areaOfInterest, gray, COLOR_BGR2GRAY); // 用Otsu自动阈值分割,反色让正方形变为白色前景 threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); // 如果场景光照不均,改用自适应阈值效果更好 // adaptiveThreshold(gray, binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 11, 2);
2. 添加轮廓筛选逻辑,过滤无效轮廓
提取轮廓后不能直接绘制外接矩形,需要通过特征筛选出真正的正方形/矩形:
- 过滤面积过小或过大的轮廓(排除噪声和ROI边缘)
- 用轮廓逼近得到简化多边形,判断顶点数是否为4(矩形的核心特征)
- 验证长宽比是否符合正方形(接近1)或目标矩形的范围
示例代码:
Mat hierarchy = new Mat(); ArrayList<MatOfPoint> contours = new ArrayList<>(); // 用CHAIN_APPROX_SIMPLE减少轮廓点数量,提升效率 findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); if (!contours.isEmpty()) { for (MatOfPoint contour : contours) { // 计算轮廓面积,过滤无效轮廓(阈值根据你的ROI尺寸调整) double area = contourArea(contour); if (area < 15 || area > (23*25)*0.8) { continue; } // 轮廓逼近,得到简化的多边形 MatOfPoint2f contour2f = new MatOfPoint2f(contour.toArray()); double epsilon = 0.04 * arcLength(contour2f, true); MatOfPoint2f approxPoly = new MatOfPoint2f(); approxPolyDP(contour2f, approxPoly, epsilon, true); MatOfPoint approx = new MatOfPoint(approxPoly.toArray()); // 判断是否是4个顶点的凸多边形(矩形/正方形的特征) if (approx.rows() == 4 && isContourConvex(approx)) { Rect rect = boundingRect(approx); double aspectRatio = (double) rect.width / rect.height; // 正方形的长宽比接近1,可根据实际情况调整范围 if (aspectRatio >= 0.9 && aspectRatio <= 1.1) { // 在ROI上绘制识别到的正方形 rectangle(areaOfInterest, rect.tl(), rect.br(), new Scalar(0, 0, 255), 2); Imgcodecs.imwrite("F:\\rect.png", areaOfInterest); } } } }
3. 可选:形态学操作消除噪声
如果ROI内存在小噪声点,可在二值化后添加形态学操作,优化轮廓质量:
// 创建2x2的矩形结构元素 Mat kernel = getStructuringElement(MORPH_RECT, new Size(2, 2)); // 腐蚀消除小噪声 erode(binary, binary, kernel); // 膨胀恢复轮廓原有形状 dilate(binary, binary, kernel);
这些步骤的核心是先精准分离前景和背景,再通过轮廓特征筛选目标,应该能帮你正确识别出ROI内的正方形。
内容的提问来源于stack exchange,提问作者warezthief
相关产品推荐
相关产品推荐

