Was für mich funktionierte, war ein Vergleich zwischen der Quadratwurzel der Fläche über den Umfang der Form. Es ist ungefähr 0,145 für einen Stern (+/- 0,0015, weil einige der Kanten nicht perfekt herausgekommen sind). 0,255 für das Sechseck, 0,21 für die Dreiecke, 0,247 für das Quadrat und 0,250 für das Pentagon.
Circularity funktioniert auch (die hat die Dreiecke bei 0.26 bis .27), und es unterscheidet sich ähnlich (.83 für das Sechseck, .55-.56 für das Dreieck, .77 für das Quadrat, und. 78 für das Fünfeck)
Unten ist der C++ Code für sie (ich habe nicht python auf meinem PC hier, aber die Idee ist die gleiche):
#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);
}
beiden Wege - entweder mit Zirkularität oder meinem sqrt (area)/arclength-Methode - Ergebnis in:
von (dichten oder spärlichen) Kontur, versuchen Sie Matc hShape-Funktion: http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#double%20matchShapes%28InputArray%20contour1,%20InputArray%20contour2,%20int%20method,%20double%20parameter%29 – Micka
Sie können _circularity_ verwenden, um Shapes zu erkennen: '(4 * pi * area)/(perimeter^2)'. Sternformen haben eine Kreisform um 0,25, zum Beispiel – Miki