1

I am trying to do perspective transform for documents in various background and light conditions. Currently, I can't do it on this image because the contour is not close.

The original Image

Edge Detection of image

So far, I have tried Adaptive Threshold, GaussianBlur, MedianBlur,all kind of Morphology operations, Hough Transform and Histogram Equalization and play with all of the parameters in them but nothing has worked.

Can anyone help me with this issue ?

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • 3
    I'd try converting to [HSV color space](https://en.wikipedia.org/wiki/HSL_and_HSV). The nearly white paper will have close to `0` S values, but large V values. Threshold both channels separately, and combine their masks. Play around with the cutoffs to get your desired discrimination in the faulty area. – HansHirse Dec 14 '20 at 09:07
  • I thought about it but you have to manually change S values and V values of the threshold for every image, right ? which is almost like hard code which is not I looking for – Minh Vũ Hoàng Dec 14 '20 at 10:24
  • Not necessarily, no. The white paper will always have close to `0` saturation, even if the light conditions are such that it becomes gray-ish. How do your backgrounds and light conditions change? Can the white paper appear "color-ish"? For potential varying value (as value for V in HSV) changes caused by less light, do some preprocessing (histogram equalization?) beforehand to get your white paper to be white-ish again. Finally, post some more examplary images, so that people here get an idea, what your real dataset looks like. – HansHirse Dec 14 '20 at 10:30
  • I think what @HansHirse proposes is one of the better ideas you can process sample images like the one you've posted. You can use HSV or HSL color space and maybe ascertain desirable value for segmentation from a sample region (pixels containing highest average lightness for e.g. in HSL space) from the center of the image assuming that the center always contains the foreground. – Knight Forked Dec 14 '20 at 13:59
  • 1
    Check if the answers to this question assist you in solving your problem in any way https://stackoverflow.com/questions/22588146/tracking-white-color-using-python-opencv – Knight Forked Dec 14 '20 at 14:02

1 Answers1

0

Use Canny Edges, Dilation and Erosion getting this output

enter image description here

imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img,20,40)

kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(edges,kernel,iterations = 1)
erosion = cv2.erode(dilation,kernel,iterations = 1)

ret,thresh = cv2.threshold(erosion, 200, 255, 0)

contours, hierarchy = cv2.findContours(thresh,  
    cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 

largest_areas = sorted(contours, key=cv2.contourArea)

cv2.drawContours(img, [largest_areas[-2]], -1, 255, 2)

cv2.imshow("image", img)
cv2.waitKey(0)
Alexander Riedel
  • 1,329
  • 1
  • 7
  • 14
  • 1
    Yeah I need it to be the largest contours. Your code returns largest_areas[-2] which means probably I have to hard code every time I switch Images – Minh Vũ Hoàng Dec 14 '20 at 10:22
  • please visualize all the steps using imshow/imwrite. Canny is rarely useful and frequently (with indiscriminate application) destroys more information than it adds. the `threshold` step does nothing. `>>> (thresh == erosion).all() # True` – Christoph Rackwitz Dec 14 '20 at 20:24