边缘畸变和1个缺失角落的正方形检测

3
这是关于方形检测的跟进,涉及类似 问题,其中karlphillipmevatronabid-rahman-k提出了一些很酷的方法。
我正在尝试设计一个强大的方形检测算法,以帮助从图像的其余部分中隔离出收据图片。我的代码基于先前问题中的凸包方法,但在一张图片上卡住了,因为其中一个点不在图像中,并且由于左侧的笔筒,收据的边缘有异常。
如何检测这张收据的角落?
以下是该图片:

image of receipt

这是我的代码:

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()

有什么想法吗?

1个回答

3
一个在Mathematica中的解决方案:
导入你的图片:
i = Import@"http://i.imgur.com/RrYKJ.jpg";

检测边缘时,比收据上的字母更大的规模(一个参数)。
i1 = EdgeDetect[i, 10]

Mathematica 图形

删除比收据周长小的线条(一个参数)

i2 = DeleteSmallComponents[i1, 1000]

Mathematica图形

查找形态组件

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

Mathematica图形

找到具有更多边缘邻接性的变形组件(以将其从掩模中删除)

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

生成掩码

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

Mathematica graphics

将掩模与原始图片相乘

ImageMultiply[Image@mc1, i]

Mathematica graphics


这看起来很不错,尽管我买不起Mathematica许可证。然而,我不知道如何在Python和OpenCV中模仿第一步骤。你知道背后的算法吗: i1 = EdgeDetect[i, 10]具体来说,我想知道如何在10的比例尺下进行边缘检测的算法。也许我可以将我的图像缩小或者以10的级别进行模糊处理,以获得类似的边缘检测? - slykat
Canny 在这里应该能很好地工作。Verde 的配方中缺少的一步是对对象边界的建模 - 您可能希望对它们进行强健的拟合,以估计四个角并消除透视畸变。 - Francesco Callari
@Franco 过去的问题指向了这个方向。 OP需要问这个问题,因为过去的答案是基于四边形的。我尽可能保持对几何图形的中立态度。你真的不知道角落的数量(我的图像中有5个)。一旦你映射了票的边界,透视畸变就很容易消除。 - Dr. belisarius
@FrancoCallari 没关系,但请注意,如果照片拍摄不慎,收据的某些边框被遗漏(就像这里部分发生的情况),匹配算法将会失败。 - Dr. belisarius
是的,Verde是正确的 - 很多问题可能会破坏像矩形匹配这样的方法。具体来说,一个角可能会丢失,收据可能会卷曲,有阴影等等。因此,我一直在努力寻找一个强大的算法。尝试了霍夫变换和凸包方法,但两者都存在问题。@Verde - 我主要遇到的问题是实现i1 = EdgeDetect[i, 10]。它似乎已经很好地去除了噪声和文本中的几乎所有边缘 - 这是我在opencv和python中做不到的。这只是一个具有大光圈的Canny边缘检测器吗?有什么想法吗? - slykat
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接