Ask Your Question

OpenCV4Android: Extracting a MatOfPoint from a Canny image for input into convexHull

asked 2013-03-18 10:43:52 -0600

Dangthrimble gravatar image

updated 2013-03-18 10:52:21 -0600


I am trying to teach myself Eclipse (ADT), Java, Android and OpenCV all at the same time (!) and need a way in Java to extract a MatOfPoint from a Canny image for inputting into convexHull. Can anyone advise?


edit retag flag offensive close merge delete



bear with me for not knowing anything about android, but you can't get the convexHull from a Canny image directly. you need to findContours() from a binary image first ( and better try threshold() instead of canny ) , then you get a list of countours and can get the hull for one ore more of the contours.

berak gravatar imageberak ( 2013-03-18 12:20:27 -0600 )edit

Why is threshold() better than Canny()? Reading the documentation, it appears Canny() can be used on a colour image whereas threshold() works on a grayscale image. If I'm starting with a colour image why is it better to convert it to grayscale and use threshold()?


Dangthrimble gravatar imageDangthrimble ( 2013-03-18 13:02:15 -0600 )edit
  1. you need to convert to grayscale anyway. (yes, you can do Canny from rgb, but it's not useful here)
  2. Edge filters like Canny or Sobel tend to break your contour into pieces, also each thing then has an outer and an inner edge, but try out, and see for yourself
berak gravatar imageberak ( 2013-03-18 13:06:12 -0600 )edit

Decided to go with the suggestion of using threshold() rather than Canny(). However when I try to convert the RGBA Mat to gray in preparation using "Imgproc.cvtColor(inRgbaMat, outGrayMat, Imgproc.COLOR_RGBA2GRAY);" all I get is a crash: OpenCV Error: Assertion failed (scn == 3 || scn == 4) in void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int), file /home/reports/ci/slave/50-SDK/opencv/modules/imgproc/src/color.cpp, line 3326

Any advice?

Dangthrimble gravatar imageDangthrimble ( 2013-03-19 10:12:06 -0600 )edit

inRgbaMat needs to be rgb or rgba. check if it's valid at all

berak gravatar imageberak ( 2013-03-19 10:22:43 -0600 )edit

How would I check that? inRgbaMat.size() returns 480x480 and inRgbaMat.type() returns 0. Does that help and, if so, what does it mean?

Dangthrimble gravatar imageDangthrimble ( 2013-03-19 10:32:56 -0600 )edit

at least, a valid image(type()==0 <-> uchar). channels() ? maybe it is already grayscale

berak gravatar imageberak ( 2013-03-19 10:39:36 -0600 )edit

The original image (origMat) is created using CvCameraViewFrame.rgba() and inRgbaMat is then created using origMat.submat(), so I would expect it to be RGBA.

Dangthrimble gravatar imageDangthrimble ( 2013-03-19 10:45:26 -0600 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2013-03-18 12:50:56 -0600

Dangthrimble gravatar image

So how about the following (assuming I want all the points but only on the external contour)?

Mat cannyMat = new Mat();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
MatOfInt hull = new MatOfInt();

Imgproc.Canny(originalMat, cannyMat, threshold1, threshold2);
Imgproc.findContours(cannyMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CV_CHAIN_APPROX_NONE);
Imgproc.convexHull(contours.get(0), hull);

Assuming that's correct, how do I then convert the hull back to a Mat that can be overlaid over originalMat?

edit flag offensive delete link more


looks good to me, maybe cvtColor() to grayscale first ;)

the hull is either a list of points (that would be MatOfPoint, right ? ) or a list of indices into the contour( i think, that's what you got now) , again to visualize it, you'll probably draw lines in your original (color) Mat.

berak gravatar imageberak ( 2013-03-18 13:00:42 -0600 )edit

if you use : public Mat onCameraFrame(CvCameraViewFrame inputFrame) { You already have a grayimage with : mat gray = inputFrame.gray();

Pascal66 gravatar imagePascal66 ( 2013-09-17 08:50:37 -0600 )edit

Question Tools


Asked: 2013-03-18 10:43:52 -0600

Seen: 2,420 times

Last updated: Mar 18 '13