实战OpenCV之文字识别

基础入门

        文字识别技术,也称为光学字符识别(Optical Character Recognition,OCR),是一种让计算机能够“读取”图像中的文字,并将其转化为可编辑文本的技术。这项技术在许多领域都有广泛的应用,包括但不限于:图片文字识别、文档管理、自动化数据输入、历史文献数字化。

        文字识别通常包含以下6个主要步骤。

        1、图像预处理:包括图像的读取、灰度化、二值化、去噪等。

        2、文本区域检测:定位图像中的文本区域。

        3、字符分割:将文本区域分割成单个字符。

        4、特征提取:提取字符的特征,用于后续识别。

        5、字符识别:通过机器学习模型或其他技术识别字符。

        6、后处理:校正识别结果,优化输出。

        OpenCV本身并没有内置的文字识别功能,但它可以与其他OCR工具(比如:Tesseract OCR)集成,或将提取的特征用于训练深度学习模型(比如:CRNN)以进行识别。在OpenCV中使用CRNN进行文字识别,与前面介绍的目标检测基本差不多,都是使用cv::dnn来进行推理,故下面着重介绍Tesseract OCR。

Tesseract OCR

        Tesseract OCR是一款开源的光学字符识别工具,它能够将图像中的文字转换为可编辑的文本。Tesseract是目前最先进和广泛使用的OCR引擎之一,支持多种语言,并且具有很高的识别准确率。Tesseract OCR最初是由HP(惠普)公司于1980年开发的,后来由Google接手维护和发展。自2006年以来,Google一直在支持Tesseract的开发,并将其开源,使之成为了一个社区驱动的项目。

        Tesseract OCR具有以下几个主要特点。

        开源:Tesseract是完全免费的,并且它的源代码是开放的,任何人都可以查看、修改和分发。

        多平台支持:支持Windows、Linux、MacOS等多种操作系统。

        多语言支持:支持多种语言,包括英语、中文、日语、韩语等超过100种语言。

        高准确率:Tesseract在识别印刷文本方面表现出色,并且对于某些语言的手写识别也有较好的效果。

        灵活的接口:Tesseract提供了多种编程语言的接口,包括C/C++、Python等,方便开发者集成到自己的应用程序中。

        可以在https://github.com/UB-Mannheim/tesseract/wiki下载Tesseract OCR的Windows安装包,当前最新版本为5.4.0。

        安装时,可以选择下载中文的训练包。这样,进行文字识别时,才可以识别出中文。使用Tesseract的常用命令如下。

// 输出tesseract的版本信息
tesseract.exe --version// 列出所有支持的语言包
tesseract.exe --list-langs// 从图片中识别文字,将结果输出到文本文件中
tesseract.exe G:\\1.png G:\\output -l chi_sim

        如果要在OpenCV中集成Tesseract OCR进行开发,则需要下载Tesseract OCR的源码。由于Tesseract OCR依赖Leptonica库,故还需要下载Leptonica库的源码。我们可以使用CMake来编译Tesseract OCR,最终得到编译好的库和头文件。

        Tesseract OCR的核心类是TessBaseAPI,它提供了初始化、设置图像、获取识别结果等一系列功能。主要的一些接口如下。

        Init:初始化Tesseract引擎。

        SetImage:设置要识别的图像。

        GetUTF8Text:获取识别后的UTF-8编码的文本。

        End:结束并释放资源。

实战解析

        在下面的实战代码中,我们首先通过OpenCV读取了一个带文字的图片文件(见下图),并将其转换为灰度图以提高OCR的识别准确性。接着,我们初始化了Tesseract OCR引擎,指定了语言为简体中文,并使用默认的OCR引擎模式。

        为了使Tesseract能够处理图像,我们通过自定义的Mat8ToPix函数将OpenCV的Mat对象转换为Leptonica库的PIX对象。然后,将转换后的PIX对象作为OCR引擎的输入图像。最后,我们执行OCR识别操作,获取到识别结果。该结果是以UTF-8编码的字符串形式存储的,需要转换为ANSI字符集来显示。注意:GetUTF8Text返回的字符串,必须使用delete []的形式进行释放,否则会导致内存泄漏。

