0

我正在开发一个程序,我应该检测相同类型的形状,并用不同的颜色为每种类型着色。

我正在使用cv2.findCountours然后cv2.approxPolyDP检测每个形状。

该程序检测任何具有 8 条边的形状为圆形,因此我决定添加一些检查 - 我正在使用 检查当前轮廓的区域cv2.contourArea,并且我也在检查cv2.minEnclosingCircle(cnt)当前轮廓的区域。

如果它们相等,我们就有一个圆圈。

import numpy as np
import cv2

img = cv2.imread('1.jpg')
gray = cv2.imread('1.jpg',0)

ret,thresh = cv2.threshold(gray,127,255,1)

contours,h = cv2.findContours(thresh,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)

for cnt in contours:
    approx = cv2.approxPolyDP(cnt, .03 * cv2.arcLength(cnt, True), True)
    print len(approx)
    if len(approx)==3:
        print "triangle"
        cv2.drawContours(img,[cnt],0,(122,212,78),-1)
    elif len(approx)==4:
        print "square"
        cv2.drawContours(img,[cnt],0,(94,234,255),-1)
    elif len(approx)==8:
        area = cv2.contourArea(cnt)
        (cx, cy), radius = cv2.minEnclosingCircle(cnt)
        circleArea = radius * radius * np.pi
        print circleArea
        print area
        if circleArea == area:
            cv2.drawContours(img, [cnt], 0, (220, 152, 91), -1)


cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

我打印了每个区域,发现结果是不同的——即使形状明显是圆形。

例如,对于相同的形状,minEnclosureCircle 区域为 628.254637106,contourArea 为 569。另一个示例:minEnclosureCircle 区域为 2220.55512328,contourArea 为 2032.0。

我怎样才能正确计算这个面积?

我将不胜感激任何帮助!

我使用的图像:

和检测到的形状:

4

3 回答 3

3

我认为使用 Hu 矩使用检测圆圈会更好:

https://en.wikipedia.org/wiki/Image_moment

它们可以用opencv计算:

http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html

Circle 有一组定义明确的时刻:

https://users.cs.cf.ac.uk/Paul.Rosin/resources/papers/Hu-circularity-PR-postprint.pdf(第4页)

以这种方式定义的圆度可用于识别圆。

编辑: python 中的 Hu Moments 教程:

https://www.pyimagesearch.com/2014/10/27/opencv-shape-descriptor-hu-moments-example/

http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html

关于stackoverflow的类似问题:

在 Python 中使用来自 OpenCV 的 Hu 矩进行形状识别

于 2017-10-09T07:57:15.813 回答
1

而不是比较区域,您应该检查计数器的凸度

elif len(approx)==8:
        k=cv2.isContourConvex(approx)
        if k:
        #now you select a circle
于 2017-10-09T08:07:57.073 回答
0

您可以尝试使用属于每个 blob 的一些属性。偏心,坚固,紧凑......等特征可以帮助您区分形状。

您可以在下面的链接中找到一些信息(但在 C++ 中)给您一些提示

https://github.com/mribrahim/Blob-Detection

于 2017-10-09T09:08:21.130 回答