0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

探索OpenVINO™ 手写字符使用方法

英特尔物联网 来源:英特尔物联网 作者:英特尔物联网 2021-07-28 09:23 次阅读

引言

手写数字识别是一个很基础的模式识别问题,从传统特征提取加机器学习训练方法到深度神经网络训练的识别方法识别都会达到比较高的精度,同时手写数字识别也是一个特别不稳定,很难具备普适性的模型,需要针对性的数据集与训练,然后才得到比较好的识别精度。

OpenVINO 在2021.4 版本中已经加入了手写数字识别的预训练模型,开始支持手写数字识别,下面让我们一起探索与尝试下它的使用方法与效果如何!

模型介绍

在OpenVINO 2021.4版本中支持的手写数字识别模型为handwritten-score-recognition-0003

,支持《digit》 or 《digit》。《digit》 格式的数字识别与小数点识别。该模型的结构有两个部分组成,前面是一个典型的CNN骨干网络,采用的是VGG-16类似的架构,实现特征提取;后面是一个双向的LSTM网络,实现序列预测;最终的预测结果基于CTC解析即可。其输入与输出格式如下:

输入格式为:[NCHW]= [1x1x32x64]

输出格式为:[WxBxL]=[16x1x13]

其中13表示“0123456789._#”,#表示空白、_表示非数字的字符

对输出格式的解码方式支持CTC贪心与Beam搜索,演示程序使用CTC贪心解码,这种方式相对简单,前面一篇文章中我们已经详细介绍过了,后面就直接套用即可!

模型使用与演示

使用该模型必须是基于常见文字检测得到的ROI区域,然后转化为灰度图象,使用该模型完成预测,关于场景文字检测,在前面一篇文章中我已经详细交代过了,这里就不再赘述。这里小可脑洞大开,针对常见的文本图象,采用OpenCV二值图象轮廓分析来完成数字ROI区域得截取,同样取得了不错得效果。基本的流程是这样:

Step 1: 读取图象并二值化

代码如下

Mat src = imread(“D:/images/zsxq/ocr.png”);

imshow(“input”, src);

Mat gray, binary;

cvtColor(src, gray, COLOR_BGR2GRAY);

adaptiveThreshold(gray, binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 25, 10);

其中adaptiveThreshold函数实现对灰度图象自适应二值化,参数blockSize=25表示高斯窗口大小,constants=10表示自适应常量值。需要注意的是参数blockSize值必须为奇数。

Step 2: 使用轮廓分析过填充过滤小噪点

代码如下

std::vector《vector《Point》》 contours;

std::vector《Vec4i》 hireachy;

findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

int image_height = src.rows;

int image_width = src.cols;

for (size_t t = 0; t 《 contours.size(); t++) {

double area = contourArea(contours[t]);

if (area 《 10) {

drawContours(binary, contours, t, Scalar(0), -1, 8);

}

}

上面的代码findContours表示轮廓发现,RETR_EXTERNAL表示采用发现最外层轮廓,CHAIN_APPROX_SIMPLE表示采用简单的链式编码收集轮廓上的像素点集。contourArea表示计算一个轮廓的面积,计算方式基于格林积分公式。drawContours表示绘制轮廓,其中thickness参数为-1表示填充,大于零表示绘制边缘。这里通过对白色噪点填充为黑色,完成噪声去除,

Step 3:膨胀预处理

对第二步输出的图象我们不能直接通过轮廓发现截取ROI,然后交给数字识别网络去识别,原因是这样会导致ROI区域的宽高比失衡,导致输入的数字resize之后发现畸变,识别精度会降低,所以通过膨胀操作,把数字适度的加宽与加高,主要是加宽,这样保持输入ROI区域resize之后不变性,就很容易识别了。这部分预处理的代码如下:

Mat se = getStructuringElement(MORPH_RECT, Size(45, 5));

Mat temp;

dilate(binary, temp, se);

其中dilate表示膨胀操作、然后对得到temp图象。

Step 4:数字识别推理与解析

对图-4进行轮廓发现,截取ROI,遍历每个轮廓,调用识别推理即可输出。其中加载模型与获取推理请求,这里就不再赘述了,截取ROI与推理解析部分的代码如下:

// 处理输出结果

