前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于OpenVIO实现日文手写体OCR

基于OpenVIO实现日文手写体OCR

原创
作者头像
IT蜗壳-Tango
发布2024-07-05 19:14:35
28000
代码可运行
发布2024-07-05 19:14:35
举报
文章被收录于专栏:OpenVINOOpenVINO
运行总次数:0
代码可运行

前期准备

安装好conda和jupyterlb(为后期训练其他模型做准备)

  1. conda做虚拟环境很方便,尤其涉及到需要切换不同版本Pyhon时
  2. jupyterlab后期训练和稍后的代码,用来查看中途运行结果很方便的

创建虚拟环境

image-20240705170244003
image-20240705170244003

正常情况下我们这里是只能看到默认的环境,为了不影响其他项目的环境,我们通常需要创建一个新的虚拟环境来和其他项目做隔离。

我们在新打开的notebook中输入以下命令创建一个名为ov的虚拟环境

代码语言:bash
复制
!conda create -n ov ipykernel -y

注意,在notebook中执行命令行通常需要在前面多加一个感叹号。

image-20240705171538107
image-20240705171538107

看到上图表面我们已经创建好了虚拟环境,但是这时我们在notebook中还是没有办法选择和使用的。

激活虚拟环境

代码语言:bash
复制
!conda activate ov

将我们的虚拟化环境添加到notebook中,为了区别,我让它的显示名为ov_env

代码语言:bash
复制
!python -m ipykernel install --name ov --display-name ov_env
image-20240705171902825
image-20240705171902825

我们再次选择环境,可以看到ov_env已经添加好了。

image-20240705172036651
image-20240705172036651

我们选择这个新建的虚拟环境,然后正式开始我们的OCR实践。

OpenVINO环境准备

我们这里使用的时windows环境,如果你是其他操作系统,个别的库可能需要更换一下版本

代码语言:bash
复制
%pip install -q "openvino>=2023.1.0" "matplotlib>=3.4" opencv-python tqdm -i https://pypi.tuna.tsinghua.edu.cn/simple
image-20240705172821775
image-20240705172821775

引入必要的库

代码语言:python
代码运行次数:0
复制
from collections import namedtuple
from itertools import groupby

import cv2
import matplotlib.pyplot as plt
import numpy as np
import openvino as ov

# Fetch `notebook_utils` module
import requests

r = requests.get(
    url="https://raw.githubusercontent.com/openvinotoolkit/openvino_notebooks/latest/utils/notebook_utils.py",
)

open("notebook_utils.py", "w").write(r.text)
from notebook_utils import download_file
image-20240705173029465
image-20240705173029465

执行完成之后,我们会在项目的根目录下看到一个notebook_utils.py文件

image-20240705173228487
image-20240705173228487

设置必要文件路径以及模型信息

代码语言:python
代码运行次数:0
复制
# Directories where data will be placed.
base_models_dir = "models"
data_folder = "data"
charlist_folder = f"{data_folder}/text"

# Precision used by the model.
precision = "FP16"
Language = namedtuple(typename="Language", field_names=["model_name", "charlist_name", "demo_image_name"])
japanese_files = Language(
    model_name="handwritten-japanese-recognition-0001",
    charlist_name="japanese_charlist.txt",
    demo_image_name="handwritten_japanese_test.png",
)
image-20240705173551354
image-20240705173551354

模型下载

代码语言:bash
复制
path_to_model = download_file(
    url=f"https://storage.openvinotoolkit.org/repositories/open_model_zoo/2023.0/models_bin/1/{japanese_files.model_name}/{precision}/{japanese_files.model_name}.xml",
    directory=base_models_dir,
)
_ = download_file(
    url=f"https://storage.openvinotoolkit.org/repositories/open_model_zoo/2023.0/models_bin/1/{japanese_files.model_name}/{precision}/{japanese_files.model_name}.bin",
    directory=base_models_dir,
)
image-20240705174739629
image-20240705174739629

执行完成后,会在根目录下生成一个文件夹,里面包含了模型以及权重文件

image-20240705174850958
image-20240705174850958

加载模型并选择推理设备

代码语言:python
代码运行次数:0
复制
core = ov.Core()
model = core.read_model(model=path_to_model)
import ipywidgets as widgets

device = widgets.Dropdown(
    options=core.available_devices + ["AUTO"],
    value="AUTO",
    description="Device:",
    disabled=False,
)
compiled_model = core.compile_model(model=model, device_name=device.value)
image-20240705175234476
image-20240705175234476

我这里选择让它自动选择,现在模型已经加载,获取有关输入和输出层(形状)的信息。

