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

    浏览量

    10135

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

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

收藏 人收藏

    评论

    相关推荐

    base64编码和解码的使用方法

    Base64编码是一种基于64个可打印字符来表示二进制数据的编码方法。它将每3个字节的二进制数据编码为4个字符,如果不足3个字节,则使用填充字符(通常是 = )来补足。 2. Bas
    的头像 发表于 11-10 10:48 430次阅读

    LangChain框架关键组件的使用方法

    LangChain,开发者可以轻松构建基于RAG或者Agent流水线的复杂应用体系,而目前我们已经可以在LangChain的关键组件LLM,Text Embedding和Reranker中直接调用OpenVINO进行模型部署,提升本地RAG和Agent服务的性能,接下来就让我们一起看下这些组件的
    的头像 发表于 08-30 16:55 505次阅读
    LangChain框架关键组件的<b class='flag-5'>使用方法</b>

    DC/DC模拟的基本使用方法和特性确认方法

    本篇介绍了DC/DC模拟的基本使用方法及确认基本特性的方法
    的头像 发表于 08-20 17:08 564次阅读
    DC/DC模拟的基本<b class='flag-5'>使用方法</b>和特性确认<b class='flag-5'>方法</b>

    浅谈锡膏的储存及使用方法

    锡膏(焊锡膏)是电子组装过程中常用的材料,它的储存和使用方法对保证焊接质量和性能至关重要。以下是详细的储存及使用方法
    的头像 发表于 06-27 10:02 758次阅读

    可编程电源使用方法

    可编程电源使用方法 可编程电源使用方法 摘要:本文详细介绍了可编程电源的使用方法,包括其基本概念、主要功能、选择原则、操作步骤、注意事项以及实际应用案例,旨在帮助读者全面了解可编程电源
    的头像 发表于 06-10 15:29 886次阅读

    手柄控制代码及使用方法

    手柄控制代码及使用方法
    的头像 发表于 05-15 10:19 1570次阅读

    Microsoft Excel融入手写笔功能,助您快速插入、删除单元格数据

     Microsoft今日宣布,向Microsoft 365内部人士开放Windows版本Excel的“Ink to Text”功能的试用机会。此工具旨在将手写字迹转为文字,使表格数据填充更便捷高效。
    的头像 发表于 04-30 14:16 866次阅读

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

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

    555集成芯片的使用方法

    555集成芯片的使用方法主要依赖于其特定的引脚功能和电路设计。
    的头像 发表于 03-25 14:39 1316次阅读

    磁场探头和电场探头的使用方法与技巧

    磁场探头和电场探头的使用方法与技巧  磁场探头和电场探头是用于测量磁场和电场的仪器。它们在科学实验、工程设计和实际应用中都起着重要的作用。本文将详细介绍磁场探头和电场探头的使用方法和技巧。 一、磁场
    的头像 发表于 01-05 14:31 820次阅读

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

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

    sumif函数求和的使用方法及实例

    ,range代表要进行条件判断的数据区域;criteria代表条件,可以是数字、字符串、表达式等;[sum_range]代表要进行求和的数据区域。 Sumif函数的使用方法非常简单,只需要
    的头像 发表于 12-03 10:36 1659次阅读

    SUMIF函数的使用方法

    SUMIF函数是Excel中常用的求和函数之一,它可以根据指定的条件对范围内的数值进行求和。本文将详细介绍SUMIF函数的使用方法,并通过实例演示其具体操作。 SUMIF函数的语法如下: SUMIF
    的头像 发表于 11-30 16:34 4800次阅读

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

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

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

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