forked from oreillymedia/Learning-OpenCV-3_examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request oreillymedia#26 from DolotovEvgeniy/learning20
Add examples for Chapter 20
- Loading branch information
Showing
3 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//Example 20-01. Using K-means | ||
#include <opencv2/opencv.hpp> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
static void help(char* argv[]) { | ||
cout << "\nThis program demonstrates kmeans clustering.\n" | ||
" It generates an image with random points, then assigns a random number\n" | ||
" of cluster centers and uses kmeans to move those cluster centers to their\n" | ||
" representative location\n" | ||
"Usage:\n" | ||
<< argv[0] << "\n" << endl; | ||
} | ||
|
||
int main(int argc, char** argv) { | ||
const int MAX_CLUSTERS = 5; | ||
cv::Scalar colorTab[] = { | ||
cv::Scalar( 0, 0, 255 ), | ||
cv::Scalar( 0, 255, 0 ), | ||
cv::Scalar( 255, 100, 100 ), | ||
cv::Scalar( 255, 0, 255 ), | ||
cv::Scalar( 0, 255, 255 ) | ||
}; | ||
cv::Mat img(500, 500, CV_8UC3); | ||
cv::RNG rng(12345); | ||
for(;;) { | ||
int clusterCount = rng.uniform(2, MAX_CLUSTERS+1); | ||
int sampleCount = rng.uniform(1, 1001); | ||
cv::Mat points(sampleCount, 1, CV_32FC2), labels; | ||
clusterCount = MIN(clusterCount, sampleCount); | ||
cv::Mat centers(clusterCount, 1, points.type()); | ||
/* generate random sample from multigaussian distribution */ | ||
for(int k = 0; k < clusterCount; k++) { | ||
cv::Point center; | ||
center.x = rng.uniform(0, img.cols); | ||
center.y = rng.uniform(0, img.rows); | ||
cv::Mat pointChunk = points.rowRange( | ||
k*sampleCount/clusterCount, | ||
k == clusterCount - 1 ? sampleCount : (k+1)*sampleCount/clusterCount | ||
); | ||
rng.fill( | ||
pointChunk, | ||
cv::RNG::NORMAL, | ||
cv::Scalar(center.x, center.y), | ||
cv::Scalar(img.cols*0.05, img.rows*0.05) | ||
); | ||
} | ||
randShuffle(points, 1, &rng); | ||
kmeans( | ||
points, | ||
clusterCount, | ||
labels, | ||
cv::TermCriteria( | ||
cv::TermCriteria::EPS | cv::TermCriteria::COUNT, | ||
10, | ||
1.0 | ||
), | ||
3, | ||
cv::KMEANS_PP_CENTERS, | ||
centers | ||
); | ||
img = cv::Scalar::all(0); | ||
for(int i = 0; i < sampleCount; i++) { | ||
int clusterIdx = labels.at<int>(i); | ||
cv::Point ipt = points.at<cv::Point2f>(i); | ||
cv::circle(img, ipt, 2, colorTab[clusterIdx], cv::FILLED, cv::LINE_AA); | ||
} | ||
cv::imshow("Example 20-01", img); | ||
char key = (char)cv::waitKey(); | ||
if(key == 27 || key == 'q' || key == 'Q') // 'ESC' | ||
break; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//Example 20-02. Using the Mahalanobis distance for classification | ||
#include <opencv2/opencv.hpp> | ||
#include <iostream> | ||
#include <ctime> | ||
#include <algorithm> | ||
|
||
using namespace std; | ||
|
||
const int CLUSTER_COUNT = 4; | ||
const int SAMPLE_COUNT = 500; | ||
const cv::Scalar colorTab[] = { | ||
cv::Scalar( 0, 0, 255 ), | ||
cv::Scalar( 0, 255, 0 ), | ||
cv::Scalar( 255, 0, 0 ), | ||
cv::Scalar( 255, 0, 255 ), | ||
cv::Scalar( 0, 255, 255 ) | ||
}; | ||
|
||
static void help(char* argv[]) { | ||
cout << "\nThis program demonstrates using the Mahalanobis distance for classification.\n" | ||
" It generates an image with random points, uses kmeans clustering.\n" | ||
" And then uses the Mahalanobis distance for classification.\n" | ||
"Usage:\n" | ||
<< argv[0] << "\n" << endl; | ||
} | ||
int main(int argc, char** argv) { | ||
cv::Mat img(500, 500, CV_8UC3, cv::Scalar::all(0)); | ||
|
||
cv::Mat points(SAMPLE_COUNT, 1, CV_32FC2); | ||
cv::RNG rng(time(NULL)); | ||
rng.fill(points, cv::RNG::UNIFORM, cv::Scalar(0, 0), cv::Scalar(img.cols, img.rows)); | ||
|
||
cv::Mat labels; | ||
kmeans(points, CLUSTER_COUNT, labels, | ||
cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, | ||
10, 1.0), | ||
3, | ||
cv::KMEANS_PP_CENTERS | ||
); | ||
|
||
vector<cv::Mat> clusters(CLUSTER_COUNT); | ||
|
||
for(int i = 0; i < SAMPLE_COUNT; i++) { | ||
int clusterIdx = labels.at<int>(i); | ||
|
||
cv::Point ipt = points.at<cv::Point2f>(i); | ||
|
||
cv::Mat sample(1, 2, CV_32FC1); | ||
sample.at<float>(0, 0) = ipt.x; | ||
sample.at<float>(0, 1) = ipt.y; | ||
clusters[clusterIdx].push_back(sample); | ||
cv::circle(img, ipt, 2, colorTab[clusterIdx], cv::FILLED, cv::LINE_AA); | ||
} | ||
cv::namedWindow("Example 20-02"); | ||
cv::imshow("Example 20-02", img); | ||
|
||
vector<cv::Mat> covarMats(CLUSTER_COUNT); | ||
vector<cv::Mat> means(CLUSTER_COUNT); | ||
for(int i = 0; i < CLUSTER_COUNT; i++) { | ||
cv::calcCovarMatrix(clusters[i], covarMats[i], means[i], | ||
CV_COVAR_NORMAL | CV_COVAR_ROWS, 5); | ||
|
||
} | ||
|
||
cout << "Press any button to classify the next point!\n" | ||
<< "Press ESC to exit." << endl; | ||
|
||
for(;;) { | ||
char key = (char)cv::waitKey(); | ||
if( key == 27 ) break; | ||
|
||
cv::Mat newPoint(1, 2, CV_32FC1); | ||
newPoint.at<float>(0, 0) = rng.uniform(0, img.cols); | ||
newPoint.at<float>(0, 1) = rng.uniform(0, img.rows); | ||
vector<float> mahalanobisDistance(CLUSTER_COUNT); | ||
|
||
for(int i = 0; i < CLUSTER_COUNT; i++) { | ||
mahalanobisDistance[i] = cv::Mahalanobis(newPoint, means[i], | ||
covarMats[i]); | ||
} | ||
int clusterIdx = std::distance( mahalanobisDistance.begin(), | ||
min_element(mahalanobisDistance.begin(), | ||
mahalanobisDistance.end())); | ||
|
||
cv::circle(img, newPoint.at<cv::Point2f>(0), 5, colorTab[clusterIdx], | ||
cv::FILLED, cv::LINE_AA); | ||
cv::imshow("Example 20-02", img); | ||
} | ||
|
||
cv::destroyAllWindows(); | ||
return 0; | ||
} |