要识别的数字在图像的固定区域,并且是印刷体数字。通过提前抠图的方式设定模板,截取图片中的数字与模板进行相似度匹配,找到 相似度最高的模板对应的数字即为识别的结果。
只能应用与最简单情况下的数字识别且复杂度较高。
步骤如下:
1.制作模板,数字0~9
2.图片预处理:灰度处理、二值化
3.图片切割,得到单个的数字图片
4.模板匹配得到数字的值
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
//求所有像素点的和
int get_pxsum(Mat image) {
int a=0;
for(int i=0;i<image.rows;i++) {
for(int j=0;j<image.cols;j++) {
a+=image.at<uchar>(i,j);
}
}
return a;
}
//求差值最小的模板对应的匹配数字
int getSubstract(Mat image) {
Mat result_img;
int min=1000000;
int result_no=0;//匹配结果
for(int i=0;i<10;i++) {
stringstream str;
str << "/home/wfl/Desktop/test/template/" << i << ".jpg";
Mat Template = imread(str.str(), CV_LOAD_IMAGE_GRAYSCALE);
threshold(Template, Template, 100, 255, CV_THRESH_BINARY);
absdiff(Template,image,result_img);
//cout<<get_pxsum(result_img)<<endl;
if(get_pxsum(result_img)<min){
min=get_pxsum(result_img);
result_no=i;
}
}
//cout<<result_no<<endl;
return result_no;
}
int main()
{
VideoCapture capture;
capture.open( "/home/wfl/Desktop/test/record.mp4" );
if ( !capture.isOpened( ) )
cout << "fail to open the right video" << endl;
long currentFrame =0;
long totalFrameNumber = capture.get( CV_CAP_PROP_FRAME_COUNT );
//cout<<totalFrameNumber<<endl;
Mat image;
//图像处理
image=imread("/home/wfl/Desktop/test/record1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
threshold(image, image, 100 , 255, CV_THRESH_BINARY);
//imshow("original",image);
//图像切割
Mat first,second,third;
Rect rect1(1200,14,12,19);
Rect rect2(1214,14,12,19);
Rect rect3(1228,14,12,19);
first=image(rect1).clone();
second=image(rect2).clone();
third=image(rect3).clone();
/*imshow("first",first);
imshow("second",second);
imshow("third",third);
waitKey();*/
//模板匹配与数字识别
cout<<getSubstract(first)<<" "<<getSubstract(second)<<" "<<getSubstract(third)<<endl;
return 0;
}
测试图片
输出结果