findContours(temp, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

for (size_t t = 0; t 《 contours.size(); t++) {

Rect box = boundingRect(contours[t]);

Mat roi = gray(box);

size_t image_size = h*w;

Mat blob_image;

resize(roi, blob_image, Size(w, h));

// NCHW

unsigned char* data = static_cast《unsigned char*》(input-》buffer());

for (size_t row = 0; row 《 h; row++) {

for (size_t col = 0; col 《 w; col++) {

data[row*w + col] = blob_image.at《uchar》(row, col);

}

}

// 执行预测

infer_request.Infer();

auto output = infer_request.GetBlob(output_name);

const float* blob_out = static_cast《PrecisionTrait《Precision::FP32》::value_type*》(output-》buffer());

const SizeVector reco_dims = output-》getTensorDesc().getDims();

const int RW = reco_dims[0];

const int RB = reco_dims[1];

const int RL = reco_dims[2];

std::string ocr_txt = ctc_decode(blob_out, RW, RL);

std::cout 《《 ocr_txt 《《 std::endl;

cv::putText(src, ocr_txt, box.tl(), cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(255, 0, 0), 1);

cv::rectangle(src, box, Scalar(0, 0, 255), 2, 8, 0);

}

首先进行轮廓发现,然后根据每个轮廓截取ROI区域,设置输入数据,推理,解析输出采用CTC方式。

扩展探索

这里我没有采用场景文字检测来获取ROI,而是采用传统的二值图象分析来完成,主要是避免跟前面的文字内容重叠,同时启发更多的思路。另外采用膨胀扩展。

有时候并非是上上之选,还可以直接修改ROI大小来扩展,这部分其实可以参考上一篇场景文字识别的代码,轮廓发现获取外接矩形,直接修改ROI大小的方式,同时根据横纵比过滤非数字符号。改动部分就是去掉第三步膨胀,然后直接在第四步循环中添加下面的代码;

Rect box = boundingRect(contours[t]);

float rate = box.width / box.height;

if (rate 》 1.5) {

continue;

}

box.x = box.x - 15;

box.width = box.width + 30;

box.y = box.y - 5;

box.height = box.height + 10;

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数字识别
    +关注

    关注

    2

    文章

    19

    浏览量

    10106

原文标题:OpenVINO™ 手写字符识别模型与使用

文章出处:【微信号:英特尔物联网,微信公众号:英特尔物联网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    微软发布Windows版OneNote应用AI手写矫正功能

    微软官方解释称,这一功能旨在优化和调整手写字体,使之更加整洁美观且更具连贯性。这不仅能提升OneNote中的手写字体可读性,而且不会改变原始手写字效的独特风格与个性化特点,方便用户日后再次审阅及分享。
    的头像 发表于 04-18 10:59 60次阅读

    如何快速下载OpenVINO Notebooks中的AI大模型

    OpenVINO Notebooks是Jupyter Notebook形式的OpenVINO范例程序大集合,方便开发者快速学习并掌握OpenVINO推理程序,并通过Copy&Paste方式将范例中的关键程序应用到自己的AI软件中
    的头像 发表于 12-12 14:40 635次阅读
    如何快速下载<b class='flag-5'>OpenVINO</b> Notebooks中的AI大模型

    c语言怎么输出ascii码对应的字符

    字符的存储和处理。本文将介绍如何在C语言中输出ASCII码对应的字符。 首先,让我们来了解一下ASCII码的基本概念。ASCII码由美国国家标准协会(ANSI)于1963年制定,在计算机系统中广泛使用。它将常见字符(如大
    的头像 发表于 11-26 10:32 3745次阅读

    c语言将小写字母转换成大写字

    在C语言中,字符的大小写转换是常见的操作,而具体实现该功能的方法有多种,本篇文章将详尽、详实、细致地介绍C语言中将小写字母转换成大写字母的几种常用
    的头像 发表于 11-26 10:30 4745次阅读

    代码字符串分割方法

    的 String#split 来分割。 使用 String#split 方法 String 类中 split 方法,是我们平常处理字符串分割最常用的方法之一,它可以根据给定的分隔符或正
    的头像 发表于 09-25 11:42 426次阅读

    如何正确安装OpenVINO并将其与所需依赖关系链接?

    在 Windows 10 中安装OpenVINO 2019.3 在 Windows 路径中设置:C:\\Program Files (x86)\\Intel
    发表于 08-15 08:29

    在Raspberry Pi上从源代码构建OpenVINO 2021.3收到错误怎么解决?

    在 Raspberry Pi 上从源代码构建 OpenVINO™2021.3。 运行OpenVINO™推理,并收到错误消息: ModuleNotFoundError:没有
    发表于 08-15 08:24

    OpenVINO工具套件是否可以商业化使用?

    参阅 英特尔® OpenVINO™分销许可第 2.1 节(2021 年 5 月版本)。 无法了解英特尔® 发行版 OpenVINO™ 工具套件是否可以商业化使用。
    发表于 08-15 08:19

    为什么无法使用PyPI安装OpenVINO trade开发工具2022.1版本?

    已安装OpenVINO™开发工具 2022.1 版,采用 PyPI: pip install openvino-dev==2022.1.0 遇到错误消息: ERROR: \"Could
    发表于 08-15 07:58

    永久设置OpenVINO trade Windows reg10的工具套件环境变量

    您可以在 Windows® 10 中手动设置OpenVINO™环境变量。在 Windows® 10 系统中,转到 >系统和安全>系统>高级系统设置&
    发表于 08-15 07:18

    如何使用交叉编译方法为Raspbian 32位操作系统构建OpenVINO工具套件的开源分发

    提供如何使用交叉编译方法为 Raspbian* 32 位操作系统构建 OpenVINO™ 工具套件的开源分发。 单击主题上的 了解详细信息: 系统要求注意本指南假定您的 Raspberry Pi* 主板
    发表于 08-15 06:28

    在Ubuntu上搭建OpenVINO C++程序开发环境

    这种集成开发环境,为了在 Ubuntu 上也能拥有类似 Visual Studio 的开发体验,笔者探索出基于 Anaconda 和 VS Code,搭建 OpenVINO C++ 程序开发环境的方式。
    发表于 08-09 09:42 484次阅读
    在Ubuntu上搭建<b class='flag-5'>OpenVINO</b> C++程序开发环境

    功率电感器的使用方法

    功率电感器的使用方法
    的头像 发表于 07-28 15:21 592次阅读
    功率电感器的<b class='flag-5'>使用方法</b>

    安全光栅,光幕的使用方法

    安全光栅的使用方法
    的头像 发表于 05-16 09:51 671次阅读
    安全光栅,光幕的<b class='flag-5'>使用方法</b>

    Python中检查字符串包含的方法

    Python 有多种处理字符串的方法。今天我们介绍如何检查一个字符串中是否包含另一个字符串。
    的头像 发表于 05-14 16:02 1.4w次阅读