mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.5 KiB
83 lines
2.5 KiB
#include "opencv2/highgui.hpp" |
|
#include "opencv2/core.hpp" |
|
#include "opencv2/imgproc.hpp" |
|
#include <iostream> |
|
|
|
using namespace cv; |
|
using namespace std; |
|
|
|
// static void help() |
|
// { |
|
// cout << "\nThis program demonstrates kmeans clustering.\n" |
|
// "It generates an image with random points, then assigns a random number of cluster\n" |
|
// "centers and uses kmeans to move those cluster centers to their representitive location\n" |
|
// "Call\n" |
|
// "./kmeans\n" << endl; |
|
// } |
|
|
|
int main( int /*argc*/, char** /*argv*/ ) |
|
{ |
|
const int MAX_CLUSTERS = 5; |
|
Scalar colorTab[] = |
|
{ |
|
Scalar(0, 0, 255), |
|
Scalar(0,255,0), |
|
Scalar(255,100,100), |
|
Scalar(255,0,255), |
|
Scalar(0,255,255) |
|
}; |
|
|
|
Mat img(500, 500, CV_8UC3); |
|
RNG rng(12345); |
|
|
|
for(;;) |
|
{ |
|
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1); |
|
int i, sampleCount = rng.uniform(1, 1001); |
|
Mat points(sampleCount, 1, CV_32FC2), labels; |
|
|
|
clusterCount = MIN(clusterCount, sampleCount); |
|
Mat centers; |
|
|
|
/* generate random sample from multigaussian distribution */ |
|
for( k = 0; k < clusterCount; k++ ) |
|
{ |
|
Point center; |
|
center.x = rng.uniform(0, img.cols); |
|
center.y = rng.uniform(0, img.rows); |
|
Mat pointChunk = points.rowRange(k*sampleCount/clusterCount, |
|
k == clusterCount - 1 ? sampleCount : |
|
(k+1)*sampleCount/clusterCount); |
|
rng.fill(pointChunk, RNG::NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05)); |
|
} |
|
|
|
randShuffle(points, 1, &rng); |
|
|
|
double compactness = kmeans(points, clusterCount, labels, |
|
TermCriteria( TermCriteria::EPS+TermCriteria::COUNT, 10, 1.0), |
|
3, KMEANS_PP_CENTERS, centers); |
|
|
|
img = Scalar::all(0); |
|
|
|
for( i = 0; i < sampleCount; i++ ) |
|
{ |
|
int clusterIdx = labels.at<int>(i); |
|
Point ipt = points.at<Point2f>(i); |
|
circle( img, ipt, 2, colorTab[clusterIdx], FILLED, LINE_AA ); |
|
} |
|
for (i = 0; i < centers.rows; ++i) |
|
{ |
|
Point2f c = centers.at<Point2f>(i); |
|
circle( img, c, 40, colorTab[i], 1, LINE_AA ); |
|
} |
|
cout << "Compactness: " << compactness << endl; |
|
|
|
imshow("clusters", img); |
|
|
|
char key = (char)waitKey(); |
|
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC' |
|
break; |
|
} |
|
|
|
return 0; |
|
}
|
|
|