#include <iostream>
#include <fstream>
#include <opencv2>
#include <opencv2>
#include <opencv2>
#include <opencv2>
#include <opencv2>
using namespace std;
using namespace cv;
using namespace cv::ml;
int main(int argc,char* argv[])
{
Mat img = imread("./digits.png");
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY);
int b = 20;
int m = gray.rows / b; //原圖為1000*2000
int n = gray.cols / b; //裁剪為5000個20*20的小圖塊
Mat data,labels; //特徵矩陣
for (int i = 0; i < n; i++)
{
int offsetCol = i*b; //列上的偏移量
for (int j = 0; j < m; j++)
{
int offsetRow = j*b; //行上的偏移量
//截取20*20的小塊
Mat tmp;
gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
data.push_back(tmp.reshape(0,1)); //序列化後放入特徵矩陣
labels.push_back((int)j / 5); //對應的標註
}
}
data.convertTo(data, CV_32F); //uchar型轉換為cv_32f
int samplesNum = data.rows;
int trainNum = 3000;
Mat trainData, trainLabels;
trainData = data(Range(0, trainNum), Range::all()); //前3000個樣本為訓練數據
trainLabels = labels(Range(0, trainNum), Range::all());
//使用KNN算法
int K = 5;
Ptr<traindata> tData = TrainData::create(trainData, ROW_SAMPLE, trainLabels);/<traindata>
Ptr<knearest> model = KNearest::create();/<knearest>
model->setDefaultK(K);
model->setIsClassifier(true);
model->train(tData);
//預測分類
double train_hr = 0, test_hr = 0;
Mat response;
// compute prediction error on train and test data
for (int i = 0; i < samplesNum; i++)
{
Mat sample = data.row(i);
float r = model->predict(sample); //對所有行進行預測
//預測結果與原結果相比,相等為1,不等為0
r = std::abs(r - labels.at
if (i < trainNum)
train_hr += r; //累積正確數
else
test_hr += r;
}
test_hr /= samplesNum - trainNum;
train_hr = trainNum > 0 ? train_hr / trainNum : 1.;
printf("accuracy: train = %.1f%%, test = %.1f%%\\n",
train_hr*100., test_hr*100.);
waitKey(0);
return 0;
}
閱讀更多 好先生Vlog 的文章