OpenCV 图片数字识别(C++)

下面是用C++来实现的

该算法的过程与上述相同,但该算法只使用第一层次的等高线,因此算法只对每一个数字使用相同的外部轮廓。

创建示例和标签数据的代码

#include 
#include 
using namespace std;
using namespace cv;

int main()
{
	//Process image to extract contour
	Mat thr, gray, con;
	Mat src = imread("digit.png", 1);
	cvtColor(src, gray, CV_BGR2GRAY);
	threshold(gray, thr, 200, 255, THRESH_BINARY_INV); //Threshold to find contour
	thr.copyTo(con);

	// Create sample and label data
	vector< vector  > contours; // Vector for storing contour
	vector< Vec4i > hierarchy;
	Mat sample;
	Mat response_array;
	findContours( con, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); //Find contour

	for ( int i = 0; i < contours.size(); i = hierarchy[i][0] ) // iterate through first hierarchy level contours
	{
		Rect r = boundingRect(contours[i]); //Find bounding rect for each contour
		rectangle(src, Point(r.x, r.y), Point(r.x + r.width, r.y + r.height), Scalar(0, 0, 255), 2, 8, 0);
		Mat ROI = thr(r); //Crop the image
		Mat tmp1, tmp2;
		resize(ROI, tmp1, Size(10, 10), 0, 0, INTER_LINEAR ); //resize to 10X10
		tmp1.convertTo(tmp2, CV_32FC1); //convert to float
		sample.push_back(tmp2.reshape(1, 1)); // Store  sample data
		imshow("src", src);
		int c = waitKey(0); // Read corresponding label for contour from keyoard
		c -= 0x30;   // Convert ascii to intiger value
		response_array.push_back(c); // Store label to a mat
		rectangle(src, Point(r.x, r.y), Point(r.x + r.width, r.y + r.height), Scalar(0, 255, 0), 2, 8, 0);
	}
	// Store the data to file
	Mat response, tmp;
	tmp = response_array.reshape(1, 1); //make continuous
	tmp.convertTo(response, CV_32FC1); // Convert  to float
	FileStorage Data("TrainingData.yml", FileStorage::WRITE); // Store the sample data in a file
	Data << "data" << sample;
	Data.release();
	FileStorage Label("LabelData.yml", FileStorage::WRITE); // Store the label data in a file
	Label << "label" << response;
	Label.release();
	cout << "Training and Label data created successfully....!! " << endl;
	imshow("src", src);
	waitKey();
	return 0;
}

训练和测试

#include 
#include 
#include 
using namespace std;
using namespace cv;

int main()
{
	Mat thr, gray, con;
	Mat src = imread("dig.png", 1);
	// imshow("src", src);
	// waitKey(10000);

	cvtColor(src, gray, CV_BGR2GRAY);
	threshold(gray, thr, 200, 255, THRESH_BINARY_INV); // Threshold to create input
	thr.copyTo(con);


	// Read stored sample and label for training
	Mat sample;
	Mat response, tmp;
	FileStorage Data("TrainingData.yml", FileStorage::READ); // Read traing data to a Mat
	Data["data"] >> sample;
	Data.release();

	FileStorage Label("LabelData.yml", FileStorage::READ); // Read label data to a Mat
	Label["label"] >> response;
	Label.release();


	// ml::KNearest knn;
	cv::Ptr knn = cv::ml::KNearest::create();
	knn->train(sample, ml::ROW_SAMPLE, response); // Train with sample and responses
	cout << "Training compleated.....!!" << endl;

	vector< vector  > contours; // Vector for storing contour
	vector< Vec4i > hierarchy;

	//Create input sample by contour finding and cropping
	findContours(con, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
	Mat dst(src.rows, src.cols, CV_8UC3, Scalar::all(0));


	for ( int i = 0; i < contours.size(); i = hierarchy[i][0] ) // iterate through each contour for first hierarchy level .
	{
		Rect r = boundingRect(contours[i]);
		if (r.height > 50)
			continue;
		if (r.height < 5)
			continue;
		Mat ROI = thr(r);
		Mat tmp1, tmp2;
		resize(ROI, tmp1, Size(10, 10), 0, 0, INTER_LINEAR );
		tmp1.convertTo(tmp2, CV_32FC1);
		cv::Mat result;
		knn->findNearest(tmp2.reshape(1, 1), 5, result);

		float p = ((float *)result.data)[0];
		int value = (int)p;
		if (value >= 0 && value < 10) {
			char name[4];
			sprintf(name, "%d", value);
			putText(dst, name, Point(r.x, r.y + r.height) , 0, 1, Scalar(0, 255, 0), 2, 8 );
			// imshow("dst", dst);
			// waitKey(500);
		}
	}
	imshow("src", src);
	imshow("dst", dst);
	imwrite("dest.jpg", dst);
	waitKey(10000);
	return 0;
}

结果

结果,第一行中的点被检测为8,而我们还没有对点进行训练。此外,我也考虑了每一个等高线在第一层次作为样本输入,用户可以通过计算面积避免它。

 

OpenCV 图片数字识别(C++)_第1张图片

你可能感兴趣的:(计算机视觉)