【问题标题】:OpenCV Draw Contours in JAVA (Android)OpenCV 在 JAVA (Android) 中绘制轮廓
【发布时间】:2025-12-10 20:25:03
【问题描述】:

我正在尝试在 JAVA (Android) 中绘制图像的轮廓,但它似乎什么也没做(该函数不绘制任何东西)这是代码:

  public Mat contours(Mat mat)
    {
        ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat hierarchy = new Mat();

        Mat balele = new Mat();
        mat.convertTo(balele, CvType.CV_32SC1);
        // find contours:
        Imgproc.findContours(balele, contours, hierarchy, Imgproc.RETR_FLOODFILL, Imgproc.CHAIN_APPROX_SIMPLE);


        Mat source = new Mat(balele.size(), balele.type());
        for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++)
        {
            Imgproc.drawContours(source, contours, contourIdx, new Scalar(0,0,255), -1);
        }

        return source;
    }

当我们将mat图像传递给方法时,它已经是二进制格式了。

您是否发现任何错误?

更新: 我更新了代码,它看起来像这样:

公共垫子轮廓(垫子垫) {

ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();

// find contours:
Imgproc.findContours(mat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
System.out.println(contours.size() + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");

Mat source = new Mat();
for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++)
{
    Imgproc.drawContours(source, contours, contourIdx, new Scalar(0,0,255), -1);
}

return source;

}

结果:

我仍然没有得到所有的轮廓并且我得到了浅白色。有更正的想法吗?

【问题讨论】:

  • 你能打印contours.size()吗?
  • 是的,我测试的图像结果是:5850
  • 好的。函数返回什么?黑矩阵?
  • 我编辑了原帖,你可以看看吗?
  • 我现在也有同样的问题。无论您设置什么颜色,drawContours() 似乎都只能绘制黑色。是 OpenCV 的 bug 吗?

标签: java android opencv


【解决方案1】:

Imgproc.findContours 会在内部更改输入 Mat,从而创建如上所示的工件,您可以将 Mat 作为克隆对象传递,这样更改不会反映在输入 Mat 上。我不确定是否有更好的解决方案,因为克隆Mat 肯定会占用一些时间和空间(不是太多)。所以你可以使用:

Imgproc.findContours(mat.clone(), contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

【讨论】:

  • 哦,那我的错,但是 OP 没有提到我猜的版本? @三木
【解决方案2】:

我发现了问题。这确实是 OpenCV 库中的一个错误。以下代码正是 OpenCV 在 java 中实现 drawContours() 的方式。它始终使用包含 R、G、B 和 Alpha 的四个值标度。

public static void drawContours(Mat image, List<MatOfPoint> contours, int contourIdx, Scalar color, int thickness, int lineType, Mat hierarchy, int maxLevel, Point offset) {
    List<Mat> contours_tmplm = new ArrayList<Mat>((contours != null) ? contours.size() : 0);
    Mat contours_mat = Converters.vector_vector_Point_to_Mat(contours, contours_tmplm);
    drawContours_0(image.nativeObj, contours_mat.nativeObj, contourIdx, color.val[0], color.val[1], color.val[2], color.val[3], thickness, lineType, hierarchy.nativeObj, maxLevel, offset.x, offset.y);
}

现在,让我们考虑一下 alpha 的默认值是多少。零,对吧?这就是为什么你总是画黑色。解决方案是使用四个值标量,例如 new Scalar(0, 0, 255, 1)

【讨论】: