数字识别代码
- 近期完成了一个数字识别的代码,开始也不会做,但通过了解和查询自己也了解到了一些在这你给大家做个分享(本代码开发环境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.control
完整的代码如下(只试过印刷体识别)
#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 <<i<<" th "<< colValue << endl;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 - leftRect 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);}
运行效果图如下:
---------------------------------------------------------------------希望可以帮到大家-----------------------------------------