5

According to my research, Canny Edge Detector is very useful for detecting the edge of an image. After I put many effort on it, I found that OpenCV function can do that, which is

    Imgproc.Canny(Mat image, Mat edges, double threshold1, double threshold2)

But for the low threshold and high threshold, I know that different image has different threshold, so can I know if there are any fast adaptive threshold method can automatically assign the low and high threshold according to different image?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Hua Er Lim
  • 231
  • 2
  • 4
  • 10
  • Rui Marques,can you help me?Thanks in advance. – Hua Er Lim Oct 02 '12 at 05:37
  • You should look in the code source of OpenCV, they use internally in the threshold method an adaptive threshold computation from Otsu. You could use that to obtain the high treshold for canny and multiply it with 0.4 <-> 0.5 to obtain the low threshold. – Adrian Oct 02 '12 at 05:47
  • Adrian Popovici,you means like this: Imgproc.Canny(image, image, 0.4*Imgproc.THRESH_OTSU, Imgproc.THRESH_OTSU)?But the image result very blur now.Sorry because i am new to OpenCV and i try my best to research on it already.Hope you can help me.Thanks. – Hua Er Lim Oct 02 '12 at 07:11
  • I don't know in Java how you can get the Otsu threshold, but you should have a method like this: getOtsuThreshold(image) that returns an integer. Then you just apply it like this Canny(srcImage, dstImage, 0.4 * thresh, thresh). Remember to have the destination image different then the source. – Adrian Oct 02 '12 at 07:35
  • Hi, i see that you wrote my name in the comments but you have to write @ before the name for that person to be notified. – Rui Marques Oct 04 '12 at 09:23

2 Answers2

5

This is relatively easy to do. Check out this older SO post on the subject.

A quick way is to compute the mean and standard deviation of the current image and apply +/- one standard deviation to the image.

The example in C++ would be something like:

Mat img = ...;
Scalar mu, sigma;
meanStdDev(img, mu, sigma);

Mat edges;
Canny(img, edges, mu.val[0] - sigma.val[0], mu.val[0] + sigma.val[0]);

Another method is to compute the median of the image and target a ratio above and below the median (e.g., 0.66*medianValue and 1.33*medianValue).

Hope that helps!

Community
  • 1
  • 1
mevatron
  • 13,911
  • 4
  • 55
  • 72
3

Opencv has an adaptive threshold function. With OpenCV4Android it is like this:

Imgproc.adaptiveThreshold(src, dst, maxValue, adaptiveMethod, thresholdType, blockSize, C);

An example:

Imgproc.adaptiveThreshold(mInput, mInput, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 15, 4);

As for how to choose the parameters, you have to read the docs for more details. Choosing the right threshold for each image is a whole different question.

Rui Marques
  • 8,567
  • 3
  • 60
  • 91