OpenCV的drawContours函数使Android应用程序崩溃

时间:2019-07-05 22:50:56

标签: java android opencv

我想在我的Android应用中绘制由Imgproc.findContours检测到的最大轮廓。 Imgproc.findContours似乎找到了一堆轮廓,但是当它尝试执行Imgproc.drawContours函数时,代码崩溃了。

这是Java代码:

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(result, contours, hierarchy, Imgproc.RETR_FLOODFILL, Imgproc.CHAIN_APPROX_SIMPLE);

largest_area = 0;
largest_contour_index = -1;

for(int i = 0; i<contours.size(); i++){
    double area = Imgproc.contourArea(contours.get(i));
    if(area > largest_area){
        largest_area = area;
        largest_contour_index = i;
    }
}

Mat contourDrawing = Mat.zeros(result.rows(), result.cols(),  CvType.CV_8UC3);

Log.d("contours.size()", Integer.toString(contours.size()));
Log.d("largest_area", Double.toString(largest_area));
Log.d("largest_contour_index", Integer.toString(largest_contour_index));

Imgproc.drawContours(contourDrawing, contours, largest_contour_index, new Scalar(255, 0, 0), 2);

Logcat输出如下,表明检测到轮廓:

D / contours.size():1901

D / largest_area:343974.0

D / largest_contour_index:825

但是当涉及到使用Imgproc.drawContours绘制轮廓时,应用程序崩溃。我正在使用OpenCV版本3.4.3。有人知道这里可能出什么问题吗?非常感谢你!

这是错误日志:

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb930b93 in tid 30396 (Thread-2), pid 30213

/lib/arm64/libopencv_java3.so (cv::drawContours(cv::_InputOutputArray const&, cv::_InputArray const&, int, cv::Scalar_<double> const&, int, int, cv::_InputArray const&, int, cv::Point_<int>)+2124)

/lib/arm64/libopencv_java3.so (Java_org_opencv_imgproc_Imgproc_drawContours_11+252)

/dev/ashmem/dalvik-classes.dex extracted in memory from ==/base.apk (deleted) (org.opencv.imgproc.Imgproc.drawContours+102)

1 个答案:

答案 0 :(得分:0)

我不太了解Java,但也许我可以帮忙吗?

建议: 1.使用numpy的zeros_like(image)而不是仅仅为了简化事情并减少那里的错误机会而采用行和列怎么办?

根据我的经验,

绘制轮廓会永远改变您绘制的图像。但是您只为轮廓创建图像,所以您已经知道了...

我对问题的猜测:

对于您向drawContours函数的输入,您的第二个参数应该是findContours中的“检测到的轮廓” ...我不能说真的,但看起来可能是{{1 }} 为了你。您是否尝试过在轮廓参数中使用result(在本例中为result)?

在Python中,我像这样使用它:

contours_to_draw

-1用于绘制所有轮廓。如果只想绘制一些,则可以通过更改此值来绘制第一个或第二个,依此类推,但是如果您知道要绘制的轮廓,建议您将它们传递给contours_to_draw,而不要使用此参数来确定要绘制的轮廓画。我想您也已经知道这一切,但是重述这些内容并没有什么害处。

这完全有帮助吗?