OPENCV ANN(類神經網路) 手寫數字辨識 (opencv249_ann_digital_number) [還沒自己改寫~純粹收集]

OPENCV ANN(類神經網路) 手寫數字辨識 (opencv249_ann_digital_number) [還沒自己改寫~純粹收集]

OPENCV ANN(類神經網路) 手寫數字辨識 (opencv249_ann_digital_number) [還沒自己改寫~純粹收集]



資料來源:https://blog.csdn.net/cherrywish/article/details/78761411

https://blog.csdn.net/qq_15947787/article/details/51385861


GITHUB: https://github.com/jash-git/opencv249_ann_digital_number


圖片重置(縮放)大小resize、圖像二值化threshold、類神經網路CvANN_MLP

#include <iostream>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <stdio.h>
using namespace cv;
using namespace std;
#define TRAIN false    //是否进行训练,true表示重新训练,false表示读取xml文件中的ann模型

int main()
{
	//	const string fileform = "*.png";
	//  const string perfileReadPath ;

	const int sample_mun_perclass = 20;//训练字符每类数量
	const int class_mun = 10;//训练字符类数

	const int image_cols = 8;
	const int image_rows = 16;
	const string fileForm = ".txt";
	const string fileReadName = "D:/Opencv2.4.9/VS2013Project/myAnn/myAnn/myCharPic/";
	string fileReadPath;
	string txtName;
	char tmp[10];
	string ImgName;
	float trainingData[class_mun*sample_mun_perclass][image_rows*image_cols] = { { 0 } };//每一行一个训练样本
	float labels[class_mun*sample_mun_perclass][class_mun] = { { 0 } };//训练样本标签
	CvANN_MLP bp;
	//ifstream fin(txtName);//正样本图片的文件名列表

	if (TRAIN)
	{
		for (int i = 0; i<class_mun; ++i)//不同类
		{
			//读取每个类文件夹下所有图像
			sprintf(tmp, "%d", i);
			cout << "文件夹" << i << endl;
			txtName = tmp + fileForm;
			ifstream fin(txtName);//正样本图片的文件名列表
			for (int j = 1; j <= sample_mun_perclass; j++)
			{
				getline(fin, ImgName);
				cout << "处理:" << ImgName << endl;
				fileReadPath = fileReadName + tmp + "/" + ImgName;
				Mat srcImage = imread(fileReadPath, 0);//读取图片
				Mat resizeImage;
				Mat trainImage;
				Mat result;

				resize(srcImage, resizeImage, Size(image_cols, image_rows), (0, 0), (0, 0), CV_INTER_AREA);//使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现
				threshold(resizeImage, trainImage, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

				for (int k = 0; k<image_rows*image_cols; ++k)
				{
					trainingData[i*sample_mun_perclass + (j - 1)][k] = (float)trainImage.data[k];
					//trainingData[i*sample_mun_perclass+(j-1)][k] = (float)trainImage.at<unsigned char>((int)k/8,(int)k%8);//(float)train_image.data[k];
					//cout<<trainingData[i*sample_mun_perclass+(j-1)][k] <<" "<< (float)trainImage.at<unsigned char>(k/8,k%8)<<endl;
				}

			} //如果设置读入的图片数量,则以设置的为准,如果图片不够,则读取文件夹下所有图片

		}

		// Set up training data Mat
		Mat trainingDataMat(class_mun*sample_mun_perclass, image_rows*image_cols, CV_32FC1, trainingData);
		cout << "trainingDataMat——OK!" << endl;

		// Set up label data 
		for (int i = 0; i <= class_mun - 1; ++i)
		{
			for (int j = 0; j <= sample_mun_perclass - 1; ++j)
			{
				for (int k = 0; k<class_mun; ++k)
				{
					if (k == i)
						labels[i*sample_mun_perclass + j][k] = 1;
					else labels[i*sample_mun_perclass + j][k] = 0;
				}
			}
		}
		Mat labelsMat(class_mun*sample_mun_perclass, class_mun, CV_32FC1, labels);
		cout << "labelsMat:" << endl;
		cout << labelsMat << endl;
		cout << "labelsMat——OK!" << endl;

		//训练代码

		cout << "training start...." << endl;

		// Set up BPNetwork's parameters
		CvANN_MLP_TrainParams params;
		params.train_method = CvANN_MLP_TrainParams::BACKPROP;
		params.bp_dw_scale = 0.001;
		params.bp_moment_scale = 0.1;
		params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.0001);  //设置结束条件
		//params.train_method=CvANN_MLP_TrainParams::RPROP;
		//params.rp_dw0 = 0.1;
		//params.rp_dw_plus = 1.2;
		//params.rp_dw_minus = 0.5;
		//params.rp_dw_min = FLT_EPSILON;
		//params.rp_dw_max = 50.;

		//Setup the BPNetwork
		Mat layerSizes = (Mat_<int>(1, 5) << image_rows*image_cols, 128, 128, 128, class_mun);
		bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM, 1.0, 1.0);//CvANN_MLP::SIGMOID_SYM
		//CvANN_MLP::GAUSSIAN
		//CvANN_MLP::IDENTITY
		cout << "training...." << endl;
		bp.train(trainingDataMat, labelsMat, Mat(), Mat(), params);

		bp.save("../bpcharModel.xml"); //save classifier
		cout << "training finish...bpModel1.xml saved " << endl;
	}
	else //若TRAIN为false,从XML文件读取训练好的分类器
	{
		bp.load("../bpcharModel.xml");//从XML文件读取训练好的SVM模型
	}

	//测试神经网络
	cout << "测试:" << endl;
	Mat test_image = imread("test2.png", CV_LOAD_IMAGE_GRAYSCALE);
	Mat test_temp;
	resize(test_image, test_temp, Size(image_cols, image_rows), (0, 0), (0, 0), CV_INTER_AREA);//使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现
	threshold(test_temp, test_temp, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
	Mat_<float>sampleMat(1, image_rows*image_cols);
	for (int i = 0; i<image_rows*image_cols; ++i)
	{
		sampleMat.at<float>(0, i) = (float)test_temp.at<uchar>(i / 8, i % 8);
	}

	Mat responseMat;
	bp.predict(sampleMat, responseMat);
	Point maxLoc;
	double maxVal = 0;
	minMaxLoc(responseMat, NULL, &maxVal, NULL, &maxLoc);
	cout << "识别结果:" << maxLoc.x << "	相似度:" << maxVal * 100 << "%" << endl;
	imshow("test_image", test_image);
	waitKey(0);

	return 0;
}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *