Kau*_*ran 5 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
Run Code Online (Sandbox Code Playgroud)
我的代码不能用于检测此图像中的星星:
我应该在代码中做出哪些更改?
小智 4
对我有用的是比较形状周长面积的平方根。一颗星的值约为 0.145(+/- .0015,因为某些边缘没有完美呈现)。六边形为 0.255,三角形为 0.21,正方形为 0.247,五边形为 0.250。
圆度也确实起作用(三角形的值为 0.26 到 0.27),并且它的区别也类似(六边形为 0.83,三角形为 0.55-0.56,正方形为 0.77,五边形为 0.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);
}
Run Code Online (Sandbox Code Playgroud)
两种方式 - 使用圆度或我的 sqrt(area)/arclength 方法 - 都会导致: