Loading...
首页专栏正文

在树莓派上用谷歌Tesseract和Arm NN创造一个文本转语言的工具

 
1人已赏
恬静的小魔龙 发布于 2020-12-17 17:13:14 浏览 6260 点赞 73 收藏 5

导言

在本文中,我们将讲解一种基于Raspberry PI(树莓派,一种微计算机系统)的Tesseract和ARM NN文本转语音解决方案。

我们将主要使用现成的组件和模型,但将侧重于理解将模型从TensorFlow转换为ARM NN的过程,例如选择一个与ARM NN工作良好的模型。

我们还将介绍一些创建ARM NN驱动的方案。

文本转语音(TTS)工具,旨在创建基于嵌入式设备的人与机器之间的自然交互。例如,嵌入式设备可以帮助视力受损的人阅读标识、字母和文档。更具体地说,设备可以使用光学字符识别来让用户知道它在图像中看到了什么。

TTS应用程序已经在桌面计算机上很常见了,并且在大多数现代智能手机和移动设备中很常见。可以在系统的可访问性工具中找到这些应用程序,比如屏幕阅读器、自定义警报等。

通常情况下,这些系统从某种机器可读的文本开始。如果您没有现有的文档、浏览器或应用程序文本源怎么办?光学字符识别(OCR)软件可以将扫描图像转换为文本,但在TTS应用程序中,这些是符号活着单个字符。OCR软件本身只关心准确地返回数字和字母。

为了实现准确的实时文本检测,将字形集合识别为可以说话的单词,我们可以求助于深入学习人工智能技术。在这种情况下,我们可以使用递归神经网络(Rnn)识别OCR捕获文本中的单词。如果我们能在嵌入式设备上做到这一点,甚至比智能手机都更轻、更便携呢?

这种轻量级的、功能强大的tts设备可以帮助视力受损的人,还可以嵌入用于识字或故事时间应用的防儿童设备,等等。

在本文中,我将向您展示如何使用TensorFlow、OpenCV、Festival和Raspberry PI来实现这一功能。我将使用TensorFlow机器学习平台和一个预先培训的Keras-OCR模型来执行OCR。OpenCV将用于从网络摄像机中获取图像。最后,将语音合成系统作为TTS模块。然后,所有的东西都将被组合起来,为Raspberry PI构建Python应用程序。

在此过程中,我将告诉您典型的OCR模型是如何工作的,以及如何使用TensorFlow Lite进一步优化解决方案,TensorFlow Lite是一组工具,用于在受约束的环境(如嵌入式和物联网设备)上运行优化的TensorFlow模型。

开始

首先,要为本教程创建设备和应用程序,您将需要一个Raspberry PI。版本2、3或4都适用于此示例。您还可以使用您的开发PC(我们用Python3.7测试了代码)。

您需要安装两个软件包:TensorFlow(2.1.0)和keras_OCR(0.7.1)。以下是一些链接:

基于递归神经网络的OCR

在这里,我使用的是角化OCR用于识别图像中文本的包。此软件包基于TensorFlow和卷积神经网络,最初在Keras网站上作为OCR实例。

网络体系结构可分为三个重要步骤。第一个是输入图像,然后使用几个卷积层提取特征。这些层水平地划分输入图像。对于每个分区,这些层确定图像列特征集。在第二步中,由递归层使用列特征序列。

这个递归神经网络(Recurrent_neural_network,RNN)通常由长期短期记忆(LTSM)层。LTSM革新了许多人工智能应用,包括语音识别、图像字幕和时间序列分析,OCR模型使用RNNS创建所谓的字符概率矩阵,此矩阵指定在输入图像的特定分区中找到给定字符的可信度。

因此,最后一步使用此矩阵从图像中解码文本。通常,可以使用连接性时间分类(Ctc)算法。这种转换不是一项简单的任务,因为可以在相邻的图像分区中找到相同的字符。另外,一些输入分区可能没有任何字符。

尽管基于RNN的OCR系统是有效的,但是当尝试在项目中采用它时,您可以发现许多个问题。理想情况下,您可能希望执行转换,学习如何根据数据调整模型。然后将模型转换为TensorFlow Lite格式,以便为边缘设备上的推理进行优化。这种方法在移动计算机视觉应用中是成功的。例如,许多MobileNet预先培训的网络在移动设备和物联网设备上进行有效的图像分类。

但是,TensorFlow Lite是TensorFlow的一个子集,因此目前并不支持所有的操作。当您想要执行OCR时,这种不兼容性就成了一个问题,就像在物联网设备上的keras-OCR包中包含的那样。

在本文中,我将展示如何使用TensorFlow模型,因为TensorFlow Lite还不支持双向LSTM层(用于Keras-OCR)。

预训练OCR模型

首先,我编写了一个测试脚本,tu.py,它展示了如何使用keras-ocr中的神经网络模型:

# Imports
import keras_ocr
import helpers

# Prepare OCR recognizer
recognizer = keras_ocr.recognition.Recognizer()

# Load images and their labels
dataset_folder = 'Dataset'
image_file_filter = '*.jpg'

images_with_labels = helpers.load_images_from_folder(
    dataset_folder, image_file_filter)

# Perform OCR recognition on the input images
predicted_labels = []
for image_with_label in images_with_labels:
    predicted_labels.append(recognizer.recognize(image_with_label[0]))

