学习笔记|文字识别之cnocr(一)
前几天分享了ddddocr热点复现|验证码识别,但发现这个包没有提供个性化训练接口,底层又是用C++写的,作为一名只懂python的伪算法工程师,止步应用不甘心,修改底层没能力,只好另请高明,于是找到了cnocr。
1. cnocr预训练模型试用
首先安装cnocr。
!pip install cnocr
开源贡献者提供了预训练模型,我们将对预训练模型的效果进行一些验证。
from cnocr import CnOcr
ocr = CnOcr()
res = ocr.ocr('images/t1.jpg')
p = plt.imread('images/t1.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t2.jpg')
p = plt.imread('images/t2.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t3.jpg')
p = plt.imread('images/t3.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t4.jpg')
p = plt.imread('images/t4.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t5.jpg')
p = plt.imread('images/t5.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t6.jpg')
p = plt.imread('images/t6.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t7.jpg')
p = plt.imread('images/t7.jpg')
plt.imshow(p)
print(res)
显然,cnocr对验证码的识别率远不如ddddocr(ddddocr试用见热点复现|验证码识别),那么对于标准的文字呢?
res = ocr.ocr('images/t12.jpg')
p = plt.imread('images/t12.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t17.jpg')
p = plt.imread('images/t17.jpg')
plt.imshow(p)
print(res)
res = ocr.ocr('images/t20.jpg')
p = plt.imread('images/t20.jpg')
plt.imshow(p)
print(res)
可以看到,cnocr对标准文字的识别率还是可以的。那么它对于其他不同字体的支持率如何呢?我们随便准备了几个微软雅黑字体。
res = ocr.ocr('images/t23.jpg')
p = plt.imread('images/t23.jpg')
plt.imshow(p)
print(res)
发现效果并不是很好。
总的来说,cnocr自带预训练模型的准确率不及ddddocr,cnocr的运行效率也明显不如ddddocr,但cnocr提供了个性化训练的方法,并且cnocr完全是用python实现的,我们试图通过自定义训练来提高cnocr对微软雅黑字体的识别率。
2. 个性化训练尝试
2.1. 个性化训练必须clone cnocr项目。
!git clone https://gitee.com/cyahua/cnocr.git
2.2. 准备训练样本。
由于水平有限,不会有服务器上生成微软雅黑字体,我们在windows上准备训练需要的样本。
2.2.1. 在cnocr下新建文件夹datasets。
2.2.2. 在datasets文件夹下再新建文件夹dataset2_002。
2.2.3. 在dataset2_002文件夹下新建test.txt文件,将我们刚刚打的那行字分成两行,加上.jpg(如下图)。
2.2.4. 在dataset_002文件夹下新建train.txt文件,将我们刚刚那行字打乱后加上.jpg,写成三行(如下图)。
2.2.5. 将test.txt和train.txt里的文字转化为微软雅黑字体的图片,同时生成每个字在字表中的位置。
2.2.5.1. 从windows里找到微软雅黑字体,一般在C:\Windows\Fonts文件夹下,将msyh.ttc复制到datasets文件夹下面。
2.2.5.2. 在cnocr项目下的examples文件夹下找到label_cn.txt,将其复制到datasets下面。
2.2.5.3. 在datasets文件夹下新建data_generator.py文件,代码如下:
import os
import pygame
pygame.init()
font = pygame.font.Font('msyh.ttc', 64)
def writing(txt, pth):
r_txt = font.render(txt, True, (0, 0, 0), (255, 255, 255))
pygame.image.save(r_txt, os.path.join(pth, txt+'.jpg'))
def indexing(txt):
res = []
for i in range(len(txt)):
try:
res.append(standards.index(txt[i]+'\n')+1)
except:
new_chrs.append(txt[i])
res.append(len(standards)+len(new_chrs)+1)
return res
if __name__ == '__main__':
pth = 'self_dataset_002'
f_tr = open(os.path.join(pth, 'train.txt'), encoding='utf-8-sig')
f_ts = open(os.path.join(pth, 'test.txt'), encoding='utf-8-sig')
f_st = open('label_cn.txt', 'r', encoding='utf-8-sig')
f_tr2 = open(os.path.join(pth, 'train2.txt'), 'w', encoding='utf-8-sig')
f_ts2 = open(os.path.join(pth, 'test2.txt'), 'w', encoding='utf-8-sig')
train_items = f_tr.readlines()
test_items = f_ts.readlines()
standards = f_st.readlines()
new_chrs = []
f_tr.close()
f_ts.close()
f_st.close()
for i in range(len(train_items)):
txt = train_items[i].split(".")[0]
idxes = indexing(txt)
img = writing(txt, pth)
cnt = "train_%06d.jpg" % i
os.rename(os.path.join(pth, txt + '.jpg'), os.path.join(pth, cnt))
for idx in idxes:
cnt = cnt + " {}".format(idx)
f_tr2.write(cnt + '\n')
for i in range(len(test_items)):
txt = test_items[i].split(".")[0]
idxes = indexing(txt)
img = writing(txt, pth)
cnt = "test_%06d.jpg" % i
os.rename(os.path.join(pth, txt + '.jpg'), os.path.join(pth, cnt))
for idx in idxes:
cnt = cnt + " {}".format(idx)
f_ts2.write(cnt + '\n')
fh = open('label_cn.txt', 'a', encoding='utf-8-sig')
for nw in new_chrs:
fh.write(nw + '\n')
fh.close()
上面的样本准备过程参考了萧班的博客,代码基本来自于该博客,局部有所调整。由于代码比较长,此处不再具体解释,在此感谢萧班CNOCR重训练_WinerChopin的博客-CSDN博客_cnocr训练。
2.2.5.4. 运行以上代码。在运行以上代码后可以将test.txt和train.txt下的XXX.jpg分别生成微软雅黑字体的文字图片(见下图)
同时生成test2.txt和train2.txt,生成每个字在字表中的位置(见下图)。
2.2.6. 生成.lst文件。在项目下运行如下代码
python scripts/im2rec.py --list --num-label 20 --chunks 1 --train-idx-fp ./datasets/dataset_002/train2.txt --test-idx-fp ./datasets/dataset_002/test2.txt --prefix ./datasets/dataset_002/d002
生成d002_test.lst和d002_train.lst(见下图)
2.2.7. 生成.rec文件。在项目下运行如下代码
python scripts/im2rec.py --pack-label --color 1 --num-thread 1 --prefix ./datasets/dataset_002/d002 --root ./datasets/dataset_002
生成d002_test.rec和d002_train.rec(见下图)
至此,样本准备完成。
2.3. 个性化训练
运行以下代码
python scripts/cnocr_train.py --gpu 0 --emb_model_type "densenet-lite" --seq_model_type "fc" --optimizer adam --epoch 20 --lr 1e-4 --train_file ./datasets/dataset_002/d002_train --test_file ./datasets/dataset_002/d002_test
可以看到20次训练结果并不是很理想
实际识别结果也说明了同样的问题,20epoch训练的结果完全无效
问题是一模一样地再训练一次,得到的结果却并不一样:
为什么会这样呢?我也还没来得及深入分析原因。如果同学们有知道原因的,或者有做OCR个性化训练更好的方法,欢迎留言。
- 点赞
- 收藏
- 关注作者
评论(0)