LZN's Blog CodePlayer

【MATLAB】数字OCR

2016-02-01
LZN

之前截取了一些羽绒服的销量数据,以为能凑着这次广州飞雪的超强寒潮写一点东西,最后发现数据并不是很有说服力。由于淘宝反爬虫的策略,因此过程中用浏览器配合按键精灵每小时截图,最后也是搜集到了不少位图数据,因此有一个问题就怎样在这些位图中将数字抽取出来,因为数字几乎没有干扰,这是个很基本的OCR(Optical Character Recognition,光学字符识别)问题。

考虑还是用MATLAB做图像处理熟悉,简单查了下资料,思路很简单:

  1. 预处理,剪裁出需要识别的区域,灰度化,二值化。

2.(关键)字符分隔,这个其实很简单,向x轴y轴分别投影,找出0和正整数之间的过渡位置,即字符和间隙的分隔位置

  1. 将图像字符串分隔为单个字符,分别向x轴y轴投影,记录投影特征,遍历10个阿拉伯数字

4.待识别的新样本重复1和2的操作,计算与记录特征的标准偏差,设定一合理阈值偏差,小于该偏差即可认为识别成功。

对于标准的屏幕显示的数字(或者字母),可以想象上述过程基本能做到极高的识别率了。手写体识别估计就更复杂了,需要用到机器学习等方法,木有涉猎,暂且不表。

识别部分程序代码如下


function img_number()
    clear all;
    close all;
    echo off;
	
	
	%---------------Read features---------------
	x_mat=load('../feature/x_project.txt');
	y_mat=load('../feature/y_project.txt');
	
    I = imread('../img/2016011920.bmp');
    I=I(612:625,900:946,:);
    I_int = rgb2gray(I);
    
    I_int=~im2bw(I_int,0.5);   %binary and reverse
    I_x_pro = sum(I_int,1);    % project to the x axis
    imshow(I_int)
	num_x_start=strfind(I_x_pro~=0,[0 1])+1; %find the start point of a specific figure
	num_x_end=strfind(I_x_pro==0,[0 1]); %find the end point of a specific figure
	
	I_y_pro = sum(I_int,2);   % project to the y axis
    num_y_start=strfind(I_y_pro'~=0,[0 1])+1; %find the start point of a specific figure
	num_y_end=strfind(I_y_pro'==0,[0 1]); %find the end point of a specific figure
	
	fig_num = size(num_x_start);   % how many figures in the image
	fig_stdwidth = 6;
	fig_stdheight = num_y_end-num_y_start+1;
	for ii=1:fig_num(2)
        I_std_ele_fig = imresize(I_int(num_y_start:num_y_end,num_x_start(ii):num_x_end(ii)), [fig_stdheight fig_stdwidth]);
		std_x_pro = sum(I_std_ele_fig,1);
		std_y_pro = sum(I_std_ele_fig,2)';
		for jj=1:10
			if(sum((std_x_pro-x_mat(jj,2:end)).^2)<10 & sum((std_y_pro-y_mat(jj,2:end)).^2)<10)
				jj-1
			end
		end 
    end 

Comments

Content