机器视觉是当今非常热门的话题。 为了解决使用神经网络识别商店标签的问题,我们选择了TensorFlow框架。
本文将确切讨论如何使用它来定位和识别同一商店价格标签上的多个对象,以及如何识别其内容。
哈布雷使用OpenCV库中提供的经典图像处理工具
已经解决了识别宜家价格标签的类似任务 。
另外,我想指出,该解决方案既可以在结合Tensorflow Serving的SAP HANA平台上运行,也可以在SAP Cloud Platform上运行。
识别商品价格的任务与想要彼此“摸索”价格并选择要购买商品的商店的买家以及零售商有关-他们想实时了解竞争对手的价格。
足够的歌词-使用技巧!
工具包对于图像的检测和分类,我们使用了在TensorFlow库中实现的卷积神经网络,并可通过对象检测API进行控制。
TensorFlow对象检测API是基于TensorFlow的开源元框架,可简化对象检测模型的创建,训练和部署。
在检测到所需对象之后,使用Tesseract(用于字符识别的库)对文本进行识别。 自2006年以来,Tesseract被认为是开源中可用的最准确的OCR库之一。
您可能会问一个问题-为什么不是所有处理都在TF上完成? 答案很简单-实施需要花费大量时间,但是反正没有很多。 牺牲加工速度和组装完成的原型要比打扰自制的OCR更容易。
创建和准备数据集首先,有必要收集工作材料。 我们参观了3家商店,并以自动模式在手机相机上拍摄了约400张不同价格标签的照片
样本照片:
图 1.价格标签图片示例
图 2.价签图片示例之后,您需要处理并标记价格标签的所有照片。 在收集图像的过程中,我们尝试收集高质量的图像(没有伪像):近似相同格式的价格标签,没有模糊,明显的旋转等。 这样做是为了便于进一步比较实际价格标签上的内容及其数字图像。 但是,如果仅在可用的高质量图像上训练神经网络,则很自然地会导致以下事实:该模型识别失真示例的信心将大大下降。 为了训练神经网络对这种情况有抵抗力,我们使用了众所周知的程序来扩展带有失真版本的图像的训练集(增强)。 为了补充训练样本,我们使用了Imgaug库中的算法:偏移,小转弯,高斯模糊,噪声。 将扭曲的图像添加到样本中,使样本增加了大约5倍(从300到1,500图像)。
为了标记图像和选择对象,使用了LabelImg程序,该程序在公共领域中可用。 它允许您选择带有矩形的图像中的必要对象,并将每个类分配给边界框。 为每张照片创建的帧的所有坐标和标签都保存在单独的XML文件中。
每张照片上都突出了以下对象:产品价格标签,产品价格,产品名称和价格标签上的产品条形码。 在某些逻辑上合理的图像示例中,区域标记为重叠。
图 3.在LabelImg中标记的一对价格标签的照片示例。 带有产品说明,价格和条形码的区域将突出显示。
图 4.在LabelImg中标记的价格标签照片的示例。 带有产品说明,价格和条形码的区域将突出显示。在对所有照片进行处理和标记后,我们准备将所有照片和标记文件分离为训练和测试样本的数据集。 通常将80%的训练样本与20%的测试样本混合在一起。
接下来,在将要训练模型的机器上,必须安装所有必需的库。 首先,我们安装TensorFlow机器学习库。 根据系统类型的不同,您需要安装其他库以在GPU上进行计算。 接下来,安装Tensorflow对象检测API库和其他用于处理图像和图形的库。 以下是我们在工作中使用的库的列表:
TensorFlow-GPU v1.5,CUDA v9.0,cuDNN v7.0
Protobuf 3 +,Python-tk,Pillow 1.0,lxml,tf Slim,Jupyter笔记本,Matplotlib
Tensorflow,Cython,Cocoapi; OpenCV的Python; 大熊猫完成所有安装步骤后,您可以继续准备数据并设置学习参数。
模型训练为了解决我们的问题,我们在可可数据集上使用了两个版本的预训练神经网络MobileNet V2和Faster-RCNN V2作为图像属性提取器。 将模型重新训练为4个新类别:价格标签,产品描述,价格,条形码。 作为主要选择,我们选择了MobileNet V2,它是一个相对简单的模型,它使我们能够以令人满意的速度提供可接受的质量。 MobileNet V2允许您甚至在移动设备上实现图像识别。
首先,您需要告诉Tensorflow对象检测API库标签的数量以及这些标签的名称。
培训之前的最后一件事是创建快捷方式映射并编辑配置文件。 标签图通知模型,并将类名称映射到每个对象的类标识符编号。

