python - 在opencv-python中检测星形

标签 python opencv image-processing computer-vision

我需要检测形状并计算图像中每个形状的出现次数。我最初检测轮廓并对其进行近似,然后计算每个轮廓中存在的顶点。我的代码如下所示:

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

我的代码无法检测这张图片中的星星:

Image with stars and other basic shapes

我应该对代码进行哪些更改?

最佳答案

对我有用的是比较形状周边面积的平方根。一颗星大约为 0.145(+/- .0015,因为一些边缘没有完美显示)。六边形 0.255,三角形 0.21,正方形 0.247,五边形 0.250。

圆度也起作用(三角形在 0.26 到 .27 之间),并且它也有类似的区别(六边形为 .83,三角形为 .55-.56,正方形为 .77,而正方形为 .78五角大楼)

下面是它的 C++ 代码(我这里的电脑上没有 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);

}

两种方式 - 使用圆度或我的 sqrt(area)/arclength 方法 - 结果:image with stars highlighted

关于python - 在opencv-python中检测星形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34203311/

相关文章:

ios - iOS 上的 CvQueryHistValue_1D?

image-processing - 如何检测隔行图像上的帧是奇数还是偶数?

android - 在android中裁剪图像的特定部分

performance - Matlab:如何对二维向量集上的嵌套循环进行向量化

python - SQL Server 透视一列并保留其他列

python - Plotly 图形对象中线条的离散色阶 (Python)

opencv - 静止图像中的虹膜检测

opencv - 如何连接具有四列的数据文件

python - 修改 Twisted 的 FileSender() 以支持字节范围 header

python - 尝试使用Python在Socket中扫描IP以获取域名