中文字ocr是个比较讨厌的事情,主要是因为中文字繁多,光简体字就有6000多个以上,虽然其中大部分简体字是不常用的。对于这么一个这么大的,种类繁多的数据集,在分类的时候真心头疼,看了很多paper后,发现现在的state of the art是基于gabor filters,通过这个过滤器,对一个中文字的不同角度的比划进行过滤,然后在每个subregion里的每个角度的比划进行统计之后生成一个histogram,和bag of words一样,histogram可以用来对每个字进行分类或者用来寻找最近邻。
gabor filters 是个复杂的东西,网上的方程各种各样的,数学不好的小白就很难明白。在网上找了好多现成的函数之后,最后找到一个能用的matlab函数:
function gb=gabor_fn(rows,cols,sigma,theta,lambda,psi,gamma)
sigma_x = sigma;
sigma_y = sigma/gamma;
% Bounding box
nstds = 3;
xmax = max(abs(nstds*sigma_x*cos(theta)),abs(nstds*sigma_y*sin(theta)));
xmax = ceil(max(1,xmax));
ymax = max(abs(nstds*sigma_x*sin(theta)),abs(nstds*sigma_y*cos(theta)));
ymax = ceil(max(1,ymax));
xmin = -xmax; ymin = -ymax;
[x,y] = meshgrid(xmin:xmax,ymin:ymax);
%[x,y] = meshgrid(-rows/2:rows/2-1,-cols/2:cols/2-1);
% Rotation
x_theta=x*cos(theta)+y*sin(theta);
y_theta=-x*sin(theta)+y*cos(theta);
gb= exp(-.5*(x_theta.^2/sigma_x^2+y_theta.^2/sigma_y^2)).*cos(2*pi/lambda*x_theta+psi);
rows和cols是图片的大小, sigma是gauss的那个sigma,越大的话周围的pixels影响越大,theta要提取的比划的角度,lambda这个貌似是什么的长度(不明白啊),psi这里没用,gamma生成y_sigma。
通过改变theta这个角度值可以获得不同角度比划的信息。
I = imread('~/Desktop/11.png')
J = rgb2gray(I);
K = imresize(J,[64,64])
gb=gabor_fn(64,64,1.2,theta,5,0,1)
这里的theta分别是pi/2, pi/4, pi和 3*pi/4 这个四个值,他们可以分别抓取中文字比划的那8个方向。下面就是这个函数能产生的效果
冲上面的图就能看出这个过滤器的威力,过滤图片之后,我们可以对每个图片其中某个的区域的点阵进行统计,这样生成一个histogram,通过histogram可以有效的对每个字进行区分。
在我的试验中,我用了16个1616大小的方格作为第一次层histogram数组,然后在它的上面又叠加了9个1616的数组,总共是一个长(16+9)*4 = 100的数组。这么长的数组以后还的进行pca或者lda什么。实验在进行中。。。
转自:http://kkx.github.io/blog/2012/06/28/gabor-filtersdui-zhong-wen-zi-tu-pian-de-te-zheng-ti-qu/