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

Bal*_*alu 6 android opencv augmented-reality ios metaio

我想创建一个应用程序来检测对象的形状,如(圆形,方形和矩形的几何形状)不应该使用Marker less基于Edge的方式来检测增强中的形状.

我已经使用了以下内容,就像通过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)实时矩形可以是任何矩形对象 - > 在此输入图像描述

我怎样才能实现这种增强方案.

提前致谢

Ste*_*zyk 10

更新:这个StackOverflow帖子(包含一些很好的样本图片)似乎已经解决了圈子检测 -至少解决了你的问题.他指向的优秀文章的参考可以在这个维基页面上找到(不幸的是仅通过回传机).

如果新链接也不成立,则以下是相关部分:

检测图像:

有一些需要注意检测图像中的圆圈的小巧位.在使用cvHoughCircles- 圆检测功能处理图像之前,您可能希望先将其转换为灰色图像并使其平滑.以下是您需要使用的函数的一般过程及其用法示例.

创建图像

假设您有一个名为'img'的初始处理图像,首先要创建一个名为'gray'的图像变量,其尺寸与img相同cvCreateImage.

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 ...
Run Code Online (Sandbox Code Playgroud)

转换为灰色

现在您需要将其转换为灰色,使用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

e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab
Run Code Online (Sandbox Code Playgroud)

流畅的图像

这样做是为了防止检测到许多假圆圈.您可能需要使用最后两个参数,注意它们需要乘以奇数.

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);
Run Code Online (Sandbox Code Playgroud)

SRC

  • 源图像.

DST

  • 目标图片.

smoothtype

平滑的类型:

  • CV_BLUR_NO_SCALE(没有缩放的简单模糊) - 像素param1×param2邻域的总和.如果邻域大小不固定,可以使用cvIntegral函数.
  • CV_BLUR(简单模糊) - 在像素param1×param2邻域上求和,随后按1 /(param1•param2)缩放.
  • CV_GAUSSIAN(高斯模糊) - 用param1×param2高斯卷积图像.
  • CV_MEDIAN(中位数模糊) - 找到param1×param1邻域的中位数(即邻域是正方形).
  • CV_BILATERAL(双边滤波器) - 使用color sigma=param1和进行双边3x3滤波space sigma=param2

参数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 );
Run Code Online (Sandbox Code Playgroud)

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

该wiki页面的其余部分实际上非常好(虽然,我不会在这里重新复制它,因为其余部分与原始问题无关,而StackOverflow的答案大小有限).希望,Wayback机器上缓存副本的链接将继续无限期地工作.

我的更新之前的回答:

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

就个人而言,我发现自己解决问题比尝试理解如何使用现有(通常是非常成熟的)库更容易.这并不是说我自己的工作会比成熟的图书馆更好,它肯定不会.只是一旦我可以自己解决问题,那么我就更容易理解和使用一个库(库本身通常比我自己的解决方案运行得更快更智能).

因此,我将采取的下一步是将位图的颜色空间更改为灰度.一个颜色位图,我很难理解,我操作起来很麻烦,特别是因为有很多不同的方式可以表示,但是灰度位图,这更容易理解和操作.对于灰度位图,只需想象一个值网格,每个值代表不同的光强度.

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

而且就目前而言,我们不用担心您使用的工具或语言.只需使用最简单,最快捷的方法.例如,假设时间没有问题,几乎任何东西都可以编写脚本以自动将图像转换为灰度.ImageMagick,Gimp,Marvin,Processing,Python,Ruby,Java等.

对于任何这些工具,应该很容易将具有相似足够强度的像素分组(以使计算更易于管理),并为每个光强度桶对不同阵列中的每个像素坐标进行排序.换句话说,按照包含每个像素的x和y位置的强度排序某种粗略的阵列直方图应该不会太困难.

之后,问题变得更像这个问题(可以在StackOverflow上找到),因此可以使用其建议的解决方案.

一旦你能够以这种方式解决问题,那么将你提出的解决方案转换为适合任务的更好的语言应该不会太困难.并且理解和使用您最终为任务选择的任何现有库的基础功能也应该更容易.至少,这就是我所希望的,因为我不够熟悉,我无法真正帮助你自己使用OpenCV库.