下面是手册中给出的K邻近分类器使用的例子,该例子是以CvMat形式实现的。通过下面的例子可以知道如何使用Opencv自带的分类器、矩阵数据如何访问、如何画图、如何使用Opencv的随机数生成函数等内容。在第二个例子中已将这些代码部分做了注释。
#include "ml.h" #include "highgui.h" int main( int argc, char** argv ) { const int K = 10; int i, j, k, accuracy; float response; int train_sample_count = 100; CvRNG rng_state = cvRNG( - 1); CvMat* trainData = cvCreateMat( train_sample_count, 2, CV_32FC1 ); CvMat* trainClasses = cvCreateMat( train_sample_count, 1, CV_32FC1 ); IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); float _sample[ 2]; CvMat sample = cvMat( 1, 2, CV_32FC1, _sample ); cvZero( img ); CvMat trainData1, trainData2, trainClasses1, trainClasses2; // form the training samples cvGetRows( trainData, &trainData1, 0, train_sample_count/2 ); cvRandArr( &rng_state, &trainData1, CV_RAND_NORMAL, cvScalar( 200, 200), cvScalar( 50, 50) ); cvGetRows( trainData, &trainData2, train_sample_count/2, train_sample_count ); cvRandArr( &rng_state, &trainData2, CV_RAND_NORMAL, cvScalar( 300, 300), cvScalar( 50, 50) ); cvGetRows( trainClasses, &trainClasses1, 0, train_sample_count/2 ); cvSet( &trainClasses1, cvScalar( 1) ); cvGetRows( trainClasses, &trainClasses2, train_sample_count/2, train_sample_count ); cvSet( &trainClasses2, cvScalar( 2) ); // learn classifier CvKNearest knn( trainData, trainClasses, 0, false, K ); CvMat* nearests = cvCreateMat( 1, K, CV_32FC1); for( i = 0; i < img- >height; i++ ) { for( j = 0; j < img- >width; j ++ ) { sample.data.fl[ 0] = ( float)j; sample.data.fl[ 1] = ( float)i; // estimate the response and get the neighbors’ labels response = knn.find_nearest( &sample,K, 0, 0,nearests, 0); // compute the number of neighbors representing the majority for( k = 0, accuracy = 0; k < K; k++ ) { if( nearests- >data.fl[k] == response) accuracy++; } // highlight the pixel depending on the accuracy (or confidence) cvSet2D( img, i, j, response == 1 ? (accuracy > 5 ? CV_RGB( 180, 0, 0) : CV_RGB( 180, 120, 0)) : (accuracy > 5 ? CV_RGB( 0, 180, 0) : CV_RGB( 120, 120, 0)) ); } } // display the original training samples for( i = 0; i < train_sample_count/2; i++ ) { CvPoint pt; pt.x = cvRound(trainData1.data.fl[i*2]); pt.y = cvRound(trainData1.data.fl[i*2+1]); cvCircle( img, pt, 2, CV_RGB( 255, 0, 0), CV_FILLED ); pt.x = cvRound(trainData2.data.fl[i*2]); pt.y = cvRound(trainData2.data.fl[i*2+1]); cvCircle( img, pt, 2, CV_RGB( 0, 255, 0), CV_FILLED ); } cvNamedWindow( " classifier result" , 1 ); cvShowImage( " classifier result" , img ); cvWaitKey( 0); cvReleaseMat( &trainClasses ); cvReleaseMat( &trainData ); return 0; }
#include <opencv.hpp> int main( int argc, char** argv ) { const int K = 10; int i, j, k, accuracy; float response; int train_sample_count = 100; RNG rng_state = RNG( - 1); //如何使用随机函数 Mat trainData=Mat::zeros( train_sample_count, 2, CV_32FC1 ); Mat trainClasses =Mat::zeros( train_sample_count, 1, CV_32FC1 ); Mat img = Mat::zeros( 500,500,CV_8UC3); float _sample[ 2]; Mat sample=Mat( 1, 2, CV_32FC1, _sample ); Mat trainData1, trainData2, trainClasses1, trainClasses2; // form the training samples trainData1=trainData.rowRange(0,train_sample_count/2); //如何从已有矩阵中提取部分矩阵 rng_state.fill( trainData1, CV_RAND_NORMAL,Mat(1,1,CV_64F,cvScalar(200, 200)), Mat(1,1,CV_64F,cvScalar(50, 50)) ); //如何利用随机函数赋值已有矩阵 trainData2=trainData.rowRange(train_sample_count/2,train_sample_count); rng_state.fill( trainData2, CV_RAND_NORMAL,Mat(1,1,CV_64F,cvScalar(300, 300)), Mat(1,1,CV_64F,cvScalar(50, 50)) ); trainClasses1=trainClasses.rowRange(0,train_sample_count/2); trainClasses1.setTo(Scalar( 1)); //如何初始化矩阵为同一个数值 trainClasses2=trainClasses.rowRange(train_sample_count/2,train_sample_count); trainClasses2.setTo(Scalar( 2)); // learn classifier CvKNearest knn( trainData, trainClasses,Mat(), false, K ); //如何建立分类器的训练对象 Mat nearests ( 1, K, CV_32FC1); for( i = 0; i < img.rows; i++ ) { for( j = 0; j < img.cols; j ++ ) { sample.at<float>(0,0) = ( float)j; sample.at<float>(0,1) = ( float)i; // estimate the response and get the neighbors’ labels response = knn.find_nearest( sample,K, 0, 0,&nearests, 0); //利用训练好的分类器分类新的数据 // compute the number of neighbors representing the majority for( k = 0, accuracy = 0; k < K; k++ ) { if( nearests.at<float>(0,k) == response) accuracy++; } // highlight the pixel depending on the accuracy (or confidence) img.at<Vec3b>(i,j)[2]=response == 1 ?(accuracy>5?180:180):(accuracy>5?0:120); //如何访问多通道的矩阵 img.at<Vec3b>(i,j)[1]=response == 1 ?(accuracy>5?0:120):(accuracy>5?180:120); img.at<Vec3b>(i,j)[0]=response == 1 ?(accuracy>5?0:0):(accuracy>5?0:0); } } // display the original training samples for( i = 0; i < train_sample_count/2; i++ ) { CvPoint pt; pt.x = cvRound(trainData1.at<float>(i,0)); pt.y = cvRound(trainData1.at<float>(i,1)); circle( img, pt, 2, CV_RGB( 255, 0, 0), CV_FILLED ); //在Mat数据类型中画图 pt.x = cvRound(trainData2.at<float>(i,0)); pt.y = cvRound(trainData2.at<float>(i,1)); circle( img, pt, 2, CV_RGB( 0, 255, 0), CV_FILLED ); } imshow( " classifier result" , img ); cvWaitKey( 0); return 0; }