does anyone know why the MatLab Canny (MLC) is so different compared to the OpenCV Canny (OCC)? ML-C delivers precise and more connected edges than the OCC, but how is that possible? The reason why I ask is, that I need to implement my protoype of ML code into C++ and I wanted to use OpenCV. Exporting code of ML isn't really possible as far as I have tried.

Kind regards,

  • 3
    $\begingroup$ Did you check the thresholds and other parameters settings? If you don't supply them, they are chosen automatically, and the strategy can vary. $\endgroup$ Oct 18, 2012 at 22:46
  • $\begingroup$ Hey Andrey, I know that they are provided automatically if you don't set them. I checked the thresholds and varied them, but results aren't of the same quality as the ML results with any combination. $\endgroup$
    – mchlfchr
    Oct 19, 2012 at 6:09
  • $\begingroup$ As far as I know that OpenCV is using Sobel for the gradients. Maybe ML is using an approximation of Gauss for the gradients, because it models the properties of edges in a better way? regards, $\endgroup$
    – mchlfchr
    Oct 22, 2012 at 16:35
  • $\begingroup$ You can type edit edge in Matlab, and see the relevant case. It is all open-source - no built-ins as far as I know. $\endgroup$ Oct 22, 2012 at 16:55
  • $\begingroup$ Yes, I know, but for some routines (like the gradient calculus) you can't go deeper. And the routine of the Canny is very long, so I thought someone here already has made that experience. ;) So I was wrong, because nobody gave me an answer on that. $\endgroup$
    – mchlfchr
    Oct 23, 2012 at 7:49

1 Answer 1


As suggested above, the Matlab Canny edge detector calculates the gradient using a "derivative of a Gaussian filter" (as stated in the documentation). In other words, Matlab does a Gaussian blur of the image and then finds the gradient of that smoothed image... all using a single fancy filter. [If you want to know the details, just type in edit edge as Andrey suggested, and then scroll down to the smoothGradient() function.]

The blurring operation significantly reduces the amount of noise present in the image, eliminating many spurious edges and leaving behind the good stuff.

Unfortunately, the OpenCV Canny function doesn't let you change the filter kernel it uses via the function parameters. However. You can generate the same results by first blurring the input image, and then passing this blurred image into the Canny function.

This significantly cleans up the resulting edge map. To blur the input image, I personally use OpenCV's GaussianBlur() function with sigmaX=2. This mimics the default sigma in Matlab. The best blurring kernel size can vary from case to case, but in Matlab it is calculated using filterLength = 8*ceil(sigma);, so for a sigma of 2 that would mean a kernel size of (16,16)

Since both the Gaussian Blur and Sobel filters are linear, passing a blurred input image to the OpenCV Canny() function is mathematically equivalent to what Matlab does because of the principle of superposition, as demonstrated in this pseudocode (note: * is the convolution operator):

// The Matlab method: the sobel and blur operations are combined into
// a single filter, and that filter is then convolved with the image
matlabFancyFilter = (sobel * blur);
gradient = matlabFancyFilter * image;

// Equivalent method: image is first convolved with the blur filter, and
// then convolved with the sobel filter.
gradient = sobel * (blur * image); // image is filtered twice

There is an OpenCV Canny tutorial here that demonstrates how to do this using C++. I'm a python guy, so here is what I do:

smoothedInput = cv2.GaussianBlur(image, (7,7), 2);
edges = cv2.Canny(smoothedInput, 25, 50);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.