How can I select the best set of parameters in the Canny edge detection algorithm implemented in OpenCV?
Asked Answered
B

2

25

I am working with OpenCV on the Android platform. With the tremendous help from this community and techies, I am able to successfully detect a sheet out of the image.

These are the step I used.

  1. Imgproc.cvtColor()
  2. Imgproc.Canny()
  3. Imgproc.GausianBlur()
  4. Imgproc.findContours()
  5. Imgproc.approxPolyDP()
  6. findLargestRectangle()
  7. Find the vertices of the rectangle
  8. Find the vertices of the rectangle top-left anticlockwise order using center of mass approach
  9. Find the height and width of the rectangle just to maintain the aspect ratio and do warpPerspective transformation.

After applying all these steps I can easily get the document or the largest rectangle from an image. But it highly depends on the difference in the intensities of the background and the document sheet. As the Canny edge detector works on the principle of intensity gradient, a difference in intensity is always assumed from the implementation side. That is why Canny took into the account the various threshold parameters.

  1. Lower threshold
  2. Higher threshold

So if the intensity gradient of a pixel is greater than the higher threshold, it will be added as an edge pixel in the output image. A pixel will be rejected completely if its intensity gradient value is lower than the lower threshold. And if a pixel has an intensity between the lower and higher threshold, it will only be added as an edge pixel if it is connected to any other pixel having the value larger than the higher threshold.

My main purpose is to use Canny edge detection for the document scanning. So how can I compute these thresholds dynamically so that it can work with the both cases of dark and light background?

I tried a lot by manually adjusting the parameters, but I couldn't find any relationship associated with the scenarios.

Buckman answered 24/1, 2014 at 5:12 Comment(4)
to the one who down vote , can you please explain whats wrong with this ?Buckman
there are geniuses who love voting down, it's a good question for me.Bassett
Imgproc.cvtColor() in which color we should convert ? A grayscale ?Fumatorium
Hey can you please provide full implementation and code of above steps ? or a link where i can get anything.. It would b great help, because we are following your steps for our project @AnkurGautamFumatorium
N
27

You could calculate your thresholds using Otsu’s method.

The (Python) code would look like this:

high_thresh, thresh_im = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
lowThresh = 0.5*high_thresh
Navarre answered 24/1, 2014 at 7:27 Comment(10)
Im needs to be a gray scale image ? The main problem i am facing is, though the background looks different than the sheet of paper but in the gray scale ,since both of them almost the same intensity ,they look same.Buckman
And hence canny edge detector is not able to detect the edges of the sheet that sharply(3 of the four edges are detected sharp but in the other edge ,there is a gap but depending upon the real life images it should not be advised to predict the other edge based on three edges ?) I tried with dilation to fill the gap ,but it seems creating other problems(giving some extra edges) based on the Kernal used(A rectangle of 2*2 generally). I will give it a try to compute parameters of canny using your method . And by the time if you have any thought ,please share with me.Buckman
Maybe you should look for a better Segmentation strategy.Navarre
I don't want to do the segmentation more exactly.I want to scan the pages out of the image(remove the extra things and warp perspective things) ,that is more like the functionality used by the camScanner app. They can easily detect the edges easily even on the almost same background. As i am new to openCV,i want to know if there is any filter or something else that enlarge the intensity difference between the parts of the image(i mean create more intensity gradient but in the original format)Buckman
not giving me the desired result or perhaps i should say the bad as compared to previous parameters.Value of Higher Threshold comes out to be around 121Buckman
@Navarre You would need to use Otsu's method on the gradient magnitude image, not the image itself, no?Afrikah
@DavidDoria If your image has distinct foreground and background you can use it directly on the image,Navarre
@Navarre Though it may "work" in easy cases, this seems like conceptually very much the wrong thing to use. The gradient magnitude image that gets thresholded is float valued in the range 0 - [thousands], so using a function of the Otsu threshold computed on the original image will always produce Canny thresholds that are at the very very low end of the range (since they are [0-255]), which basically just separates "definitely not edge" from "at least a little edge". In cases where this works I bet you'd get the same result if you just hard code "100" or even "200" as the threshold.Afrikah
Isn't the magnitude image [-thousands, +thousands] depending on the phase of the edges? Using Otsu on that wouldn't be very helpfull either... could work if you use the absolute of the magnitude gradient. I used the method as presented here and it worked on more than just trivial cases for me, but I haven't proved it to be correct scientifically. If you have the time and passion I would be happy to see an Answer from you with a new approach and a scientificall explanation though!Navarre
@AnkurGautam -Have you fixed your problem? Can you please help me to fix the same problem?Lima
T
7

Use the following snippet which I obtained from this blog:

v = np.median(gray_image)

#---- Apply automatic Canny edge detection using the computed median----
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(gray_image, lower, upper)
cv2.imshow('Edges',edged)

##So what am I doing here?

I am taking the median value of the gray scale image. The sigma value of 0.33 is chosen to set the lower and upper threshold. 0.33 value is generally used by statisticians for data science. So it is considered here as well.

Transcript answered 4/2, 2017 at 6:48 Comment(2)
Would be great if you gave the reference : pyimagesearch.com/2015/04/06/…Boorer
Mentioned it in the answerTranscript

© 2022 - 2024 — McMap. All rights reserved.