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

Reg*_*ser 45 opencv

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

在此输入图像描述

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

我从哪里开始呢?

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

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

Abi*_*n K 78

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

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

下面是我在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()
Run Code Online (Sandbox Code Playgroud)

以下是输出:

在此输入图像描述

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

另外,您也可以使用houghcircles.你可以在这里找到一个教程.

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

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

  • +1 - 弗拉德,你的所有观点都是正确的.但是在这里,请看问题,他是新手,所以他需要一些东西才能开始,所以我的答案是非常基本的.这就是为什么我在第一句中明确提到"如果所有形状都是规则的".OP没有询问方形和矩形,所以我没有触及那部分.我喜欢"回答问题",而不是提供他没有提出的所有信息.让他自己找到并解决它.如果他不能,让他再来一次并具体询问. (4认同)
  • 这假设没有其他形状.检测通常意味着找到其他东西.所以,如果有一个矩形和正方形,你就不会区分它们.其次,即使有点噪音也会错误的顶点计数方法. (3认同)
  • 为了在Python 3中工作,需要将一个变量添加到第6行:img2,contours,h = cv2.findContours(thresh,1,2) (2认同)

Vla*_*lad 22

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

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

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

几何散列是一种在旋转和缩放方面获得不变性的好方法; 这种方法需要提取一些轮廓点.

广义Hough变换可以处理不变性,噪声并且具有最少的预处理,但是比其他方法更难实现.OpenCV具有线条和圆形的变换.

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