机器学习实践系列之16 - OpenCV之手写体识别

       OpenCV3.0 开始有了手写体数字识别的 例子,opencv提供了一张手写数字图片进行训练。

       图片位置:/opencv/sources/samples/data/digits.png,

       例子中使用 KNN最近邻算法进行 训练和分类,对于数字的识别率能达到 90% 以上,当然也是因为数字比较简单,不过作为入门级的OCR,想来应该是够了。


参考代码:

#include 
#include "opencv2\opencv.hpp"

using namespace std;
using namespace cv;

#pragma comment(lib,"opencv_core310.lib")  
#pragma comment(lib,"opencv_highgui310.lib") 
#pragma comment(lib,"opencv_imgproc310.lib")
#pragma comment(lib,"opencv_ml310.lib") 

#define TRAIN_NUM 3000

int main()
{
	Mat src = imread("digits.png");
	Mat grayImage;
	cvtColor(src, grayImage, CV_BGR2GRAY);
	threshold(grayImage, grayImage, 48, 255, CV_THRESH_BINARY);

	int m = grayImage.rows / 20;   // 原图为2000*1000
	int n = grayImage.cols / 20;   // 裁剪为20*20的小块

	Mat data,labels;   // 特征矩阵
	for(int i=0; i tData = ml::TrainData::create(trainData, ml::ROW_SAMPLE, trainLabels);
	Ptr model = ml::KNearest::create();
	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; ipredict(sample);   // 对所有行进行预测
		// 预测结果与原结果相比,相等为1,不等为0
		r = std::abs(r - labels.at(i)) <= FLT_EPSILON ? 1.f : 0.f;          

		if (i < TRAIN_NUM)
			train_hr += r;  // 累积正确数
		else
			test_hr += r;
	}

	test_hr /= data.rows - TRAIN_NUM;
	train_hr = TRAIN_NUM>0 ? train_hr/TRAIN_NUM : 1.0;

	printf("accuracy: train = %.1f%%, test = %.1f%%\n",train_hr*100., test_hr*100.);
	waitKey(0);
	return 0;
}

你可能感兴趣的:(机器学习,计算机视觉)