opencv-识别手写数字

首先拆分图片得到数据

#include "stdafx.h"
#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int mainss(int argc, const char** argv)
{
	char ad[128] = { 0 };
	int  filename = 0, filenum = 0;
	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的小图块

	for (int i = 0; i < m; i++)
	{
		int offsetRow = i*b;  //行上的偏移量
		if (i % 5 == 0 && i != 0)
		{
			filename++;
			filenum = 0;
		}
		for (int j = 0; j < n; j++)
		{
			int offsetCol = j*b; //列上的偏移量
			sprintf_s(ad, "C:\Users\dongufang\Documents\Visual Studio 2015\Projects\opencvtest\opencvtest\data\%d\%d.jpg", filename, filenum++);
			//截取20*20的小块
			Mat tmp;
			gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
			imwrite(ad, tmp);
		}
	}
	return 0;
}

然后knn

#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ml/ml.hpp>  
using namespace std;
using namespace cv;
using namespace ml;

char ad[128] = { 0 };

int main()
{
	Mat traindata, trainlabel;
	int k = 5, testnum = 0, truenum = 0;
	//读取训练数据 4000张
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j<400; j++)
		{
			sprintf_s(ad, "C:\Users\dongufang\Documents\Visual Studio 2015\Projects\opencvtest\opencvtest\data\%d\%d.jpg", i, j);
			Mat srcimage = imread(ad);
			srcimage = srcimage.reshape(1, 1);
			traindata.push_back(srcimage);
			trainlabel.push_back(i);
		}
	}
	traindata.convertTo(traindata, CV_32F);
	Ptr<KNearest> knn = KNearest::create();
	knn->setDefaultK(k);
	knn->setIsClassifier(true);

	Ptr<TrainData> tdata = TrainData::create(traindata,ROW_SAMPLE, trainlabel);
	knn->train(tdata);

	cv::Mat nearests(1, k, CV_32F);
	//读取测试数据  1000张
	for (int i = 0; i < 10; i++)
	{
		for (int j = 400; j<500; j++)
		{
			testnum++;
			sprintf_s(ad, "C:\Users\dongufang\Documents\Visual Studio 2015\Projects\opencvtest\opencvtest\data\%d\%d.jpg", i, j);
			Mat testdata = imread(ad);
			testdata = testdata.reshape(1, 1);
			testdata.convertTo(testdata, CV_32F);
			Mat result;
			int  response = knn->predict(testdata, result);
			if (response == i)
			{
				truenum++;
			}
			cout << "result:" << response << endl;
		}
	}
	cout << "测试总数" << testnum << endl;
	cout << "正确分类数" << truenum << endl;
	cout << "准确率:" << (float)truenum / testnum * 100 << "%" << endl;
	return 0;
}

原文地址:https://www.cnblogs.com/mrcharles/p/11879789.html