slykat
slykat

Reputation: 867

Square detection with aberrations in edges and 1 missing corner

This is a follow up to couple of similar questions regarding square detection in which karlphillip, mevatron, and abid-rahman-k came up with some cool approaches.

I am trying to design a robust square detection algorithm to help isolate a picture of a receipt from the rest of the image. My code is built off the convex hull approach from the previous questions but it's choking on an image where one of the points isn't in the image and the edges of the receipt have aberrations due to a pen holder on the left side.

How can I detect the corners on this receipt?

Here is the image:

image of receipt

Here is my code:

import cv2
import numpy as np

img = cv2.imread('taco.jpg')
img = cv2.resize(img,(1944,2592))
img = cv2.medianBlur(img,31)
img = cv2.GaussianBlur(img,(0,0),3)

grayscale = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
thresh = cv2.Canny(grayscale, 10, 20)
thresh = cv2.dilate(thresh,None)

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

for cnt in contours:
    if cv2.contourArea(cnt)>250:  # remove small areas like noise etc
        hull = cv2.convexHull(cnt)    # find the convex hull of contour
        hull = cv2.approxPolyDP(hull,0.1*cv2.arcLength(hull,True),True)
        if len(hull)==4:
            cv2.drawContours(img,[hull],0,(0,255,0),2)

cv2.namedWindow('output',cv2.cv.CV_WINDOW_NORMAL)
cv2.imshow('output',img)
cv2.cv.ResizeWindow('output',960,640)
cv2.waitKey()
cv2.destroyAllWindows()

Any ideas?

Upvotes: 3

Views: 2102

Answers (1)

Dr. belisarius
Dr. belisarius

Reputation: 61016

A solution in Mathematica:

Import your image:

i = Import@"http://i.imgur.com/RrYKJ.jpg";

Detect edges in a scale grater than the letters in the receipt (a parameter)

i1 = EdgeDetect[i, 10]

Mathematica graphics

Delete lines smaller than the scale of the perimeter of the receipt (a parameter)

i2 = DeleteSmallComponents[i1, 1000]

Mathematica graphics

Find the morphological components

(mc = MorphologicalComponents[Erosion[ColorNegate@i2, 1]]) // Colorize

Mathematica graphics

Find the morph component with more border adjacency (to delete it from the mask)

com = Commonest[Join[mc[[1]], mc[[-1]], Transpose[mc][[1]], Transpose[mc][[-1]]]]

Form the mask

mc1 = Unitize[mc /. com[[1]] -> 0];

Mathematica graphics

Multiply the mask by your original image

ImageMultiply[Image@mc1, i]

Mathematica graphics

Upvotes: 3

Related Questions