我试图在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 calss如下:
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上运行?在使用本教程之前,我设法使用Qt在C ++中工作:link。但是我目前在Android上没有运气。
答案 0 :(得分:3)
我现在发现了崩溃的原因。分水岭采用8位3通道数据格式,RGBA采用4通道数据。我只是将它从RGBA转换为RGB,它解决了所有问题。
答案 1 :(得分:3)
您的Mat与正确的.depth()和/或.channel()不匹配。 第一步是使用myMat.depth()和myMat.channels()函数仔细检查每个Mat是否具有您认为它的类型。功能分水岭使用两个Mat参数。第一个应该是一个8位,3通道图像,第二个应该是一个32位单通道图像。
如果它们不是正确的图像,请使用cvtColor将您所拥有的图像转换为您需要的图像。
答案 2 :(得分: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);