正如我以前做过的类似事情一样,我经历了霍夫变换,但要比使用轮廓更难于适合我的情况。我有以下建议可帮助您入门:
通常,纸张(至少边缘)是白色的,因此,您可以通过进入YUV之类的颜色空间更好地分离光度来获得更好的运气:
image_yuv = cv2.cvtColor(image,cv2.COLOR_BGR2YUV) image_y = np.zeros(image_yuv.shape[0:2],np.uint8) image_y[:,:] = image_yuv[:,:,0]
纸上的文字有问题。使用模糊效果,以(希望)消除这些高频噪声。您也可以使用形态运算,例如膨胀。
image_blurred = cv2.GaussianBlur(image_y,(3,3),0)
您可以尝试应用精巧的边缘检测器,而不是简单的阈值。不一定,但可以帮助您:
edges = cv2.Canny(image_blurred,100,300,apertureSize = 3)
然后找到轮廓。就我而言,我只使用了极端的外部轮廓。您可以使用CHAIN_APPROX_SIMPLE标志来压缩轮廓
contours,hierarchy = cv2.findContours(edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
现在您应该有一堆轮廓。是时候找到合适的了。对于每个轮廓
cnt
,首先找到凸包,然后使用approaxPolyDP
尽可能简化轮廓。hull = cv2.convexHull(cnt) simplified_cnt = cv2.approxPolyDP(hull,0.001*cv2.arcLength(hull,True),True)
现在,我们应该使用这个简化的轮廓来找到封闭的四边形。您可能会尝试很多规则。最简单的方法是选取轮廓的四个最长最长的线段,然后通过将这四条线相交来创建封闭的四边形。根据您的情况,您可以根据线条的对比度,它们形成的角度以及类似的东西找到这些线条。
现在您有一堆四边形。现在,您可以执行两步方法来找到所需的四边形。首先,您删除那些可能是错误的。例如,四边形的一个角度大于175度。然后,您可以选择面积最大的一个作为最终结果。您可以看到橙色轮廓是我此时得到的结果之一:
找到(希望)右四边形之后的最后一步是变回矩形。为此,您可以使用
findHomography
提出转换矩阵。(H,mask) = cv2.findHomography(cnt.astype('single'),np.array([[[0., 0.]],[[2150., 0.]],[[2150., 2800.]],[[0.,2800.]]],dtype=np.single))
数字假定投射到信纸上。您可能会想出更好更好的数字来使用。您还需要重新排列轮廓点以匹配信纸的坐标顺序。然后调用
warpPerspective
创建最终图像:final_image = cv2.warpPerspective(image,H,(2150, 2800))
这种扭曲应导致如下所示(根据我之前的结果):
我希望这可以帮助您找到适合您情况的方法。
0
我在桌子上有几页纸的图像。我想从图像中裁剪页面。通常,页面将是图像中最大的矩形,但是,在某些情况下,矩形的所有四个边可能都不可见。
我正在执行以下操作,但未获得期望的结果:
以下是一些示例:
第一个示例 :我可以在此图像中找到矩形,但是,如果也可以裁剪出木材的其余部分,我想。
第二个示例 :在此图像中找不到矩形的正确尺寸。
第三个示例 :在此图像中也找不到正确的尺寸。
第四例 :与此相同。