从相机中dynamic检测不同形状(圆形,方形和矩形)?

我想创build一个应用程序来检测对象的形状(圆形,正方形和矩形只有几何形状),不应该使用标记较less基于边缘的方式来检测扩增中的形状。

我已经使用了以下的东西,像通过metaio sdk中已经存在的教程的过程

1)Metaio: http ://dev.metaio.com/sdk/tutorials/hello-world/

2)OpenCV: http : //docs.opencv.org/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html#canny-detector

这些是我试图实现的东西。

几何形状:1)实时圈可以是任何圆形物体 – > 在这里输入图像说明

2)实时广场可以是任何方形物体 – > 在这里输入图像说明

3)实时矩形可以是任何矩形对象 – > 在这里输入图像说明

我怎样才能实现这种增强的情况。

提前致谢

更新:这个StackOverflow后(包括一些很好的示例图片)似乎已经解决了至less你的问题的部分圆检测 – 部分。 他指出的优秀写作的参考可以在这个维基页面上find(不幸的是,只能通过backback机器)。

如果新的链接也没有,下面是相关部分:

检测图像:

有几个需要注意的位来检测图像中的圆圈。 在使用cvHoughCircles处理图像之前,您可以先将其转换为灰色图像,然后对其进行平滑处理。 以下是您需要使用的function的一般过程。

创build图像

假设你有一个名为'img'的处理的初始图像,首先你需要使用cvCreateImage创build一个名为'gray'的图像variables,其尺寸与img相同。

 IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 ); // allocate a 1 channel byte image CvMemStorage* storage = cvCreateMemStorage(0); IplImage* cvCreateImage(CvSize size, int depth, int channels); size: cvSize(width,height); depth: pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F channels: Number of channels per pixel. Can be 1, 2, 3 or 4. The channels are interleaved. The usual data layout of a color image is b0 g0 r0 b1 g1 r1 ... 

转换成灰色

现在,您需要使用cvCvtColor将其转换为灰色,在颜色空间之间进行转换。

 cvCvtColor( img, gray, CV_BGR2GRAY ); cvCvtColor(src,dst,code); // src -> dst code = CV_<X>2<Y> <X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS eg: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab 

平滑的图像

这样做是为了防止检测到大量假圆圈。 你可能需要玩弄最后两个参数,注意他们需要乘以一个奇数。

 cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 ); // smooth it, otherwise a lot of false circles may be detected void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1, int param2); 

SRC

  • 源图像。

DST

  • 目标图像。

smoothtype

平滑的types:

  • CV_BLUR_NO_SCALE(不缩放的简单模糊) – 对像素param1×param2邻域进行求和。 如果邻域大小不固定,可以使用cvIntegral函数。
  • CV_BLUR(简单模糊) – 通过像素param1×param2邻域求和,随后按1 /(param1•param2)进行缩放。
  • CV_GAUSSIAN(高斯模糊) – 用param1×param2高斯卷积图像。
  • CV_MEDIAN(中值模糊) – findparam1×param1邻域(即邻域为正方形)的中位数。
  • CV_BILATERAL(双边滤波器) – 使用color sigma=param1space sigma=param2应用双边3×3滤波

参数1

  • 平滑操作的第一个参数。

参数2

  • 平滑操作的第二个参数。

param2为零的情况下,简单缩放/非缩放和高斯模糊,将其设置为param1

使用Hough Circle检测

函数cvHoughCircles用于检测灰色图像上的圆圈。 再次,最后两个参数可能需要摆弄。

 CvSeq* circles = cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/4, 200, 100 ); CvSeq* cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1=100, double param2=100, int min_radius=0, int max_radius=0 ); 

=======相关部分结束=========

该wiki页面的其余部分实际上是非常好的(虽然,我不打算在这里重复它,因为其余的是与原来的问题脱节,并且StackOverflow具有对答案的大小限制)。 希望链接到Wayback机器上的caching副本将继续无限期地工作。

以前的答案在我更新之前:

大! 现在您已经发布了一些示例,我可以看到,您不仅在矩形,方形矩形和圆形之后,还希望在3D环境中查找这些形状,因此可能会寻找平行四边形椭圆形的特殊情况帧到video帧可以最终显示自己是矩形,正方形和/或圆圈(取决于你如何平移相机)。

就我个人而言,我觉得比试图了解如何使用现有的(通常是非常成熟的)库更容易解决问题。 这并不是说我自己的工作会比成熟的图书馆好,但肯定不会。 只是一旦我可以自己解决问题,那么我就会更容易理解和使用一个图书馆(图书馆本身往往比我自己的解决scheme更快,更聪明)。

所以下一步我要把位图的颜色空间改成灰度。 一个彩色位图,我很难理解和操作,特别是因为有很多不同的方式可以表示,但灰度位图,这是更容易理解和操纵。 对于灰度位图,只需设想一个值的网格,每个值代表不同的光强度。

现在,让我们将问题的范围限制在静态2D环境中寻找平行四边形和椭圆(我们将担心稍后处理3D环境和移动video帧,或者我应该说,自己会担心这个部分那个问题对我来说已经变得太复杂了)。

而且现在也让我们不用担心你使用的是什么工具或者语言。 只要使用最简单和最便捷的方法。 例如,假设时间不成问题,几乎任何事情都可以通过脚本自动将图像转换为灰度。 ImageMagick,Gimp, Marvin , Processing ,Python,Ruby,Java等

使用这些工具中的任何一种,应该很容易地将具有相似强度的像素(使得计算更易于pipe理)分组,并且针对每个光强度桶将每个像素坐标sorting在不同的arrays中。 换句话说,按照包含每个像素的x和y位置的强度来排列一些粗糙的数组直方图不应该太困难。

之后,问题就变成了一个更像这个问题的问题(可以在StackOverflow上find),因此可以使用其build议的解决scheme。

一旦你能够以这种方式解决问题,那么把你提出的解决scheme转换成更适合这个任务的更好的语言应该不是太难。 理解和使用你最终select的任何现有库的底层function也应该容易得多。 至less,这就是我所希望的,因为我不够熟悉,而且我也无法真正帮助OpenCV库。