最后,您需要配置用于对象检测的学习源,以确定将用于训练的模型和参数。 这是开始训练之前的最后一步。

训练过程由以下命令启动:
python train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/mobilenet.config
如果一切配置正确,TensorFlow将初始化神经网络的重新训练。 实际训练开始之前,初始化过程可能最多需要30秒。 在每个步骤都对神经网络进行重新训练时,将显示算法误差函数(损失)的值。 对于MobileNet V2,损失函数的初始值大约为20。应该训练模型,直到损失函数下降到大约2的值。要可视化神经网络的学习过程,可以使用方便的TensorBoard实用程序。
: tensorboard
该命令将初始化本地计算机上的Web界面,该界面可在localhost:6006上使用。 停止后,以后可以使用每5分钟保存一次的检查点来恢复训练过程。
识别价格标签及其要素训练完成后,最后一步是创建神经网络图。 这是通过console命令完成的,其中必须在星号下指定培训目录中存在的最大数量的cpkt文件。
python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/faster_rcnn_inception_v2.config --trained_checkpoint_prefix training/model.ckpt-**** --output_directory inference_graph
完成此过程后,即可进行对象检测分类器的操作。 要检查图像识别,只需运行Tensorflow Object Detection库随附的脚本即可,该脚本指示先前经过训练的模型以及用于识别的照片。
这里提供
了一个标准的Python脚本示例。
在我们的示例中,在简单的笔记本电脑上使用ssd mobilenet模型识别一张照片大约需要1.5秒。
图 5.测试样品中带有价格标签的图像的识别结果
图 6.测试样品中带有价格标签的图像的识别结果当我们确信可以正常检测到价格标签时,有必要教该模型从各个要素中读取信息:商品价格,商品名称和条形码。 为此,有可用的Python库来识别照片中的字符和条形码-Pyzbar和Tesseract。
在开始识别照片中的字符和条形码之前,您需要将此照片切成我们需要的元素-为了提高速度并且不识别价格标签中未包含的不必要信息。 还必须“拉出”模型识别的对象及其类的坐标。

然后,我们使用这些坐标将照片切成仅识别必要区域的部分。


图 7.价格标签突出显示的示例接下来,我们将所有剪切区域转移到库中:将产品名称和产品价格转移到tesseract,将条形码转移到pyzbar,然后得到识别结果。

图 8.识别内容的一个例子是价格标签区域。此时,如果原始图像分辨率低或模糊,则文本和条形码识别可能会引起问题。 如果由于价格标签上的数字较大而可以正常识别价格,则产品名称和条形码定义不明确或根本没有定义。 为此,建议不要使用小照片进行识别,并且建议上传没有噪点和强烈失真的图像-例如,在没有适当聚焦的情况下。
不良图像识别示例:



图 9.价格标签和识别内容模糊的高亮部分示例在此示例中,您可以看到,如果以劣质图像或多或少正确地识别了商品的价格,则库将无法处理商品的名称。 并且条形码根本不被识别。
同样的文字质量很好。

图 10.突出显示的价格标签零件和公认内容的示例结论最后,我们设法获得了质量可以接受的模型,该模型具有较低的错误率和较高的相关对象检测率。 更快的RCNN Inception V2具有比MobileNet SSD V2更好的识别质量,但是速度差一个数量级,这是一个很大的限制。
在50张图像的延迟样本上获得的价格标签识别准确性为100%,也就是说,所有照片中的所有价格标签均已成功识别。 带条形码和价格的区域的识别精度为90%。 文本区域的识别精度为85%。 价格阅读的准确性约为95%,文本为80-85%。 此外,作为实验,我们展示了价格标签识别的结果,它与训练样本中的价格标签完全不同。
图 11.识别不在训练集中的非典型价格标签的示例。如您所见,即使价格标签与训练价格标签明显不同,模型也不是没有错误,而是可以在价格标签上识别出重要的对象。
还有什么可以做的?1)最近发布了一篇有关自动增强的很酷的文章,可以使用其方法
2)可以并且应该充分压缩完成的训练模型
3)在SCP和TFS中发布完成的服务的示例
在准备原型和本文时,使用了以下材料:1.
通过SAP HANA将机器学习(TensorFlow)引入企业2.
SAP Leonardo ML Foundation-自带模型(BYOM)3.
TensorFlow对象检测GitHub存储库4.
宜家支票识别条款5.
关于MobileNet的好处的文章6.
TensorFlow对象检测文章该文章的编写者:
Sergey Abdurakipov,Dmitry Buslov,Alexey Khristenko