StructuredEdgeDetection - detectEdges method - Android [closed]
Hi everyone,
I managed until now with help of the forum to install openCV with extra modules and to get a model for the StructuredEdgeDetection and to implement it correctly to android. My problem now is with method detectEdges which gives an error every time I try to execute it. Here is my code :
//bitmap to detect it's edges
Mat rgba = new Mat();
Utils.bitmapToMat(bitmap, rgba);
//same bitmap to to greyscale it
Mat grey = new Mat();
Utils.bitmapToMat(bitmap, grey);
StructuredEdgeDetection pDollar = createStructuredEdgeDetection(DATA_PATH + "SEDmodel" + ".yml");
//convert the source Mat object to float
Mat src = new Mat();
rgba.convertTo(src, CvType.CV_32FC3, 1.0 / 255.0);
//convert the destination Mat to float
Mat edges = new Mat(grey.size(), CvType.CV_8UC1);
Imgproc.cvtColor(grey, edges, Imgproc.COLOR_RGB2GRAY, 4);
grey.convertTo(edges, CvType.CV_32FC3, 1.0 / 255.0);
//try to detect the edges
pDollar.detectEdges(src, edges);
//convert the edges to Mat
Mat output = new Mat();
edges.convertTo(output, CvType.CV_8UC1, 255.0);
//convert Mat to bitmap to display it
Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(edges, resultBitmap);
return resultBitmap;
The error that I'm getting :
Caused by: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(3.4.0-dev) /Users/Chao/opencv_contrib/modules/ximgproc/src/structured_edge_detection.cpp:529: error: (-215) _src.type() == (((5) & ((1 << 3) - 1)) + (((3)-1) << 3)) in function virtual void cv::ximgproc::StructuredEdgeDetectionImpl::detectEdges(cv::InputArray, cv::OutputArray) const
I checked the line 529 in structured_edge_detection.cpp (link) as shown in the error and I saw this :
* The function detects edges in src and draw them to dst
*
* \param _src : source image (RGB, float, in [0;1]) to detect edges
* \param _dst : destination image (grayscale, float, in [0;1])
* where edges are drawn
And to my understanding that's what I did in the code snippet above. Any help is much appreciated.
EDIT :
With much help from @LBerger I managed to put this together and make it work :
//bitmap to detect it's edges
Mat rgba = new Mat();
Utils.bitmapToMat(bitmap, rgba);
//convert it to rgb
Mat rgb = new Mat();
Imgproc.cvtColor(rgba, rgb, Imgproc.COLOR_BGRA2BGR);
//convert the source Mat object to float
Mat src = new Mat();
rgb.convertTo(src, CvType.CV_32F, 1.0 / 255.0);
//give the destination Mat the same parameters as the destination Mat
Mat edges = new Mat(src.size(), src.type());
//try to detect the edges
StructuredEdgeDetection pDollar = createStructuredEdgeDetection(DATA_PATH + "SEDmodel" + ".yml");
pDollar.detectEdges(src, edges);
//optional -- computes orientation from edge map
Mat orientation_map = new Mat();
pDollar.computeOrientation(edges, orientation_map);
//optional -- suppress edges
Mat edge_nms = new Mat();
pDollar.edgesNms(edges, orientation_map, edge_nms, 2, 0, 2, true);
//convert the edges to Mat
edges.convertTo(edges, CvType.CV_8U, 255.0);
//convert Mat to bitmap to display it
Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(edges, resultBitmap);
return resultBitmap;
The bitmap is a photo taken directly from the phone camera. After resizing it and I feed it to the method I created above. So yes I'm sure it's a color image. I edited my post to link the .cpp class I'm referring to and inside the method there is this line :
CV_Assert( _src.type() == CV_32FC3 );
that's why I used CV_32FC3 . I tried with CV_32FC1 and even with CV_32F but I keep having the same problem and I can't understand what these numbers in the error means ? :
_src.type() == (((5) & ((1 << 3) - 1)) + (((3)-1) << 3))
do you have any idea?
First src is not Cv_32FC3 sure! Check again it can be a png image with an alpha channel too CV_8UC4 will give CV_32FC4
I tried it with CV_8UC4 and it didn't work too. I still have the same error. I have OpenCV 3.3.1 and I got it from here with opencv-contrib. Could this be the problem ? since I didn't get it from the official repo? and could you please explain the numbers I mentioned in the previous comment ? maybe then I can understand the error better. Thanks
We are agree image type must be 32FC3. src in pDollar.detectEdges(src, edges); is not 32FC3. Just try Mat src2 = new Mat(grey.size(), CvType.CV_32FC3); and pDollar.detectEdges(src2, edges);
Ok ! i replaced the src with the line code you gave me !! and I didn't get the error. That means probably it worked. But now the image output is all black. I saw a thread about that and they suggested to add this line : edges.convertTo(edges, CvType.CV_8U, 255.0); before displaying. I tried it but It didn't work. Any idea ?
The last bit of my code looks like this now :
result with src2 is black because pixels in image should be 0 or constant.
You can multiply edge_im by 255 and convert to uchar to display image. Check example
try to convert rgba in rgb :
you don't need to resize grey image
Thank you ! it worked !! and sorry I can't up vote your answers since I have enough points ! I'll update my post with the working code so everybody can benefit from it.
Imgproc.cvtColor(rgba, rgb, Imgproc.COLOR_BGRA2BGR); Image must be converted in RGB because I thnik model.yml is trained using RGB space