【问题标题】:How to detect simple geometric shapes using OpenCV如何使用 OpenCV 检测简单的几何形状
【发布时间】:2012-07-10 13:26:58
【问题描述】:

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

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

我从哪里开始?

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

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

【问题讨论】:

  • 你只有这几种规则形状吗?或任何其他不规则形状?

标签: opencv


【解决方案1】:

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

  1. 在图像中查找轮廓(图像应该是您问题中给出的二进制)
  2. 使用approxPolyDP 函数逼近每个轮廓。
  3. 首先,检查所有形状的近似轮廓中的元素数量。就是认形状。例如,正方形有 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()

下面是输出:

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

您也可以使用houghcircles 来查找圈子。你可以找到tutorial here

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

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

【讨论】:

  • 感谢您的回答,再澄清一件事。如何检测形状方向?
  • 形状方向是什么意思。一个例子?
  • 这假定没有其他形状。检测通常意味着在其他事情中找到一些东西。因此,如果存在矩形和正方形,您将不会区分它们。其次,即使是一点点噪音也会使顶点计数的方法出错。
  • +1 - 弗拉德,你所有的观点都是正确的。但是在这里,请看问题,他是新手,所以他需要一些东西来入门,所以我的回答是非常基本的水平。这就是为什么我在第一句话中明确提到“如果所有形状都是规则的”。 OP没有询问正方形和矩形,所以我没有触及那部分。我喜欢“回答问题”,而不是提供他没有问的所有信息。让他自己找到并解决。如果他不能,让他再过来问清楚。
  • 为了在 Python 3 中工作,需要在第 6 行添加一个变量:img2,contours,h = cv2.findContours(thresh,1,2)
【解决方案2】:

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

【讨论】:

  • 只有在您确切知道自己的形状会是什么样子的情况下。如果您有不同大小的正方形,例如。你放大/缩小我认为这种方法效果不佳。
  • 这个链接只回答不合适。
【解决方案3】:

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

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 transform 可以处理不变性、噪声并且具有最少的预处理,但它比其他方法更难实现。 OpenCV 对线和圆有这样的变换。

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

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    相关资源
    最近更新 更多