头疼了两天总算整明白了:
前言:
在ocr(数字图像文本识别)过程中,由于图像的不可控性,总会存在一定角度的倾斜。倾斜角度要满足一定范围:
θ≤d/L (θ即倾斜角度,d为文本行距,L为文本行长)
若超出这个范围,则可能将下(上)一行的文字拼接到本行,替代原有文字,产生误断。
通常来讲:θ应在2度以内。
为了避免或者是纠正这种问题,就需要对图像进行预处理,进行倾斜检测:
检测方法
有如下假设:搜索图像都已进行了二值化处理(非黑即白)(常用方法:中值阈值,最佳阈值,otu算法)。图像大小为M*N,图像只是倾斜,并未上下翻转。
直线在想素质上的特点:扫描图像中一条直线方程上的坐标点,会发现黑点最多(N<Max(M,N))。
方法1:投影法。
思想是:如图所示,扫描有限条直线(m条),统计每条直线上法线方向黑点最多(最少)的一斜行。在所有最值中,最大的那行所对应的斜率mx/n的绝对值即倾斜角度的正切值。
实现方法:输入int[][] pixels;
输出int[][] A;
步骤: 1初始化参数int a=n, b=0, count=0, max=0,c=0;
直线方程:y=ax/b;法线方程y=bx/a+c
2 for(;b<m;b++){
max=0;
for(int i=0;i<n;i++){
//统计对应斜率(a,b)时,过点(i*b/a,i)的法线上的黑点数;
count=0; c=(a*a-b*b)*i/a*a
for(int j=0;j<m;i++)
if(pixels[j][b/a*j+c]==1)count++;
if(count>max){
max=count;
A[b][0]=i;//记录每种斜率上黑点最多的斜行,和最大值;
A[b][1]=max;
}
}
}
3接下来是对数组A的分析了。这个数组保存了图像各个方向上最长直线的斜率和位置。
选择合理的其中一个作为倾斜角度,即可。也可简单的只去最大值;因为文本图像通常没有很
多的噪声,不会出现大的色块。其实依照数组你甚至可以重绘所有被检测到的直线。
方法2:hough变换:
原理:
图像中任意一条直线的方程可写为Ax+By=C;做归一化处理可得方程Ax+By=1;那么一条直线将唯一的被数对(A,B)确定。
过任意一点(a,b)的直线方程为Ma+Nb=1;若p1(a,b),p2(c,d)共线(不是几何意义的共线,而是有条线,两点均在此线上)Ax+By=1可得:M1a+N1b=1与M2c+N2d=1交于(A,B)点.
如图所示:
那么在扫描整幅图像时:可作如下处理:
0.初始条件:int[][] AB;
1.i=0->m;j=0->n
if(pixels[i][j]==1)
a=0->max;b=0->max
if(ai+bj==1)
AB[i][j]++;
2.寻找AB中的最大值,其对应坐标(i,j);就是所求倾斜角的-i/j就是倾斜角的正切值。
实现:
上述原理中有一处不好处理就是AB的取值范围,不好确定。
做如下改进即可,原图像中直线的方程设为:
p=xcosa+ysina;(a为图像中直线倾斜角度的余角,p为原点到直线的距离)
则A->p/sina b->p/cosa 0<a<180 0<p<sqrt(m*m+n*n);
即做了一个十字坐标系xoy到极坐标系poa的转换。
PS:由此可以看到直线检测在图像处理中是如何运作的。是跟曲线方程特征而决定的。同理其他曲线,也可根据曲线方程的特点有hough变换得到。投影法就略显困难。因此hough变换被广泛用于图像中图形识别过程中。
但是hough变换也存在缺点:计算量大,优点是图像内容无关。