To, co zadziałało, było porównaniem pierwiastka kwadratowego z obszaru ponad obwodem kształtu. To około 0,145 dla gwiazdy (+/- .0015, ponieważ niektóre krawędzie nie wypadły idealnie). 0.255 dla sześciokąta, .21 dla trójkątów, .247 dla kwadratu i .250 dla pięciokąta.
Okrągłość działa również (w trójkątach dochodzi od 0,26 do .27), i podobnie się różnicuje (0,83 dla sześciokąta, 0,55-.56 dla trójkąta, 0,77 dla kwadratu, oraz. 78 do pięciokąta)
Poniżej znajduje się kod C++ dla niego (nie mam Pythona na moim komputerze tutaj, ale idea jest ta sama):
#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);
}
Oba sposoby - albo za pomocą cykliczność lub mój metoda sqrt (obszar)/arclength - wynik:
z (gęsty lub rzadki) kontur, spróbuj matc Funkcja hShape: 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
Możesz użyć _circularity_ do wykrywania kształtów: '(4 * pi * area)/(obwód^2)'. Kształty gwiazd mają okrągłość około 0,25, na przykład – Miki