OpenCV:是否可以从角落检测矩形? [英] OpenCV: Is it possible to detect rectangle from corners?

查看:86
本文介绍了OpenCV:是否可以从角落检测矩形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张照片,一个人拿着一张纸.我想检测那张纸的矩形.

I have a photo where a person holds a sheet of paper. I'd like to detect the rectangle of that sheet of paper.

我尝试按照OpenCV提供的不同教程以及各种SO答案和用于检测正方形/矩形的示例代码进行操作,但是问题是它们都依赖于某种轮廓.

I have tried following different tutorials from OpenCV and various SO answers and sample code for detecting squares / rectangles, but the problem is that they all rely on contours of some kind.

如果遵循squares.cpp的示例,则从轮廓获得以下结果:

If I follow the squares.cpp example, I get the following results from contours:

如您所见,手指是轮廓的一部分,因此算法无法找到正方形.

As you can see, the fingers are part of the contour, so the algorithm does not find the square.

我也尝试使用HoughLines()方法,但得到的结果与上述类似:

I, also, tried using HoughLines() approach, but I get similar results to above:

我可以可靠地检测到拐角处

I can detect the corners, reliably though:

图像中还有其他拐角,但我将发现的总拐角限制为<找到总是 50个纸页的角.

There are other corners in the image, but I'm limiting total corners found to < 50 and the corners for the sheet of paper are always found.

是否存在用于从图像的多个角中查找矩形的算法?我似乎找不到现有的方法.

Is there some algorithm for finding a rectangle from multiple corners in an image? I can't seem to find an existing approach.

推荐答案

您可以应用形态过滤器来缩小边缘图像中的间隙.然后,如果找到轮廓,则可以检测到内部闭合轮廓,如下所示.然后找到该轮廓的凸包以获取矩形.

You can apply a morphological filter to close the gaps in your edge image. Then if you find the contours, you can detect an inner closed contour as shown below. Then find the convexhull of this contour to get the rectangle.

封闭边缘:

轮廓:

凸包:

在下面的代码中,我只使用了任意大小的核用于形态过滤器,并使用面积比阈值过滤掉了感兴趣的轮廓.您可以使用自己的条件代替这些条件.

In the code below I've just used an arbitrary kernel size for morphological filter and filtered out the contour of interest using an area ratio threshold. You can use your own criteria instead of those.

代码

Mat im = imread("Sh1Vp.png", 0); // the edge image
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(11, 11));
Mat morph;
morphologyEx(im, morph, CV_MOP_CLOSE, kernel);

int rectIdx = 0;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(morph, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for (size_t idx = 0; idx < contours.size(); idx++)
{
    RotatedRect rect = minAreaRect(contours[idx]);
    double areaRatio = abs(contourArea(contours[idx])) / (rect.size.width * rect.size.height);
    if (areaRatio > .95)
    {
        rectIdx = idx;
        break;
    }
}
// get the convexhull of the contour
vector<Point> hull;
convexHull(contours[rectIdx], hull, false, true);

// visualization
Mat rgb;
cvtColor(im, rgb, CV_GRAY2BGR);
drawContours(rgb, contours, rectIdx, Scalar(0, 0, 255), 2);
for(size_t i = 0; i < hull.size(); i++)
{
    line(rgb, hull[i], hull[(i + 1)%hull.size()], Scalar(0, 255, 0), 2);
}

这篇关于OpenCV:是否可以从角落检测矩形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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