http://blog.csdn.net/WL2002200/article/details/43149229
OpenCV 中KNN构造函数如下。
- C++: CvKNearest::CvKNearest()
- C++: CvKNearest::CvKNearest(const Mat& trainData, const Mat& responses, const Mat& sam-
- pleIdx=Mat(), bool isRegression=false, int max_k=32 )
训练函数为:
- C++: bool CvKNearest::train(
- const Mat& trainData, //训练数据
- const Mat& responses,//对应的响应值
- const Mat& sampleIdx=Mat(),//样本索引
- bool isRegression=false,//是否是回归,否则是分类问题
- int maxK=32, //最大K值
- bool updateBase=false//是否更新数据,是,则maxK需要小于原数据大小 )
查找函数:
- C++: float CvKNearest::find_nearest(
- const Mat& samples,//按行存储的测试数据
- int k, //K 值
- Mat* results=0,//预测结果
- const float** neighbors=0, //近邻指针向量
- Mat* neighborResponses=0, //近邻值
- Mat* dist=0 //距离矩阵) const
- C++: float CvKNearest::find_nearest(
- const Mat& samples,
- int k,
- Mat& results,
- Mat& neighborResponses,
- Mat& dists) const
还有一些其他辅助函数,无关紧要,略去了。
opencv 有KNN 的示例,改写成C++ 版本如下:
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/ml/ml.hpp>
- int main( )
- {
- const int K = 10;
- int i, j, k, accuracy;
- float response;
- int train_sample_count = 100;
- cv::RNG rng_state(-1);
- cv::Mat trainData(train_sample_count,2,CV_32FC1);
- cv::Mat trainClasses(train_sample_count,1,CV_32FC1);
- cv::Mat img(cv::Size(500,500),CV_8UC3,cv::Scalar::all (0));
- float _sample[2];
- cv::Mat sample(1,2,CV_32FC1,_sample);
- cv::Mat trainData1, trainData2, trainClasses1, trainClasses2;
- // form the training samples
- trainData1 = trainData.rowRange (0,train_sample_count/2);
- rng_state.fill (trainData1,CV_RAND_NORMAL,cv::Scalar(200,200),cv::Scalar(50,50));
- trainData2 = trainData.rowRange (train_sample_count/2,train_sample_count);
- rng_state.fill (trainData2,CV_RAND_NORMAL,cv::Scalar(300,300),cv::Scalar(50,50));
- trainClasses1 = trainClasses.rowRange (0,train_sample_count/2);
- trainClasses1.setTo (1);
- trainClasses2 = trainClasses.rowRange (train_sample_count/2,train_sample_count);
- trainClasses2.setTo (2);
- // learn classifier
- CvKNearest knn( trainData, trainClasses, cv::Mat(), false, K );
- cv::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<cv::Vec3b>(i,j) = response == 1 ?
- (accuracy > 5 ? cv::Vec3b(0,0,180) : cv::Vec3b(0,120,180)) :
- (accuracy > 5 ? cv::Vec3b(0,180,0) : cv::Vec3b(0,120,120));
- }
- }
- // display the original training samples
- for( i = 0; i < train_sample_count/2; i++ )
- {
- cv::Point pt;
- pt.x = cvRound(trainData1.at<float>(i,0));
- pt.y = cvRound(trainData1.at<float>(i,1));
- cv::circle (img,pt,2,cv::Scalar(0,0,255),1,CV_FILLED);
- pt.x = cvRound(trainData2.at<float>(i,0));
- pt.y = cvRound(trainData2.at<float>(i,1));
- cv::circle (img,pt,2,cv::Scalar(0,255,0),1,CV_FILLED);
- }
- cv::namedWindow( "classifier result", 1 );
- cv::imshow( "classifier result", img );
- cv::waitKey(0);
- return 0;
- }