安装好conda和jupyterlb(为后期训练其他模型做准备)
正常情况下我们这里是只能看到默认的环境,为了不影响其他项目的环境,我们通常需要创建一个新的虚拟环境来和其他项目做隔离。
我们在新打开的notebook中输入以下命令创建一个名为ov
的虚拟环境
!conda create -n ov ipykernel -y
注意,在notebook中执行命令行通常需要在前面多加一个感叹号。
看到上图表面我们已经创建好了虚拟环境,但是这时我们在notebook中还是没有办法选择和使用的。
激活虚拟环境
!conda activate ov
将我们的虚拟化环境添加到notebook中,为了区别,我让它的显示名为ov_env
!python -m ipykernel install --name ov --display-name ov_env
我们再次选择环境,可以看到ov_env
已经添加好了。
我们选择这个新建的虚拟环境,然后正式开始我们的OCR实践。
我们这里使用的时windows
环境,如果你是其他操作系统,个别的库可能需要更换一下版本
%pip install -q "openvino>=2023.1.0" "matplotlib>=3.4" opencv-python tqdm -i https://pypi.tuna.tsinghua.edu.cn/simple
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
执行完成之后,我们会在项目的根目录下看到一个notebook_utils.py
文件
# 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",
)
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,
)
执行完成后,会在根目录下生成一个文件夹,里面包含了模型以及权重文件
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)
我这里选择让它自动选择,现在模型已经加载,获取有关输入和输出层(形状)的信息。
recognition_output_layer = compiled_model.output(0)
recognition_input_layer = compiled_model.input(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文件夹,里面保存的是示例图片
我们也可以通过以下代码在notebook中查看这张图片
plt.figure(figsize=(20, 1))
plt.axis("off")
plt.imshow(resized_image, cmap="gray", vmin=0, vmax=255)
模型已加载,图像已准备就绪。剩下的唯一元素是下载的charlist。在使用之前,您必须在charlister的开头添加一个空白符号。
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)
上面代码运行好之后,会在data/text目录下生成一个txt文件,里面保存的是一些日文
现在,运行推理。compiled_model()
函数以与模型输入相同的顺序获取一个包含输入的列表。然后,从输出张量中获取输出。
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中从相应的索引中获取符号。
plt.figure(figsize=(20, 1))
plt.axis("off")
plt.imshow(resized_image, cmap="gray", vmin=0, vmax=255)
print("".join(output_text))
我们可以看到正确识别出来了。
最后我们使用自己写的来测试一下,一起来感受一下来自"佩恩"的压迫感....
使用OpenVINO来加载预训练的模型进行日文手写体的识别在速度上是飞快的,尤其是在没有GPU的情况下,另外一个好处我们可以基于预训练的模型进行二次训练,使其达到我们想要的效果,目前现有的这个模型的识别率还是不是很高,后面有时间和大家再介绍一下如何进行微调。
我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。