#include <opencv2/opencv.hpp>
using namespace cv;#include <iostream>
using namespace std;#include <tesseract/baseapi.h>
using namespace tesseract;#include <leptonica/allheaders.h>Pix *Mat8ToPix(cv::Mat *pMat)
{Pix *pPix = pixCreate(pMat->size().width, pMat->size().height, 8);for(int y = 0; y < pMat->rows; y++){for(int x = 0; x <pMat->cols; x++){pixSetPixel(pPix, x, y, (l_uint32)pMat->at<uchar>(y, x));}}return pPix;
}string Utf8ToAnsi(const string& utf8Str)
{int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);wstring wideStr(wideLen, L'\0');MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], wideLen);int ansiLen = WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL);string ansiStr(ansiLen, '\0');WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, &ansiStr[0], ansiLen, NULL, NULL);return ansiStr;
}int main(int argc, char **argv)
{Mat image = imread("Text.png");if (image.empty()){cout << "Can not open or find the image" << endl;return -1;}Mat grayImage;cvtColor(image, grayImage, COLOR_BGR2GRAY);// 初始化Tesseract引擎TessBaseAPI *pTess = new TessBaseAPI();// chi_sim表示简体中文if (pTess->Init("C:\\Program Files\\Tesseract-OCR\\tessdata", "chi_sim", OEM_DEFAULT)){cout << "Can not initialize tesseract." << endl;return -1;}// 将OpenCV图像转换为Leptonica的PIX对象PIX *pPix = Mat8ToPix(&grayImage);// 设置图像源pTess->SetImage(pPix);// 进行OCR识别char *pszText = pTess->GetUTF8Text();string strResult = Utf8ToAnsi(pszText);// 输出识别结果cout << "Text: [" << strResult << "]" << endl;delete[] pszText;pTess->End();delete pTess;pixDestroy(&pPix);return 0;
}

        执行上面的代码,运行效果可参考下图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/17040.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程状态,优先级,环境变量

目录 谈谈硬件冯诺依曼体系结构数据流向 谈谈软件(操作系统)什么是操作系统&#xff1f;为什么需要操作系统&#xff1f;操作系统如何管理&#xff1f; 谈谈进程管理进程PCB查看进程ps ajxprockill -9 PID 系统调用getpid()getppid()fork() 进程状态linux下的进程状态RSDT/tXZ …

QML —— ChartView - 饼状图Demo(附源码)

效果 说明 ChartView类型将不同的系列类型显示为图表。 需引入模块:       import QtQuick 2.0       import QtCharts 2.0 代码 注意:引入ChartView需要pro文件内写入"QT += quick charts" main.cpp #include <QGuiApplication>

shell bash---类似数组类型

0 Preface/Foreword C/C,Python&#xff0c;Java等编程语言&#xff0c;都含有数组类型&#xff0c;那么shell脚本是不是也有类似的语法呢&#xff1f; 1 类似数组类型 1.1 &#xff08;&#xff09;类似数组类型 #! /bin/bashecho "Welcome to bash world!" anim…

【论文分享】基于街景图像识别和深度学习的针对不同移动能力老年人的街道步行可达性研究——以南京成贤街社区为例

全球老龄化趋势加剧, 许多城市中老年人数量不断增加&#xff0c;而现有街道和社区基础设施往往未能满足其步行安全和便利需求。本次我们给大家带来一篇SCI论文的全文翻译&#xff0c;该论文通过探讨不同步行能力的老年人对城市步行环境的需求&#xff0c;提供了关于如何改善城市…

Figma汉化:提升设计效率,降低沟通成本

在UI设计领域&#xff0c;Figma因其强大的功能而广受欢迎&#xff0c;但全英文界面对于国内设计师来说是一个不小的挑战。幸运的是&#xff0c;通过Figma汉化插件&#xff0c;我们可以克服语言障碍。以下是两种获取和安装Figma汉化插件的方法&#xff0c;旨在帮助国内的UI设计师…

Docker:查看镜像里的文件

目录 背景步骤1、下载所需要的docker镜像2、创建并运行临时容器3、停止并删除临时容器 背景 在开发过程中&#xff0c;为了更好的理解和开发程序&#xff0c;有时需要确认镜像里的文件是否符合预期&#xff0c;这时就需要查看镜像内容 步骤 1、下载所需要的docker镜像 可以使…

『VUE』27. 透传属性与inheritAttrs(详细图文注释)

目录 什么是透传属性&#xff08;Forwarding Attributes&#xff09;使用条件唯一根节点禁用透传属性继承总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 什么是透传属性&#xff08;Forwarding Attributes&#xff09; 在 V…

Linux内存与磁盘管理

内存查看命令 内存查看命令free、top top写过了&#xff0c;在进程管理里free命令 free命令用于显示系统内存的使用情况&#xff0c;包括物理内存、交换空间和内核缓冲区的信息。通过free命令可以快速了解系统当前的内存使用情况&#xff0c;有助于监控系统性能和调优。 基本…

19-8 ACC自适应巡航控制系统输入输出接口设计