代码语言:python
代码运行次数:0
复制
recognition_output_layer = compiled_model.output(0)
recognition_input_layer = compiled_model.input(0)

接下来,加载一个图像。该模型需要一个单通道图像作为输入,因此图像是以灰度级读取的。

加载输入图像后,获取用于计算所需输入层高度与当前图像高度之间的比例的信息。在下面的代码中,图像将被调整大小并填充,以保持字母成比例并符合输入形状。

代码语言:python
代码运行次数:0
复制
# 这里使用的是openvino的示例图片
file_name = download_file(
    "https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/image/" + japanese_files.demo_image_name,
    directory=data_folder,
)

# 这个模型,一次只能读取一行文字
image = cv2.imread(filename=str(file_name), flags=cv2.IMREAD_GRAYSCALE)
image_height, _ = image.shape
_, _, H, W = recognition_input_layer.shape
scale_ratio = H / image_height
resized_image = cv2.resize(image, None, fx=scale_ratio, fy=scale_ratio, interpolation=cv2.INTER_AREA)
resized_image = np.pad(resized_image, ((0, 0), (0, W - resized_image.shape[1])), mode="edge")
input_image = resized_image[None, None, :, :]

这时,在根目录下会生成一个data文件夹,里面保存的是示例图片

image-20240705180224657
image-20240705180224657

我们也可以通过以下代码在notebook中查看这张图片

代码语言:python
代码运行次数:0
复制
plt.figure(figsize=(20, 1))
plt.axis("off")
plt.imshow(resized_image, cmap="gray", vmin=0, vmax=255)
image-20240705180443866
image-20240705180443866

模型已加载,图像已准备就绪。剩下的唯一元素是下载的charlist。在使用之前,您必须在charlister的开头添加一个空白符号。

代码语言:python
代码运行次数:0
复制
used_charlist_file = download_file(
    "https://storage.openvinotoolkit.org/repositories/openvino_notebooks/data/data/text/" + japanese_files.charlist_name,
    directory=charlist_folder,
)
used_charlist = japanese_files.charlist_name

blank_char = "~"

with used_charlist_file.open(mode="r", encoding="utf-8") as charlist:
    letters = blank_char + "".join(line.strip() for line in charlist)
image-20240705181233246
image-20240705181233246

上面代码运行好之后,会在data/text目录下生成一个txt文件,里面保存的是一些日文

image-20240705180757408
image-20240705180757408

推理

现在,运行推理。compiled_model()函数以与模型输入相同的顺序获取一个包含输入的列表。然后,从输出张量中获取输出。

代码语言:python
代码运行次数:0
复制
predictions = compiled_model([input_image])[recognition_output_layer]
predictions = np.squeeze(predictions)
predictions_indexes = np.argmax(predictions, axis=1)

output_text_indexes = list(groupby(predictions_indexes))
output_text_indexes, _ = np.transpose(output_text_indexes, (1, 0))
output_text_indexes = output_text_indexes[output_text_indexes != 0]
output_text = [letters[letter_index] for letter_index in output_text_indexes]

模型的输出为W x B x L格式,其中:

W:输出序列长度

B:批大小

L:Kondate和Nakayosi中支持符号的置信度分布

要获得更易于阅读的格式,请选择概率最高的符号。当持有预测具有最高概率的索引列表时,由于CTC解码的限制,将删除并发符号,然后删除空白。

最后,在charlist中从相应的索引中获取符号。

输出结果

代码语言:python
代码运行次数:0
复制
plt.figure(figsize=(20, 1))
plt.axis("off")
plt.imshow(resized_image, cmap="gray", vmin=0, vmax=255)

print("".join(output_text))
image-20240705182423351
image-20240705182423351

我们可以看到正确识别出来了。

最后我们使用自己写的来测试一下,一起来感受一下来自"佩恩"的压迫感....

image-20240705190240793
image-20240705190240793
image-20240705190338132
image-20240705190338132

总结

使用OpenVINO来加载预训练的模型进行日文手写体的识别在速度上是飞快的,尤其是在没有GPU的情况下,另外一个好处我们可以基于预训练的模型进行二次训练,使其达到我们想要的效果,目前现有的这个模型的识别率还是不是很高,后面有时间和大家再介绍一下如何进行微调。


我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前期准备
  • 创建虚拟环境
  • OpenVINO环境准备
    • 引入必要的库
      • 设置必要文件路径以及模型信息
      • 模型下载
      • 加载模型并选择推理设备
      • 推理
      • 输出结果
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档