如何从图像中裁剪出最大的矩形 [英] How to crop biggest rectangle out of an image

查看:143
本文介绍了如何从图像中裁剪出最大的矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在桌子上有一些页面图像。我想从图像中裁剪页面。通常,页面将是图像中最大的矩形,但是,在某些情况下,矩形的所有四个边可能都不可见。

I have a few images of pages on a table. I would like to crop the pages out of the image. Generally, the page will be the biggest rectangle in the image, however, all four sides of the rectangle might not be visible in some cases.

我正在做以下但没有得到理想的结果:

I am doing the following but not getting desired results:

import cv2
import numpy as np

im = cv2.imread('images/img5.jpg')
gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,0)
_,contours,_ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Show",im)
cv2.imwrite("images/img5_rect.jpg", im)
cv2.waitKey(0)

下面是一些例子:

第一个例子:我可以在这个图像中找到矩形,但是,如果剩下的部分,我想木材也可以裁剪掉。

1st Example: I can find the rectangle in this image , however, would like if the remaining part of the wood can be cropped out as well.

2nd示例:未在此图像中找到矩形的正确尺寸。

2nd Example: Not finding the correct dimensions of the rectangle in this image.

第3名示例:无法在此图像中找到正确的尺寸。

3rd Example: Not able to find the correct dimensions in this image either.

第4个例子:同样如此。

4th Example: Same with this as well.

推荐答案

正如我之前所做的那样类似的东西,我经历过hough变换,但是对于我的情况来说,比使用轮廓要困难得多。我有以下建议可以帮助您入门:

As I have previously done something similar, I have experienced with hough transforms, but they were much harder to get right for my case than using contours. I have the following suggestions to help you get started:


  1. 一般来说,纸张(边缘,至少)是白色的,所以你可以转到像YUV这样的颜色空间更好运气,它可以更好地分离光度:

  1. Generally paper (edges, at least) is white, so you may have better luck by going to a colorspace like YUV which better separates luminosity:

image_yuv = cv2.cvtColor(image,cv2.COLOR_BGR2YUV)
image_y = np.zeros(image_yuv.shape[0:2],np.uint8)
image_y[:,:] = image_yuv[:,:,0]


  • 纸上的文字是个问题。使用模糊效果,(希望)消除这些高频噪音。您也可以使用扩张等形态学操作。

  • The text on the paper is a problem. Use a blurring effect, to (hopefully) remove these high frequency noises. You may also use morphological operations like dilation as well.

    image_blurred = cv2.GaussianBlur(image_y,(3,3),0)
    


  • 您可以尝试应用canny边缘检测器,而不是简单的阈值。不一定,但可以帮助你:

  • You may try to apply a canny edge-detector, rather than a simple threshold. Not necessarily, but may help you:

     edges = cv2.Canny(image_blurred,100,300,apertureSize = 3)
    


  • 然后找到轮廓。在我的情况下,我只使用极端外轮廓。您可以使用CHAIN_APPROX_SIMPLE标志压缩轮廓

  • Then find the contours. In my case I only used the extreme outer contours. You may use CHAIN_APPROX_SIMPLE flag to compress the contour

    contours,hierarchy = cv2.findContours(edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    


  • 现在你应该有一堆轮廓。是时候找到合适的人了。对于每个轮廓 cnt ,首先找到凸包,然后使用 approaxPolyDP 尽可能简化轮廓。 / p>

  • Now you should have a bunch of contours. Time to find the right ones. For each contour cnt, first find the convex hull, then use approaxPolyDP to simplify the contour as much as possible.

    hull = cv2.convexHull(cnt)
    simplified_cnt = cv2.approxPolyDP(hull,0.001*cv2.arcLength(hull,True),True)
    


  • 现在我们应该使用这个简化的轮廓找到封闭的四边形。您可以尝试一些您提出的规则。最简单的方法是选取轮廓的四个最长的段,然后通过交叉这四条线来创建包围的四边形。根据你的情况,你可以根据线条的对比度,它们的角度和类似的东西找到这些线条。

  • Now we should use this simplified contour to find the enclosing quadrilateral. You may experiment with lots of rules you come up with. The simplest method is picking the four longest longest segments of the contour, and then create the enclosing quadrilateral by intersecting these four lines. Based on your case, you can find these lines based on the contrast the line makes, the angle they make and similar things.

    现在你有一堆四边形。您现在可以执行两步法查找所需的四边形。首先,删除可能错误的那些。例如,四边形的一个角度超过175度。然后你可以选择面积最大的那个作为最终结果。你可以看到橙色轮廓是我此时得到的结果之一:

    Now you have a bunch of quadrilaterals. You can now perform a two step method to find your required quadrilateral. First you remove those ones that are probably wrong. For example one angle of the quadrilateral is more than 175 degrees. Then you can pick the one with the biggest area as the final result. You can see the orange contour as one of the results I got at this point:

    找到后的最后一步(希望如此) )右四边形,正在转变为一个矩形。为此,您可以使用 findHomography 来提供转换矩阵。

    The final step after finding (hopefully) the right quadrilateral, is transforming back to a rectangle. For this you can use findHomography to come up with a transformation matrix.

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

    这种翘曲会产生类似于以下(来自我之前的结果):

    This warping should result in something like the following (from my results before):

    我希望这可以帮助你找到一个在你的情况下适当的方法。

    I hope this helps you to find an appropriate approach in your case.

    这篇关于如何从图像中裁剪出最大的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