文档旋转角度求解
小艾同学 ... 大约 2 分钟
# 文档旋转角度求解
# 模型
- 普通方差模型
- tf 加速
- 多进程加速
# 问题
# 假设/前提条件/约束
- 白底黑字,也并非就要白底,因为会被二值化,只要能分开就可以
- 横/竖文字排版
- 可以有一些图表等其他的内容
# 基于方差的方法
方差用来度量离散程度,聚集程度 这个最优的角度会使得方差最大,也即差距最大
暴力求解
设旋转角度为,在一定角度范围 内 取 个角度,遍历每个角度, 对每个角度求方差,取最大方差对应的角度即可
rotateList = np.linspace(rotateMin,rotateMax,nRotate)
maxVar = 0
bestRotate = 0
for itemRotate in rotateList:
# 旋转
itemImgBin = imgBin.rotate(itemRotate,expand=1,fillcolor=255)
# 计算该旋转角度下的图像得分
itemImgBinData = np.array(itemImgBin) # 白 True 黑 False
r,c = itemImgBinData.shape
rowCount = c - itemImgBinData.sum(axis=1) # 行
colCount = r - itemImgBinData.sum(axis=0) # 列
# 方差
rowVar = np.var(rowCount)
colVar = np.var(colCount)
var = rowVar + colVar
if var > maxVar:
maxVar = var
bestRotate = itemRotate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1、rotate 0.025s;
2、read+rotate 0.25s;
3、遍历 for 会导致耗费很长时间,个在1s。
# tf 并行
可以对角度空间内的所有角度同时并行的求方差,得到方差向量, 然后从方向向量中取到最大方差即可。
原始的图像旋转 rotate 是在一个图片上进行的,一次只能旋转一个角度,这里需要对个原始图像旋转个角度, 张量旋转,tf就是numpy在张量上的扩展
import tensorflow as tf
import tensorflow_addons as tfa
angles = tf.linspace(rotateMin, rotateMax, nRotate)*np.pi/180 # (n,) tf.float64
angles = tf.cast(angles,dtype=tf.float32) # tf.float32
images = np.array([imgBinData]*len(angles)) # n h w c
# 旋转
rotateImages = tfa.image.rotate(
images,
angles,
interpolation="nearest",
fill_mode="constant",
fill_value=1 # "fill_value is not supported and is always 0 for TensorFlow < 2.4.0."
) # (n,h w c) float64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
个并行,在40核16G的机器上是 1-1.5s
# 多进程并行
tf 只是利用了多核,但性能还是不太够。直接使用 python 开多进程并行,使用多进程求解
个并行,在40核16G的机器上是 0.5s
单张 是 0.28(算读取)
单张 是 0.028(不算读取)
这里是求,理论上将,在资源足够的时候,这种多进程求解时间是与 无关的。
但随着 的增加,求解时间是会边长的
- 在 0.1s
- 在 0.2-0.3s
- 在 0.5s 左右