如何使用OpenCV检测简单的几何形状

时间:2012-07-11 00:44:16

标签: opencv

我有这个项目,我需要(在iOS上)检测图像中的简单几何形状。

enter image description here

在搜索互联网后,我得出结论,最好的工具是OpenCV。事情是,直到两个小时前,我不知道OpenCV是什么,我甚至从未做过任何涉及图像处理的事情。我的主要经验是JS / HTML,C#,SQL,Objective-C ......

我从哪里开始?

我发现这个answer我能够消化并且通过阅读其他东西,我知道OpenCV应该返回带有点/角的形状数组,这是真的吗?它还将如何代表一个圆圈或半圆圈? 还有形状方向呢?

您知道任何可以演示类似功能的Demo iOS项目吗?

3 个答案:

答案 0 :(得分:77)

如果您只有这些常规形状,则有一个简单的过程如下:

  1. 在图像中查找轮廓(图像应为问题中给出的二进制)
  2. 使用approxPolyDP函数近似每个轮廓。
  3. 首先,检查所有形状的近似轮廓中的元素数量。它是识别形状。例如,square将有4,五边形将有5.圈将有更多,我不知道,所以我们找到它。 (圈数为16,半圈为9)。
  4. 现在分配颜色,运行测试图像的代码,检查其编号,并用相应的颜色填充。
  5. 以下是我在Python中的示例:

    import numpy as np
    import cv2
    
    img = cv2.imread('shapes.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    ret,thresh = cv2.threshold(gray,127,255,1)
    
    contours,h = cv2.findContours(thresh,1,2)
    
    for cnt in contours:
        approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
        print len(approx)
        if len(approx)==5:
            print "pentagon"
            cv2.drawContours(img,[cnt],0,255,-1)
        elif len(approx)==3:
            print "triangle"
            cv2.drawContours(img,[cnt],0,(0,255,0),-1)
        elif len(approx)==4:
            print "square"
            cv2.drawContours(img,[cnt],0,(0,0,255),-1)
        elif len(approx) == 9:
            print "half-circle"
            cv2.drawContours(img,[cnt],0,(255,255,0),-1)
        elif len(approx) > 15:
            print "circle"
            cv2.drawContours(img,[cnt],0,(0,255,255),-1)
    
    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    以下是输出:

    enter image description here

    请记住,它仅适用于常规形状。

    要查找圈子,您可以使用houghcircles。您可以找到tutorial here

    关于iOS ,OpenCV开发者今年夏天正在开发一些iOS样本,请访问他们的网站:www.code.opencv.org并与他们联系。

    您可以在此处找到他们教程的幻灯片:http://code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf

答案 1 :(得分:21)

答案取决于是否存在其他形状,噪声水平(如果有)和您想要提供的不变性(例如旋转,缩放等)。这些要求不仅将定义算法,还将定义预处理阶段以提取特征。

上面提出的

Template matching在形状没有旋转或缩放以及周围没有类似形状时效果很好;换句话说,它在模板所在的图像中找到最佳翻译:

double minVal, maxVal;
Point minLoc, maxLoc;
Mat image, template, result; // template is your shape
matchTemplate(image, template, result, CV_TM_CCOEFF_NORMED);
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // maxLoc is answer

Geometric hashing是一种在旋转和缩放方面获得不变性的好方法;这种方法需要提取一些轮廓点。

Generalized Hough变换可以处理不变性,噪声并且具有最少的预处理,但实现起来比其他方法更难。 OpenCV对线条和圆圈进行了这样的转换。

在形状数量有限的情况下计算力矩或计算凸包顶点可能是最简单的解决方案:openCV structural analysis

答案 2 :(得分:3)

您还可以使用template matching检测图像内的形状。