Ask Your Question
1

StructuredEdgeDetection - detectEdges method - Android [closed]

asked 2018-04-10 07:20:05 -0600

charara gravatar image

updated 2018-04-10 09:27:31 -0600

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;
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by LBerger
close date 2018-04-10 09:38:59.898973

Comments

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?

charara gravatar imagecharara ( 2018-04-10 07:58:35 -0600 )edit

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

LBerger gravatar imageLBerger ( 2018-04-10 08:02:07 -0600 )edit

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

charara gravatar imagecharara ( 2018-04-10 08:23:14 -0600 )edit

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);

LBerger gravatar imageLBerger ( 2018-04-10 08:27:38 -0600 )edit

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 :

    //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;
charara gravatar imagecharara ( 2018-04-10 08:45:23 -0600 )edit

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 :

 Imgproc.cvtColor(rgba, rgb, Imgproc.COLOR_BGRA2RGB);
 rgb.convertTo(src, CvType.CV_32F, 1.0 / 255.0);
pDollar.detectEdges(src, edges);

you don't need to resize grey image

LBerger gravatar imageLBerger ( 2018-04-10 09:05:57 -0600 )edit
1

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.

charara gravatar imagecharara ( 2018-04-10 09:25:36 -0600 )edit

Imgproc.cvtColor(rgba, rgb, Imgproc.COLOR_BGRA2BGR); Image must be converted in RGB because I thnik model.yml is trained using RGB space

LBerger gravatar imageLBerger ( 2018-04-10 09:38:20 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-04-10 07:44:11 -0600

LBerger gravatar image

updated 2018-04-10 08:37:50 -0600

Are you sure that rgba is a color image with three channels and only three ?

   rgba.convertTo(src, CvType.CV_32FC3, 1.0 / 255.0);

when you give a grey image to previous line no exception is thrown and src type can be 32FC1

CvType.CV_32FC3 is not use because in cvtColor there is a mask : _type = CV_MAKETYPE(CV_MAT_DEPTH(_type), channels());

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-04-10 07:20:05 -0600

Seen: 925 times

Last updated: Apr 10 '18