Reputation: 867
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:
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
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]
Delete lines smaller than the scale of the perimeter of the receipt (a parameter)
i2 = DeleteSmallComponents[i1, 1000]
Find the morphological components
(mc = MorphologicalComponents[Erosion[ColorNegate@i2, 1]]) // Colorize
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];
Multiply the mask by your original image
ImageMultiply[Image@mc1, i]
Upvotes: 3