如何使用OpenCV检测简单的几何形状
我有这个项目,我需要(在iOS)来检测图像内的简单几何形状。
在search互联网后,我已经得出结论,最好的工具是OpenCV。 事情是,直到两个小时前,我不知道什么OpenCV是什么,我甚至从来没有远程做任何涉及image processing。 我的主要经验是JS / HTML,C#,SQL,Objective-C …
我从哪里开始呢?
我发现这个答案是我能够消化的,通过阅读其他的东西,我明白,OpenCV应该返回一个形状的点/angular的数组,这是真的吗? 另外它将如何表示一个圆圈或一个半圈? 那么形状的方向呢?
你知道任何演示iOS项目,可以展示类似的function?
如果你只有这些规则的形状,有一个简单的过程如下:
- 在图像中查找轮廓(图像应该是你的问题给出的二进制)
- 使用
approxPolyDP
函数近似每个轮廓。 - 首先,检查所有形状的近似轮廓中的元素的数量。 它是识别形状。 例如,广场将有4个,五angular形将有5个。圈子将有更多,我不知道,所以我们find它。 (我得到了16圈和半圈9。)
- 现在分配颜色,运行testing图像的代码,检查其编号,填充相应的颜色。
下面是我在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()
以下是输出:
请记住,它只适用于常规形状。
或者查找圈子,您可以使用houghcircles
。 你可以在这里find一个教程 。
关于iOS ,OpenCV开发者今年夏天正在开发一些iOS样本,请访问他们的网站:www.code.opencv.org并联系他们。
你可以在这里find他们教程的幻灯片: http : //code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf
答案取决于其他形状的存在,噪声水平(如果有的话)和你想提供的不变性(例如旋转,缩放等)。 这些要求将不仅定义algorithm,而且还需要预处理阶段来提取特征。
上面提出的模板匹配在形状不旋转或缩放时以及周围没有相似的形状时效果很好; 换句话说,它会在模板所在的图像中find最好的翻译:
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
几何哈希是一个很好的方法来获得旋转和缩放的不变性; 这种方法将需要提取一些轮廓点。
广义霍夫变换可以处理不变性,噪声,并且将具有最小的预处理,但是比其他方法实施起来要困难一些。 OpenCV对线条和圆圈进行了这种转换。
在形状数量有限的情况下,计算矩或计算凸包顶点可能是最简单的解决scheme: openCV结构分析
您还可以使用模板匹配来检测图像内的形状。