opencv 文字角度_opencv 文字识别

(40) 2024-08-16 07:01:01

这里主要记录下我在工作中对倾斜字体文本行的校正的方法探索,废话不多,一起说来看看吧。


目录

一、算法流程图

二、算法实现

2.1、预处理

2.2、水平模糊

2.3、垂直投影

2.4、短斜线倾斜角度的统计计算

2.5、倾斜校正

三、算法实现的最终结果


实现倾斜文本行字体的校正主要分为两部分,一部分为倾斜角度的检测,另一部分为倾斜校正。其中倾斜角度的检测极为重要,他关系到后续的校正。

一、算法流程图

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第1张

二、算法实现

2.1、预处理

原始图片:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第2张

这里主要是灰度化、滤波以及二值化,结果如下:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第3张

2.2、水平模糊

水平模糊也叫做游程平滑。是将图像上长度小于某一域值的连续黑点转为白点的演算法则。图像经模糊算法处理后, 图像上距离相近的连通成份将会形成为一较大的连通区域。

def horizontal_blur(image): '''水平平滑''' dst=image #计算图像的字符宽度 hor_vec=np.sum(dst,axis=0) width=hor_vec.shape[0] left=right=0 for i in range(width): if hor_vec[i]!=0: left=i break for j in range(width-1,-1,-1): if hor_vec[j]!=0: right=j break char_width=right-left+1 if right-left+1>0 else 10 # 计算游程平滑阈值 thres=char_width//10 h,w=dst.shape for r in range(h): c=0 while c<w and dst[r,c]==0: c+=1 max_w=0 for i in range(w-1,-1,-1): if dst[r,i] !=0: max_w=i break start=0 end=0 flag=True for j in range(c,max_w): if flag and dst[r,j]==0: start=j flag=False if not flag and dst[r,j]!=0: end=j if end>start and end-start <= thres: k=start while k<end: dst[r,k]=255 k+=1 flag=True return dst

处理后的结果如下:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第4张

2.3、垂直投影

这个很好计算,这里不多介绍。直接看结果:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第5张

2.4、短斜线倾斜角度的统计计算

1、垂直投影测角原理

把斜体字进行抽象,
可以看成是一平行四边形。
一般地,
对于一个由黑象素组成的实心平行四边形图像

其垂直投影直方图是一梯形 。具体如下:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第6张

那么倾斜角度的计算公式为:

                             opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第7张

                            opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第8张

也就是说我们可以通过上图第二个图来计算倾斜字体的角度,而第二张图就是我们的投影曲线了。所以我们计算投影曲线的角度也就是我们的倾斜角度。

但从2.3中的
投影图可知, 首先, 水平模糊后斜体字部分并非理想的平行四边形, 其次, 模糊图中存 在多个倾斜的边和倾斜角度信息, 但由于计算误差等原因, 可能存在一些错误的倾斜角度信息, 必须对所有倾斜角度信 息进行统计分析, 才可以获得更准确的测角信息。

需要注意的是:模糊区域边界部分投影曲线形状与字符 结构有较大关系, 例如字符边界不是竖直笔画 ( 英文字母 X)或边界笔画反而会干扰倾斜角度取得的字符 ( A, W等 ), 因此并非所有短斜线的斜率都是斜体字的斜率。 一般地, 正确的折线数量大于不正确的 。基于此, 本文在设计算法时采用 投票法来获取正确角度, 即对于得到的所有角度, 通过投票获知哪个角度出现的次数最多, 该角度就是要找的倾斜角度。

2、代码实现

这里代码不多详述,因为代码是公司的,所以能不能再贴了,有需要的小伙伴可以私底下聊,我会经量帮你解决。

2.5、倾斜校正

图像中倾斜字的校正实际上就是象素坐标的空间旋转 变换。
假设倾斜字符向右扭曲
,
X
轴与水平轴重合
,
Y
轴所 指方向为字符扭曲方向。如果将字符图像水平旋转使
Y
轴 所指方向与水平轴垂直,
则校正了图像的变形

现以一倾斜 字符“


为例
,
推导空间变换公式如下:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第9张

旋转时
A
点以下的字符部分水平右移
,
以上部分水平左 移。

B
点为例
,
设旋转后的坐标值为
(
i, j), 易知水平右移 时纵坐标不变,
横坐标增加
BC, 则变换公式为
:
 
                                               
opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第10张
同理
,
左移部分变换公式为
:
 
                                               
opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第11张
然而图像中点的坐标值仍然为整数,
因此经过变换后所获得的结果必须进行取整操作,
这就存在误差
,
不可避免地造成图像失真。
本文采用双线性插值来降低取整带来的失真
,
并对校正后的二值图像进行平滑处理,
以消除插值带来的毛刺点。
 
具体实现如下:
def bilinear_interpolation(image,angle,center,y_min,y_max): '''对倾斜字体进行双线性插值''' center_x, center_y=center h,w=image.shape dst=np.zeros((h,w),dtype=np.uint8) for r in range(h): for c in range(w): #计算原图上的坐标 i = r if r<center_y: j=c+(center_y-r)/math.tan(angle) elif r>center_y: j=c-(r-center_y)/math.tan(angle) else: j=c #计算源图上的四个近邻点 x_0=max(int(np.floor(j)),0) y_0=max(int(np.floor(i)),0) x_1=min(x_0+1,w-1) y_1=min(y_0+1,h-1) #双线性插值 if (x_0 >=x_1) or (y_0>=y_1): continue value0=((x_1-j)*image[y_0,x_0]+(j-x_0)*image[y_0,x_1]) value1=((x_1-j)*image[y_1,x_0]+(j-x_0)*image[y_1,x_1]) dst[r,c]=int(((y_1-i)*value0+(i-y_0)*value1)) return dst def correct_slanted_fonts(image,mask,angle): '''倾斜字体的矫正''' h,w=mask.shape # 计算倾斜字体的中心点 center_x=0 center_y=0 num=0 for r in range(h): for c in range(w): if mask[r,c]==255: center_x+=c center_y+=r num+=1 center_x=center_x//num center_y=center_y//num #计算文本的上下边界 ver_vec=np.sum(mask,axis=1) up=0 down=0 h=ver_vec.shape[0] for i in range(h): if ver_vec[i]!=0: up=i break for i in range(h-1,-1,-1): if ver_vec[i]!=0: down=i break #对图像进行双线性插值 dst=bilinear_interpolation(image,angle,(center_x,center_y),up,down) # cv2.namedWindow("test1",0) # cv2.imshow("test1", dst) # cv2.waitKey(0) return dst

三、算法实现的最终结果

现在让我们来看看我们的需要校正的文本数据样例,部分具体样例图片如下:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第12张

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第2张opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第14张

 最终我们校正后的结果:

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第15张

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第16张

opencv 文字角度_opencv 文字识别 (https://mushiming.com/)  第17张

参考文献:

一种斜体印刷字倾斜角度检测算法

THE END

发表回复