ACC系统输出接口 ACC_EngTrgReq ACC 发动机扭矩需求 ACC ModSts ACC 模式 OFF Failure Brake Only Stand-by Disenabled Stand-by Enabled Active –Control Override Standstil ACC_EngTrgReqActive ACC纵向控制功能发动机扭矩请求激活 Not Active Active ACC_DecelToStopReq …

SpringCloud核心组件(五)

文章目录 Gateway一. 概述简介1. Gateway 是什么2. 什么是网关?3.Gateway 和 Nginx 两个网关的区别什么是流量入口&#xff1f; 4.Gateway 能干嘛5.gateway 三大核心概念6.运行方式 二. 入门案例a.创建gateway模块&#xff0c;在pom.xml中引入依赖b.创建启动类GatewayApplicat…

【JavaScript】LeetCode:96-100

文章目录 96 单词拆分97 最长递增子序列98 乘积最大子数组99 分割等和子集100 最长有效括号 96 单词拆分 动态规划完全背包&#xff1a;背包-字符串s&#xff0c;物品-wordDict中的单词&#xff0c;可使用多次。问题转换&#xff1a;s能否被wordDict中的单词组成。dp[i]&#x…

maven的optional选项说明以及具体应用

写在前面 本文看下maven的optional选项的作用和用法。 1&#xff1a;什么作用 考虑这样的场景&#xff0c;A依赖B&#xff0c;B依赖C&#xff0c;正常的按照依赖的传递性&#xff0c;A也会间接的依赖C&#xff0c;但是在一些特定的场景中项目A只希望依赖B&#xff0c;而不依…

124. 二叉树中的最大路径和【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 124. 二叉树中的最大路径和 一、题目描述 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径…

【强弱分界】,股市动态多维波动 精准辅助工具 源码

该策略结合了多重技术指标&#xff0c;旨在通过高低点的动态波动分析&#xff0c;提供精准的买入、卖出信号及市场强弱判断。 本策略适用于&#xff1a; 中短期股市交易者&#xff0c;帮助判断市场的进出场时机。 高频交易和量化交易系统中的信号生成模块。 在波动较大的市场…

【IEEE出版 | 中国石油大学(华东)主办】第六届信息与计算机前沿术国际学术会议(ICFTIC 2024,12月13-15日)

第六届信息与计算机前沿术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 官方信息 会议官网&#xff1a;WWW.ICFTIC.ORG 2024 6th International Conference on Frontier Technologies of Information…

如何在SM30生成的维护表中增加选择框 CheckBox

用户想要在屏幕中显示选择框进行维护&#xff0c;如下图&#xff1a; 很简单&#xff0c;先通过 SE11 定义一个 CHAR1 类型的字段名&#xff0c;然后通过使用程序转到表维护生成器 进入到概述屏幕&#xff0c;双击&#xff0c;然后进入到屏幕布局&#xff1a; 先删除原来通过系…

极客争锋 智连未来 TuyaOpen Framework极客创意大赛正式开启

TuyaOpen Framework极客创意大赛正式开启 可选择基于: TuyaOpen Framework 原生开源包: https://github.com/tuya/tuyaopen 支持 Ubuntu/T2/T3/T5/ESP32/ESP32C3等多款芯片TuyaOpen Arduino:https://github.com/tuya/arduino-tuyaopen支持 T2/T3/T5等多款芯片TuyaOpen LuaNode…

麒麟kysec安全

一、kysec安全框架管理 开启kysec getstatus Copy security-switch --set default Copy 重启系统 reboot Copy 刷新页面&#xff0c;等待几分钟&#xff0c;即可完成文件的扫描。 查看kysec状态 getstatus Copy 切换到管理员身份&#xff08;密码&#xff1a;devuser…

c++ 左值、右值、左值引用()、右值引用(),移动构造和std::move

左值和右值 不是等于号的左边和右边 &#xff01;&#xff01;&#xff08;一部分场景下是这样&#xff09; 右值可以描述成一个临时值 c 左值、右值、左值引用、右值引用&& 左值右值左值引用右值引用结论 第二弹~ 你可以完全不看上面的解释移动语义移动构造和move 左…

黑马嵌入式开发入门模电基础学习笔记

学习视频: 黑马程序员嵌入式开发入门模电&#xff08;模拟电路&#xff09;基础 文章目录 背景介绍电流电压组件仿真三极管ne555PCBEDA案例&#xff1a;非接触式电笔案例&#xff1a;电子琴 背景介绍 电流 电压 组件 仿真 三极管 mos管 ne555 PCB EDA 案例&#xff1a;非接触…