形状检测 - 使用OpenCV进行轮廓近似

inf*_*rno 15 c++ opencv image-processing

我正在为形状检测编写小应用程序.我首先需要做的是找到图像上最重要的形状.我从一些预处理开始,包括将图像转换为灰度,阈值和边缘检测.这些操作之前和之后的图像如下所示

之前

在此输入图像描述

在此输入图像描述

因此,您可以看到主要形状是可见的(但它有点散乱),还有一些噪音(小树等).我需要做的是以某种方式提取最重要的形状(最大的形状) - 在这种情况下它是一个塔.我想要做的是在opencv中使用轮廓查找功能,然后以某种方式使用多边形找到conturs.然后我会(不知何故)计算countours的面积并选择最大的面积.到目前为止,我只能(仅)使用找到轮廓

cvFindContours(crated,g_storage,&contours);
Run Code Online (Sandbox Code Playgroud)

我知道有一个

cvApproxPoly
Run Code Online (Sandbox Code Playgroud)

函数,但是我无法获得有关此函数结果的任何有用信息.有人可以告诉我是否可以计算轮廓的面积或用多边形逼近轮廓.也许你有更好的想法如何只提取最重要的形状?

dam*_*ian 8

您不必在此处进行边缘检测.只是二进制图像的阈值,然后找到blob(cvFindContours).您可以在每个返回的CvSeq上使用cvContourArea来查找其区域.


Moa*_*nti 7

如果你总是有一个受控的背景,我会采取这些步骤(由@damian建议):

  1. 二值化,即创建诸如background = 0和对象区域= 1(或255)的图像.之后,您的图像上会有几个白色区域.有几种方法可以执行此操作,但如果您的背景被控制,则可以使用固定阈值.请注意,此处您已删除对象内部的噪音.在二进制图像中,您始终可以使用形态学打开/关闭以平滑对象
  2. 使用cvFindContours查找所有对象:它现在应该更容易.
  3. 使用cvFloodFill用背景颜色填充较小的轮廓.


Pio*_*zmo 5

你的主要问题是塔的轮廓是分散的.从那些小碎片中重建整个轮廓将很困难.优化边缘检测阶段(尝试cvAdaptiveThreshold),或使用不同的方法(可能像对象分割)

将轮廓合成为一体后,可以检查其区域如下:

CvSeq* convex_hull=cvConvexHull2( contour, storage, CV_CLOCKWISE, 2 );
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
float size=fabs(cvContourArea( quad,CV_WHOLE_SEQ,0 ));
Run Code Online (Sandbox Code Playgroud)

您需要调整参数.它用于检测矩形.