# Display results
rows = 4
cols = 2
font_size = 14
helpers.plot_results(images_with_labels, predicted_labels, rows, cols, font_size)

此脚本从keras_格拉希识别模块实例化Recognizer对象。然后,脚本从附带的测试数据集(DataSet文件夹)加载图像及其标签。此数据集包含了合成词集(Synth 90k),然后从脚本在数据集中的每一幅图像上运行OCR识别,然后显示预测结果。

为了加载图像及其标签,我使用了我在Helpers模块中实现的LOAD_TOMES_FROM_FILDER函数。此方法需要两个参数:带图像的文件夹的路径和过滤器。在这里,我假设图像位于DataSet子文件夹下,并以jpeg格式读取所有图像(.jpg扩展)。

在Synth90k数据集中,每个图像文件名都包含其下划线之间的标签。例如:199_pulpiest_61190.jpg。因此,要获得图像标签,LOAD_RAMES_FROM_FILDER函数将文件名拆分为下划线,然后接受得到的字符串集合的第一个元素。另外,请注意LOAD_HOMES_FROM_FILDER函数返回一个元组数组。数组的每个元素都包含图像和相应的标签。因此,我只将这个元组的第一个元素传递给OCR引擎。

要执行识别,我使用Recognizer对象的识别方法。此方法返回预测的标签。我将后者存储在“预测的标签”集合中。

最后,我将预测的标签、图像和原始标签的集合传递给另一个助手函数,它在大小行x列的矩形网格中显示图像。您可以通过修改相应的变量来更改网格外观。

照相机

在测试了OCR模型之后,我实现了相机类。该类使用OpenCV的keras-OCR模块。OpenCV提供了一个方便的编程接口来访问相机,显示图片。首先初始化VideoCapture对象,然后调用其读取方法从摄像机获取图像:

import cv2 as opencv

class camera(object):
    def __init__(self):
        # Initialize the camera capture
        self.camera_capture = opencv.VideoCapture(0)

    def capture_frame(self, ignore_first_frame):
        # Get frame, ignore the first one if needed
        if(ignore_first_frame):
            self.camera_capture.read()

        (capture_status, current_camera_frame) = self.camera_capture.read()

        # Verify capture status
        if(capture_status):
            return current_camera_frame

        else:
            # Print error to the console
            print('Capture error')

在这段代码中,我在摄像机类的初始化器中创建了VideoCapture。我将值0传递给VideoCapture指向默认系统的摄像机。然后,我将生成的对象存储在照相机类的Camera_Capture字段中。

为了从摄像机中获取图像,我实现了Capture_Frame方法。它有一个额外的参数,ignore_first_frame。当这个参数是True,引用camera_capture.read两次,但我忽略了第一次调用的结果。这个操作的基本原理是,由我的相机返回的第一帧通常是空白的。

对Read方法的第二次调用将给出捕获状态和帧。如果capture_statusTrue,获取摄像机框。否则,打印“捕获错误”字符串。

文本到言语

应用程序的最后一个元素是TTS模块。我决定在这里使用Festival,因为它可以离线工作。

要在Raspberry PI上安装节日,请调用以下命令:

sudo apt-get install festival -y

您可以通过键入:

echo "Hello, Arm" | Festival –tts

你的树莓派应该说“Hello, Arm”

节日提供了一个API。然而,为了保持简单,我决定通过命令行来界面Festival。为此,我用另一种方法扩展了Helpers模块:

def say_text(text):
    os.system('echo ' + text + ' | festival --tts')

把东西放在一起

最后,我们可以把所有的东西放在一起。我是在Main.py:

import keras_ocr
import camera as cam
import helpers

if __name__ == "__main__":
    # Prepare recognizer
    recognizer = keras_ocr.recognition.Recognizer()

    # Get image from the camera
    camera = cam.camera()

    # Ignore the first frame, which is typically blank on my machine
    image = camera.capture_frame(True)

    # Perform recognition
    label = recognizer.recognize(image)

    # Perform TTS (speak label)
    helpers.say_text('The recognition result is: ' + label)

首先,我创建了OCR识别器。然后,我创建相机对象并从默认的摄像头读取帧。该图像被传递给识别器的识别方法,并通过TTS助手发出结果标签。

总结

总之,我们创建了一个可靠的系统,可以通过深入学习执行ocr,然后通过文本到语音引擎将结果传递给用户。我们用了一个预先训练过的角光机包。

在更高级的场景中,文本识别可以先进行文本检测。首先检测图像中的文本行,然后对每一行文本执行识别。

通过将上面的应用程序扩展到文本检测,您可以实现RNN支持的物联网系统,该系统执行OCR,帮助视力受损的人阅读餐馆的菜单或政府办公室的文件。此外,这样一个应用程序,如果得到翻译服务的支持,可以充当自动翻译。

他强任他强,清风拂山岗

*本文仅代表作者观点,不代表易百纳技术社区立场。系作者授权易百纳技术社区发表,未经许可不得转载。

精彩评论

内容存在敏感词
打赏
打赏作者
恬静的小魔龙
您的支持将鼓励我继续创作!
金额:
¥1 ¥5 ¥10 ¥50 ¥100
支付方式:
微信支付
支付宝支付
微信支付
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区