之前截取了一些羽绒服的销量数据,以为能凑着这次广州飞雪的超强寒潮写一点东西,最后发现数据并不是很有说服力。由于淘宝反爬虫的策略,因此过程中用浏览器配合按键精灵每小时截图,最后也是搜集到了不少位图数据,因此有一个问题就怎样在这些位图中将数字抽取出来,因为数字几乎没有干扰,这是个很基本的OCR(Optical Character Recognition,光学字符识别)问题。
考虑还是用MATLAB做图像处理熟悉,简单查了下资料,思路很简单:
- 预处理,剪裁出需要识别的区域,灰度化,二值化。
2.(关键)字符分隔,这个其实很简单,向x轴y轴分别投影,找出0和正整数之间的过渡位置,即字符和间隙的分隔位置
- 将图像字符串分隔为单个字符,分别向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