数字识别代码完整

数字识别代码

  • 近期完成了一个数字识别的代码,开始也不会做,但通过了解和查询自己也了解到了一些在这你给大家做个分享(本代码开发环境Opencv3)
    • 这里分享给大家一个比较好的网址,我的代码也是参照的这个改动的
    • 完整的代码如下(只试过印刷体识别)
    • 运行效果图如下:

近期完成了一个数字识别的代码,开始也不会做,但通过了解和查询自己也了解到了一些在这你给大家做个分享(本代码开发环境Opencv3)

这里分享给大家一个比较好的网址,我的代码也是参照的这个改动的

链接: [link]https://blog.csdn.net/huaweiran1993/article/details/80548290?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-4.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-4.controlAlt

完整的代码如下(只试过印刷体识别)

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;


int getColSum(Mat src, int col)//统计所有列像素的总和
{
     
	int sum = 0;
	int height = src.rows;//列
	int width =src.cols;
	for (int i = 0; i < height; i++)
	{
     
		sum = sum + src.at <uchar>(i, col);
	}
	return sum;
}

int getRowSum(Mat src, int row)//统计所有行像素的总和
{
     
	int sum = 0;
	int height = src.rows;
	int width = src.cols;
	for (int i = 0; i < width; i++)
	{
     
		sum +=src.at <uchar>(row, i);
	}
	return sum;
}

//------------进行图片的切割------------//

void cutTop(Mat& src, Mat& dstImg)//上下切割
{
     


	int top, bottom;
	top = 0;
	bottom = src.rows;

	int i;
	for (i = 0; i < src.rows; i++)
	{
     
		int colValue = getRowSum(src, i);//统计所有行像素的总和
		if (colValue > 0)//扫描直到行像素的总和大于0时,记下当前位置top
		{
     
			top = i;
			break;
		}
	}
	for (; i <src.rows; i++)
	{
     
		int colValue = getRowSum(src, i);//统计所有行像素的总和
		//cout << i << " th " << colValue << endl;
		if (colValue == 0)//继续扫描直到行像素的总和等于0时,记下当前位置bottom
		{
     
			bottom = i;
			break;
		}
	}

	int height = bottom - top;
	Rect rect(0, top, src.cols, height);
	dstImg = src(rect).clone();
	
}

	int cutLeft(Mat& src, Mat& leftImg, Mat& rightImg)//左右切割
	{
     
		int left, right;
		left = 0;
		right = src.cols;

		int i;
		for (i = 0; i < src.cols; i++)
		{
     
			int colValue = getColSum(src, i);//统计所有列像素的总和
			//cout <
			if (colValue > 0)//扫描直到列像素的总和大于0时,记下当前位置left
			{
     
				left = i;
				break;
			}
		}
		if (left == 0)
		{
     
			return 1;
		}
		//继续扫描
		for (i; i < src.cols; i++)
		{
     
			int colValue = getColSum(src, i);//统计所有列像素的总和
		
			if (colValue == 0)//继续扫描直到列像素的总和等于0时,记下当前位置right
			{
     
				right = i;
				break;
			}
		}
		int width = right - left;//分割图片的宽度则为right - left
		Rect rect(left, 0, width, src.rows);//构造一个矩形,参数分别为矩形左边顶部的X坐标、Y坐标,右边底部的X坐标、Y坐标(左上角坐标为0,0)
		leftImg = src(rect).clone();
		Rect rectRight(right, 0, src.cols - right,src.rows);//分割后剩下的原图
		rightImg = src(rectRight).clone();
		cutTop(leftImg, leftImg);//上下切割

		return 0;
	}
    int getPXSum(Mat &src, int &a)//获取所有像素点和
	{
     
		threshold(src, src, 100, 255, CV_THRESH_BINARY);
		a = 0;
		for (int i = 0; i <src.rows; i++)
		{
     
			for (int j = 0; j < src.cols; j++)
			{
     
				a += src.at <uchar>(i, j);
			}
		}
		return a;
	}

	int  getSubtract(Mat &src) //数字识别
	{
     
		Mat img_result;
		int min = 2000000;
		int serieNum = 0;
		int i;
		for (int i = 0; i < 10; i++)
		{
     
			char name[200];
			sprintf_s(name, "%d.png", i);

			Mat Template = imread(name, CV_LOAD_IMAGE_GRAYSCALE);//读取模板
			
			threshold(Template, Template, 100, 255, CV_THRESH_BINARY);
			
			resize(src, src, Size(32, 58), 0, 0, CV_INTER_LINEAR);
			resize(Template, Template, Size(32, 58), 0, 0, CV_INTER_LINEAR);//调整尺寸
			//imshow(name, Template);

			/*让需要匹配的图分别和10个模板对应像素点值相减,然后求返回图片的整个图片的像素点值得平方和,和哪个模板匹配时候返回图片的平方和最小则就可以得到结果*/
			absdiff(Template, src, img_result);//AbsDiff,OpenCV中计算两个数组差的绝对值的函数。
			int diff=0;
			int a = getPXSum(img_result, diff);//获取所有像素点和
			if (a< min)//像素点对比
			{
     
				min = a;
				serieNum = i;
			}
		}

		printf("最小距离是%d ", min);
		printf("匹配到第%d个模板匹配的数字是%d\n", serieNum, serieNum);
		return serieNum;
	}

	int main()
	{
     
		Mat src = imread("sz3.png", CV_LOAD_IMAGE_GRAYSCALE);//读取图片
		imshow("原图", src);//显示原图
		threshold(src, src, 100, 255, THRESH_BINARY_INV);//二值化
		imshow("origin", src);//显示二值化后图片
		Mat leftImg, rightImg;
		int res = cutLeft(src, leftImg, rightImg);
		int a=0;
		while (res == 0)
		{
     
			char nameLeft[10];
			sprintf_s(nameLeft, "%d", a);
			a++;
			imshow(nameLeft, leftImg);//显示分割后的图片
			
			Mat srcTmp = rightImg;
			getSubtract(leftImg);
			res = cutLeft(srcTmp, leftImg, rightImg);

		    
		}
		waitKey(0);
		
	}































运行效果图如下:

数字识别代码完整_第1张图片
数字识别代码完整_第2张图片

---------------------------------------------------------------------希望可以帮到大家-----------------------------------------------------------------------
--------------------------------------------------------------- ----(请联系删除)------------------------------------------------------------------------------

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