简体   繁体   English

在opencv-python中检测星形

[英]Detect star shape in opencv-python

I need to detect the shapes and count the occurence of each shape in the image.I initially detected the contours and approximated them ,and counted the vertices in each of the contour present.My code looks like this: 我需要检测形状并计算图像中每个形状的出现。我最初检测到轮廓并对它们进行近似,并计算每个轮廓中的顶点。我的代码如下所示:

import cv2
import numpy as np 
import collections
import sys

img = cv2.imread(str(sys.argv[1]),0)
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh,1,2)


no_of_vertices = []

i = 0
mask = np.zeros(img.shape,np.uint8)
for contour in contours:

 cnt = contour
 area = cv2.contourArea(cnt)
 if area>150:
    epsilon = 0.02*cv2.arcLength(cnt,True)
    approx = cv2.approxPolyDP(cnt,epsilon,True)
    no_of_vertices.append(len(approx))



counter = collections.Counter(no_of_vertices)




 a,b = counter.keys(),counter.values()

 i=0
 while i<len(counter):
   print a[i],b[i]
   i = i + 1

My code doesnt work for detecting the stars in this image: 我的代码无法检测此图像中的星星:

图像与星星和其他基本形状

What changes should I make in the code? 我应该在代码中做出哪些更改?

What worked for me was a comparison between the square root of the area over the perimeter of the shape. 对我有用的是比较形状周边区域的平方根。 It's about 0.145 for a star (+/- .0015 because some of the edges didn't come out perfectly). 一颗恒星约为0.145(+/- .0015,因为有些边缘没有完美出现)。 0.255 for the hexagon, .21 for the triangles, .247 for the square, and .250 for the pentagon. 六边形为0.255,三角形为.21,正方形为.247,五边形为.250。

Circularity also does work (which has the triangles come in at 0.26 to .27), and it differentiates similarly (.83 for the hexagon, .55-.56 for the triangle, .77 for the square, and .78 for the pentagon) 圆度也起作用(三角形在0.26到.27之间),并且它的区别相似(六边形为.83,三角形为.55-.56,正方形为.77,五边形为.78) )

Below is the C++ code for it (I don't have python on my PC here, but the idea's the same): 下面是它的C ++代码(我的PC上没有python,但想法是一样的):

#include "stdafx.h"
#include <opencv/cxcore.h>
#include <opencv2\core\mat.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv/cxcore.h>
#include <opencv/highgui.h>
#include <opencv/cv.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>

using namespace cv;
using namespace std;

RNG rngee(12345);

int main() {
    Mat im = imread("C:/this/is.a/path/image.png", CV_LOAD_IMAGE_COLOR);
    Mat imgrey = im.clone();
    cvtColor(im, imgrey, CV_RGB2GRAY);
    vector<vector<Point> > imContours;
    vector<Vec4i> hierarchy;

    double divMaxSize = 0.175, divMinSize = 0.125;

   namedWindow("Image", CV_WINDOW_NORMAL| CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED);

   threshold(imgrey, imgrey, 100, 255, 0);

   findContours(imgrey, imContours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

    for (int i=0; i < imContours.size(); i++) {
         Scalar color = Scalar( rngee.uniform(0, 255), rngee.uniform(0,255), rngee.uniform(0,255) );
         cout << "sqrt(Area)/arcLength = " << sqrt(contourArea(imContours[i]))/arcLength(imContours[i], true ) << endl;
         if(sqrt(contourArea(imContours[i]))/arcLength(imContours[i], true ) < divMaxSize && sqrt(contourArea(imContours[i]))/arcLength( imContours[i], true ) > divMinSize) 
         {
             drawContours(im, imContours, i, color, 2, 8, hierarchy, 0, Point() ); 
             cout << "I'm a star!" << endl;
         }
        imshow("Image", im);
        waitKey(0);
    }
    imshow("Image", im);
    waitKey(0);

}

Both ways - either using circularity or my sqrt(area)/arclength method - result in: 两种方式 - 使用圆形或我的sqrt(区域)/ arclength方法 - 导致: 图像与明星突出显示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM