Detecting right-angle corners of a rectangle in a complex image?

asked 2018-05-15 18:10:57 -0500

Richard123 gravatar image

updated 2018-05-17 08:05:18 -0500

I have some images of old scanned maps. The scans have "dead space" around them and also have a border around the map which is unnecessary and unhelpful for tiling the map. I'd like to automatically identify this border and crop it.

The border is of varying size, so this can't just be done with a standard imagemagick crop. I need to detect the corners of the scanned map.

This is the original image:

enter image description here

And this is what I'd like to end up with:

enter image description here

I've tried running canny edge detection on the original image, which simplifies nicely:

enter image description here

But I'm struggling with the next step - identifying the pixel positions of the four corners. It feels as though it should be easy - but maybe it's one of the things that is easy for humans but not for machines?

I've tried Hough line detection - this was very slow across the whole image, so I tried cropping the four relevant areas on the image and just running it on those.

The problem is that sometimes there are corners that are deceptive, e.g. here:

image description

I also tried corner detection, but again, it finds all kinds of things that aren't right angle corners.

Any ideas for how I can find the four right angle corners that make up the image that I need? They're always in approximately the same areas of the image, if that helps.

Any ideas?

UPDATE: Thanks, I tried as per the suggestion. Unfortunately I'm having trouble with the Hough line detection. Here's my original:

image description

Here are the canny edges:

image description

And here are the Hough lines:

image description

Unfortunately I can't start on the vertical/horizontal line detection because the line detection isn't good enough. It looks as though the line detection stops whenever it gets to a corner. Is there a way I can force it to continue through corners?

Also, I'm having problems setting the minimum line length: my parameter doesn't do anything.

This is my code:

gray = cv2.cvtColor(corner_img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
cv2.imwrite('cropped_sw_corner-canny.png', edges)
minLineLength = 10 # Changing this to 100 does nothing.
maxLineGap = 1
threshold = 100
lines = cv2.HoughLinesP(edges,1,np.pi/180,threshold,minLineLength,maxLineGap)
for l in lines:
    for x1,y1,x2,y2 in l:
        cv2.line(corner_img,(x1,y1),(x2,y2),(0,0,255), 2)
cv2.imwrite('houghlines.jpg', corner_img)
edit retag flag offensive close merge delete


Here's what I would try, crop a larger area. Run hough line. Make two lists of horizontal lines and vertical lines by using the delta in x1 and x2 and y1 and y2. Now find the biggest horizontal and biggest vertical line that intersect (you may have to extend the lines a bit using slope).

dpizzle gravatar imagedpizzle ( 2018-05-16 12:18:29 -0500 )edit

Thank you! I've updated the question - I'm having a few problems with the Hough Line detection, unfortunately.

Richard123 gravatar imageRichard123 ( 2018-05-17 08:06:20 -0500 )edit

Maybe try dialating before houghlines?

dpizzle gravatar imagedpizzle ( 2018-05-17 10:58:20 -0500 )edit