3

我试图在 Android 上实现 OpenCV 的分水岭功能。但是我的程序总是在调用分水岭函数的地方崩溃。我可以很好地输出标记的结果。但分水岭函数总是崩溃。这是我的代码:

         Mat threeChannel = new Mat();
         Imgproc.cvtColor(mRgba, threeChannel, Imgproc.COLOR_BGR2GRAY);
         Imgproc.threshold(threeChannel, threeChannel, 100, 255, Imgproc.THRESH_BINARY);

         Mat fg = new Mat(mRgba.size(),CvType.CV_8U);
         Imgproc.erode(threeChannel,fg,new Mat(),new Point(-1,-1),2);

         Mat bg = new Mat(mRgba.size(),CvType.CV_8U);
         Imgproc.dilate(threeChannel,bg,new Mat(),new Point(-1,-1),3);
         Imgproc.threshold(bg,bg,1, 128,Imgproc.THRESH_BINARY_INV);

         Mat markers = new Mat(mRgba.size(),CvType.CV_8U, new Scalar(0));
         Core.add(fg, bg, markers);

         WatershedSegmenter segmenter = new WatershedSegmenter();
         segmenter.setMarkers(markers);
         Mat result = segmenter.process(mRgba);

         return result;

WatershedSegmenter 类如下:

public class WatershedSegmenter{
    public Mat markers;

    public void setMarkers(Mat markerImage)
    {
        markerImage.convertTo(markers, CvType.CV_32S);
    }

    public Mat process(Mat image)
    {
        Imgproc.watershed(image, markers);
        markers.convertTo(markers,CvType.CV_8U);
        return markers;
    }
}

有没有人设法让这个在Android上运行?在遵循本教程之前,我设法让它在 C++ 中与 Qt 一起工作:link。但是我目前在Android上没有任何运气。

4

3 回答 3

3

我现在找到了崩溃的原因。watershed 采用 8 位 3 通道格式的数据,而 RGBA 是 4 通道数据。我只是将它从 RGBA 转换为 RGB,它解决了所有问题。

于 2013-10-10T00:38:35.987 回答
3

您的 Mat 与正确的 .depth() 和/或 .channel() 不匹配。第一步是使用 myMat.depth() 和 myMat.channels() 函数仔细检查每个 Mat 是否具有您认为的类型。函数 watershed 使用两个 Mat 参数。第一个应该是 8 位 3 通道图像,第二个应该是 32 位单通道图像。

如果它们不是正确的图像,请使用 cvtColor 将您拥有的图像转换为您需要的图像。

于 2015-07-16T09:23:19.763 回答
1

试试这个解决方案

BitmapFactory.Options o = new BitmapFactory.Options();
       o.inDither = false;
       o.inSampleSize=4;

       int width , height ;
       width  = src_Bitmap.getWidth();
       height = src_Bitmap.getHeight();



       Mat rgba = new Mat();
       Mat gray_mat= new Mat();
       Mat threeChannel = new Mat();



       Utils.bitmapToMat(src_Bitmap,gray_mat);

       Imgproc.cvtColor(gray_mat,rgba , Imgproc.COLOR_RGBA2RGB);


       Imgproc.cvtColor(rgba, threeChannel, Imgproc.COLOR_RGB2GRAY);
       Imgproc.threshold(threeChannel, threeChannel, 100, 255, Imgproc.THRESH_OTSU);


       Mat fg = new Mat(rgba.size(),CvType.CV_8U);
       Imgproc.erode(threeChannel,fg,new Mat(),new Point(-1,-1),2);

       Mat bg = new Mat(rgba.size(),CvType.CV_8U);
       Imgproc.dilate(threeChannel,bg,new Mat(),new Point(-1,-1),3);
       Imgproc.threshold(bg,bg,1, 128,Imgproc.THRESH_BINARY_INV);



       Mat markers = new Mat(rgba.size(),CvType.CV_8U, new Scalar(0));
       Core.add(fg, bg, markers);

       // Start the WaterShed Segmentation :


       Mat marker_tempo = new Mat();
       markers.convertTo(marker_tempo, CvType.CV_32S);

       Imgproc.watershed(rgba, marker_tempo);
       marker_tempo.convertTo(markers,CvType.CV_8U);

       result_Bitmap=Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565);

       Imgproc.applyColorMap( markers, markers,4 );
       Utils.matToBitmap( markers,result_Bitmap);


        myImageView.setImageBitmap(result_Bitmap);
于 2018-03-18T01:32:30.247 回答