I have some questions about the Canny edge detector in OpenCV.
Here is the code I tried.
def auto_canny(image, sigma=0.33):
v = np.median(image)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
then,
##### first situation #####
img = cv2.imread('mango.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
auto = auto_canny(gray)
cv2.imwrite('mango_gray_edge.jpg', auto)
In this situation, I got an image like this:
##### second situation #####
img = cv2.imread('mango.jpg')
auto = auto_canny(img)
cv2.imwrite('mango_color_edge.jpg', auto)
in this situation, I got an image like this:
and this is the original image:
The different between the first situation and the second situation is whether I convert the color image to grayscale. But, I am confused about this. Because,
In the first situation, I convert the image to grayscale, so the image has a single channel. And in the second situation, the image still has three channels.
And the edge is much better when I didn’t convert it to grayscale, just like in second situation.
So my question is,
Does the Canny function in OpenCV include method to convert image to grayscale? I mean, do I need to convert the image to grayscale before I use cv2.Canny()
?
How does Canny deal with both single channel (first situation convert to grayscale) and three channels (original image like second situation) image at the same time?
How does Canny actually work? Could Canny deal with color image directly or must the color image be converted to grayscale first?
From the steps of Canny, when we calculate gradient, I think it should be single channel, then it can be calculated. If the image is color (three channels), how can we calculate the gradient? Do we calculate three channels separately? How does it work?
Yes, OpenCV's Canny implementation can handle multiple channels.
Remember that OpenCV is open-source, so you can just check the implementation to find this kind of information.
Basically, what Canny does before non-maxima suppression is to compute the magnitude (norm
) of the gradient for each pixel, according to Sobel derivatives (dx
and dy
).
If you have more than one channel, as you can see in the source code, the magnitude of the gradient for a given pixel is the highest among all the ch
channels.