【opencv】dnn示例-scene_text_recognition.cpp OpenCV库深度学习模型检测和识别图像中文本...

devtools/2024/9/19 0:37:17/ 标签: 深度学习, opencv, dnn, 人工智能, 计算机视觉

f8069d3b7bbe6af918488ea97075f824.png

1a2e61c97f3847272938be099baf4cea.png

1440 x 1080
0: 't'
1: 'i'
2: 'I'
3: '黄'

中文显示异常:文末有解决方案

3fa27f5ed397cb6a8e3feb4ab1d61693.png

934 x 1408
0: '蓝朝路'
1: 'BaoanHwy'
2: 'GucunPark'
3: '宝安公路'
4: '顾村公园'
5: 'HutaiRd.'
6: '沪太路'
7: '东'

中文显示异常:文末有解决方案

文件下载及参数设置参考:(文本识别、文本检测模型及参数)

TextRecognitionModel:
crnn.onnx:
url: https://drive.google.com/uc?export=dowload&id=1ooaLR-rkTl8jdpGy1DoQs0-X0lQsB6Fj
sha: 270d92c9ccb670ada2459a25977e8deeaf8380d3,
alphabet_36.txt: https://drive.google.com/uc?export=dowload&id=1oPOYx5rQRp8L6XQciUwmwhMCfX0KyO4b
parameter setting: -rgb=0;
description: The classification number of this model is 36 (0~9 + a~z).The training dataset is MJSynth.crnn_cs.onnx:
url: https://drive.google.com/uc?export=dowload&id=12diBsVJrS9ZEl6BNUiRp9s0xPALBS7kt
sha: a641e9c57a5147546f7a2dbea4fd322b47197cd5
alphabet_94.txt: https://drive.google.com/uc?export=dowload&id=1oKXxXKusquimp7XY1mFvj9nwLzldVgBR
parameter setting: -rgb=1;
description: The classification number of this model is 94 (0~9 + a~z + A~Z + punctuations).The training datasets are MJsynth and SynthText.crnn_cs_CN.onnx:
url: https://drive.google.com/uc?export=dowload&id=1is4eYEUKH7HR7Gl37Sw4WPXx6Ir8oQEG
sha: 3940942b85761c7f240494cf662dcbf05dc00d14
alphabet_3944.txt: https://drive.google.com/uc?export=dowload&id=18IZUUdNzJ44heWTndDO6NNfIpJMmN-ul
parameter setting: -rgb=1;
description: The classification number of this model is 3944 (0~9 + a~z + A~Z + Chinese characters + special characters).The training dataset is ReCTS (https://rrc.cvc.uab.es/?ch=12).             TextDetectionModel:
- DB_IC15_resnet50.onnx:
url: https://drive.google.com/uc?export=dowload&id=17_ABp79PlFt9yPCxSaarVc_DKTmrSGGf
sha: bef233c28947ef6ec8c663d20a2b326302421fa3
recommended parameter setting: -inputHeight=736, -inputWidth=1280;
description: This model is trained on ICDAR2015, so it can only detect English text instances.- DB_IC15_resnet18.onnx:
url: https://drive.google.com/uc?export=dowload&id=1vY_KsDZZZb_svd5RT6pjyI8BS1nPbBSX
sha: 19543ce09b2efd35f49705c235cc46d0e22df30b
recommended parameter setting: -inputHeight=736, -inputWidth=1280;
description: This model is trained on ICDAR2015, so it can only detect English text instances.- DB_TD500_resnet50.onnx:
url: https://drive.google.com/uc?export=dowload&id=19YWhArrNccaoSza0CfkXlA8im4-lAGsR
sha: 1b4dd21a6baa5e3523156776970895bd3db6960a
recommended parameter setting: -inputHeight=736, -inputWidth=736;
description: This model is trained on MSRA-TD500, so it can detect both English and Chinese text instances.- DB_TD500_resnet18.onnx:
url: https://drive.google.com/uc?export=dowload&id=1sZszH3pEt8hliyBlTmB-iulxHP1dCQWV
sha: 8a3700bdc13e00336a815fc7afff5dcc1ce08546
recommended parameter setting: -inputHeight=736, -inputWidth=736;
description: This model is trained on MSRA-TD500, so it can detect both English and Chinese text instances.

这段源代码是一个使用OpenCV库和深度学习模型检测和识别图像中文本的完整示例。下面简要介绍一下这个代码的主要部分。

包含头文件 & 命名空间: 引入了必要的头文件,包括OpenCV库和深度神经网络模块,以及使用标准和OpenCV命名空间。

参数解析: 代码开始部分定义了一些参数,用于存储模型路径、输入图像大小、二值化阈值、多边形阈值,以及其他相关配置。这些参数可以通过命令行提供。

主函数 (main): 解析命令行参数后,加载文本检测模型和文本识别模型,检测模型使用DBNet算法,识别模型使用CRNN算法。

加载词汇: 为识别模型加载词汇表,词汇表通常是字符集文件。

参数设置: 为检测和识别模型设置输入参数,包括缩放比例、输入尺寸以及RGB均值等。

处理输入图像: 读取输入图像,执行文本检测,然后对检测到的文本区域进行识别。

绘制结果: 在图像上绘制检测到的文本多边形,并在每个检测到的文本区域旁边显示识别的结果。

fourPointsTransform 函数: 对于检测到的每个文本区域,使用透视变换校正倾斜的文本,以便在识别模型中使用。

sortPts 函数: 辅助函数用于排序点,可用于未来的功能扩展。

代码的功能总结

从命令行接收输入参数,包括输入图像路径、检测和识别模型的路径,以及其他处理参数。

加载用于文本检测的DBNet模型和用于文本识别的CRNN模型。

对输入图像进行处理,使用检测模型识别文本区域。

对每个检测到的文本区域进行透视变换和裁剪。

使用识别模型对变换后的图块执行文本识别。

在原始图像上绘制检测到的文本区域,并显示识别的文本。

在屏幕上显示结果,并等待按键退出程序。

这段代码的核心在于集成OpenCV的DNN模块以及图像处理技术,实现从图像中自动检测和识别文本的流程。它可以作为一种端到端的文本检测和识别解决方案,在有文本的场景图片中自动识别出文字。

#include <iostream>  // 引用输入输出库
#include <fstream>   // 引用文件操作库
#include <opencv2/core.hpp>  // 引用OpenCV核心功能库
#include <opencv2/imgproc.hpp>  // 引用OpenCV图像处理库
#include <opencv2/highgui.hpp>  // 引用OpenCV高层GUI库
#include <opencv2/dnn/dnn.hpp>  // 引用OpenCV深度学习模块库using namespace cv;  // 使用OpenCV命名空间
using namespace cv::dnn;  // 使用OpenCV深度学习命名空间// 定义程序接收的命令行参数
std::string keys ="{ help  h                          | | Print help message. }""{ inputImage i                     | td3.png| Path to an input image. Skip this argument to capture frames from a camera. }""{ detModelPath dmp                 |DB_TD500_resnet18.onnx | Path to a binary .onnx model for detection. ""Download links are provided in doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown}""{ recModelPath rmp                 |crnn_cs_CN.onnx | Path to a binary .onnx model for recognition. ""Download links are provided in doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown}""{ inputHeight ih                   |736| image height of the model input. It should be multiple by 32.}""{ inputWidth iw                    |736| image width of the model input. It should be multiple by 32.}""{ RGBInput rgb                     |1| 0: imread with flags=IMREAD_GRAYSCALE; 1: imread with flags=IMREAD_COLOR. }""{ binaryThreshold bt               |0.3| Confidence threshold of the binary map. }""{ polygonThreshold pt              |0.5| Confidence threshold of polygons. }""{ maxCandidate max                 |200| Max candidates of polygons. }""{ unclipRatio ratio                |2.0| unclip ratio. }""{ vocabularyPath vp                | alphabet_3944.txt | Path to benchmarks for evaluation. ""Download links are provided in doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown}";// 定义用于文档透视变换的函数
void fourPointsTransform(const Mat& frame, const Point2f vertices[], Mat& result);// 定义用于对点进行排序的函数
bool sortPts(const Point& p1, const Point& p2);int main(int argc, char** argv)
{// 解析命令行参数CommandLineParser parser(argc, argv, keys);parser.about("Use this script to run an end-to-end inference sample of textDetectionModel and textRecognitionModel APIs\n""Use -h for more information");if (argc == 0 || parser.has("help")){parser.printMessage();return 0;}// 提取命令行指定的参数float binThresh = parser.get<float>("binaryThreshold");float polyThresh = parser.get<float>("polygonThreshold");uint maxCandidates = parser.get<uint>("maxCandidate");String detModelPath = parser.get<String>("detModelPath");String recModelPath = parser.get<String>("recModelPath");String vocPath = parser.get<String>("vocabularyPath");double unclipRatio = parser.get<double>("unclipRatio");int height = parser.get<int>("inputHeight");int width = parser.get<int>("inputWidth");int imreadRGB = parser.get<int>("RGBInput");if (!parser.check()){parser.printErrors();return 1;}// 加载模型CV_Assert(!detModelPath.empty());TextDetectionModel_DB detector(detModelPath);  // 加载文本检测模型detector.setBinaryThreshold(binThresh)  // 设置二值化阈值.setPolygonThreshold(polyThresh)  // 设置多边形阈值.setUnclipRatio(unclipRatio)  // 设置非切割比例.setMaxCandidates(maxCandidates);  // 设置最大候选数量CV_Assert(!recModelPath.empty());TextRecognitionModel recognizer(recModelPath);  // 加载文本识别模型// 加载词汇表CV_Assert(!vocPath.empty());std::ifstream vocFile;vocFile.open(samples::findFile(vocPath));CV_Assert(vocFile.is_open());String vocLine;std::vector<String> vocabulary;  // 创建用于存储词汇的向量while (std::getline(vocFile, vocLine)) {vocabulary.push_back(vocLine);}recognizer.setVocabulary(vocabulary);recognizer.setDecodeType("CTC-greedy");// 设置检测模型和识别模型的参数double detScale = 1.0 / 255.0;Size detInputSize = Size(width, height);Scalar detMean = Scalar(122.67891434, 116.66876762, 104.00698793);detector.setInputParams(detScale, detInputSize, detMean);double recScale = 1.0 / 127.5;Scalar recMean = Scalar(127.5);Size recInputSize = Size(100, 32);recognizer.setInputParams(recScale, recInputSize, recMean);// 创建窗口用于展示结果static const std::string winName = "Text_Spotting";// 载入输入图像Mat frame = imread(samples::findFile(parser.get<String>("inputImage")));std::cout << frame.size << std::endl;// 运行文本检测和识别推理std::vector< std::vector<Point> > detResults;  // 存储检测结果detector.detect(frame, detResults);  // 运行文本检测Mat frame2 = frame.clone();  // 克隆原图用于绘制结果if (detResults.size() > 0) {// 文本识别Mat recInput;if (!imreadRGB) {cvtColor(frame, recInput, cv::COLOR_BGR2GRAY);  // 转换图像到灰度格式} else {recInput = frame;}std::vector< std::vector<Point> > contours;for (uint i = 0; i < detResults.size(); i++){const auto& quadrangle = detResults[i];CV_CheckEQ(quadrangle.size(), (size_t)4, "");  // 确保每个检测到的形状是四边形contours.emplace_back(quadrangle);std::vector<Point2f> quadrangle_2f;for (int j = 0; j < 4; j++)quadrangle_2f.emplace_back(quadrangle[j]);// 执行透视变换和裁剪Mat cropped;fourPointsTransform(recInput, &quadrangle_2f[0], cropped);std::string recognitionResult = recognizer.recognize(cropped);  // 识别文本std::cout << i << ": '" << recognitionResult << "'" << std::endl;putText(frame2, recognitionResult, quadrangle[3], FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);  // 在图像上绘制识别结果}polylines(frame2, contours, true, Scalar(0, 255, 0), 2);  // 绘制检测到的文本轮廓} else {std::cout << "No Text Detected." << std::endl;}imshow(winName, frame2);  // 显示结果waitKey();  // 等待用户按键return 0;  // 程序结束
}// 文档透视变换函数定义
void fourPointsTransform(const Mat& frame, const Point2f vertices[], Mat& result)
{const Size outputSize = Size(100, 32);  // 设置输出图像尺寸// 定义透视变换的目标顶点Point2f targetVertices[4] = {Point(0, outputSize.height - 1),Point(0, 0),Point(outputSize.width - 1, 0),Point(outputSize.width - 1, outputSize.height - 1)};// 获取透视变换矩阵Mat rotationMatrix = getPerspectiveTransform(vertices, targetVertices);// 应用透视变换warpPerspective(frame, result, rotationMatrix, outputSize);#if 0imshow("roi", result);  // 可以选择展示变换后的区域waitKey();
#endif
}// 点排序函数定义
bool sortPts(const Point& p1, const Point& p2)
{return p1.x < p2.x;  // 按照X坐标排序
}

57af8302d1351b43d75ee32d14c7ff1e.png

06fc9efc9923470ca116eea2cec9ead3.png


http://www.ppmy.cn/devtools/3827.html

相关文章

elementui单个输入框回车刷新整个页面

<!-- 搜索 --> <el-form :model"queryParams" ref"queryForm" :inline"true"><el-form-item label"名称" prop"nameLike"><el-input v-model"queryParams.nameLike" placeholder"请输入…

3.2 iHRM人力资源 - 组织架构 - 编辑及删除

iHRM人力资源 - 组织架构 文章目录 iHRM人力资源 - 组织架构一、编辑功能1.1 表单弹层并数据回显1.2 编辑校验1.3 编辑 二、删除功能 一、编辑功能 编辑功能和新增功能用的组件其实是一个&#xff0c;结构几乎是一样的&#xff0c;其实是复用了组件&#xff0c;我们也省去了很…

keil创建单片机工程

一、创建工程 打开Keil uVision4&#xff0c;依次选择 Project—>New uVision4 Project&#xff0c;选择工程保存路径及填写工程名称&#xff0c;如下图 然后点“保存”。在Select a CPU Data Base File中选择"STC MCU Database"&#xff0c;点 "OK"&am…

docker的安装以及docker中nginx配置

机器 test3 192.168.23.103 1机器初始化配置 1.1关闭防火墙&#xff0c;清空防火墙规则 systemctl stop firewalld iptables -F setenforce 01.2部署时间同步 yum install ntp ntpdate -y1.3安装基础软件包 yum install -y wget net-tools nfs-utils lrzsz gcc gcc-c make…

【大数据与云计算】虚拟机安装Linux

前言&#xff1a;使用Linux系统对大数据学习必不可少&#xff0c;本文主要介绍虚拟机安装linux的流程 文章目录 一、 下载VMware二、下载Linux三、安装Linux 一、 下载VMware 官网链接 下载VMware-player&#xff0c;一直下一步安装即可。 二、下载Linux 点击链接直接下载&…

ASP.NET多语种网络硬盘系统的设计

摘 要 网络硬盘系统是计算机网络中比较流行的一种应用软件&#xff0c;但是一般的网络硬盘系统只适用于使用单一语种的人群。为满足不同语种人群对网络硬盘系统的需求&#xff0c;设计了多语种网络硬盘系统。采用ASP.NET 2.0开发语言&#xff0c;利用ASP.NET中的三层结构、B/S模…

新项目应该选mongodb还是postgresql?

文章目录 MongoDBPostgreSQL大数据处理时的优势对比实际使用经验 选择MongoDB还是PostgreSQL作为新项目的数据库&#xff0c;主要取决于项目的具体需求、数据模型、应用场景以及团队熟悉程度等因素。下面将从几个关键角度对两者进行对比分析。 MongoDB 数据模型&#xff1a;Mo…

JavaVue 借助json传递数据

由前端向后端发送一个json键值对 <template><div><button click"sendRequest">发送请求</button></div> </template><script setup> import axios from axios;const sendRequest () > {const jsonData {key1: value…

vue3的一般使用

vue3的一般使用 ** 1.子组件写模版时 可以省略props

开发语言漫谈-go

网上吹嘘go语言的很多&#xff0c;确实鹅厂&#xff0c;字节、B站、知乎都在用go。但是实质上你发现他们的领域是一样的。你听说过谁家的财务系统用go&#xff1f;谁家erp用go&#xff1f; go的设计思路和python差不多&#xff0c;就是要降低入门难度&#xff0c;提高开发效率。…

政企即时通讯APP:快速构建专属、安全的智慧办公解决方案

在数字化时代&#xff0c;政企单位对信息系统的依赖日益加深&#xff0c;但随之而来的信息安全隐患也不容忽视。组织内部信息系统的安全问题&#xff0c;尤其是在人员调整或离职时&#xff0c;管理员账号管理的混乱&#xff0c;以及敏感资料泄露和业务系统破坏的风险&#xff0…

麦克斯韦方程简单理解波粒二象性粒子退相干(Quantum Decoherence):微观的动态,宏观的静态量子

目录 麦克斯韦方程简单理解 波粒二象性 粒子退相干(Quantum Decoherence):微观的动态,宏观的静

[C++][算法基础]二分图的最大匹配(匈牙利算法)

给定一个二分图&#xff0c;其中左半部包含 n1 个点&#xff08;编号 1∼n1&#xff09;&#xff0c;右半部包含 n2 个点&#xff08;编号 1∼n2&#xff09;&#xff0c;二分图共包含 m 条边。 数据保证任意一条边的两个端点都不可能在同一部分中。 请你求出二分图的最大匹配…

【JavaScript】异步函数(async和await详解)

异步函数 ES8 的 async/await 旨在解决利用异步结构组织代码的问题。为此&#xff0c;ECMAScript 对函数进行了扩展&#xff0c;为其增加了两个新关键字&#xff1a;async 和 await。 1. async async 关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头…

51单片机之DS1302实时时钟

1.DS1302时钟芯片介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称…

Ansible相关

Ansible 环境准备 主机名ip分组crontol192.168.88.1node1192.168.88.11testnode2192.168.88.12proxynode3192.168.88.13webserversnode4192.168.88.14webserversnode5192.168.88.15database 所有操作只需在crontol上操作即可 安装ansible # 依赖一般也会跟着一起装好 yum …

uniapp微信小程序(商城项目)

最近&#xff0c;闲来无事&#xff0c;打算学一下uniapp小程序 于是在跟着某站上学着做了一个小程序&#xff0c;主要是为了学uniapp和vue。某站黑马优购 完成的功能主要有&#xff1a;首页、搜索、分类和购物车。 有人问了为什么没有登录、和添加订单呢&#xff1f;问的很好…

上位机图像处理和嵌入式模块部署(树莓派4b开机启动脚本)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 编写好程序之后&#xff0c;一般要求程序开机启动后就可以运行。所以这个时候&#xff0c;我们一般就会把程序流程放在开发板的启动脚本当中。如果…

华为配置 dhcp snooping

1、开启snooping功能前必须先全局开启dhcp的功能 [HUAWEI] dhcp enable //全局开启 2、全局开启snooping功能 [HUAWEI] dhcp snooping enable ipv4 //全局单独开启IPv4的snooping功能&#xff0c;这样将能够有效的节约设备的CPU利用率 3、接口或VLAN下开启DH…

玄子Share-安装及管理程序

玄子Share-安装及管理程序 Linux 应用程序基础 应用程序与系统命令的关系 角色系统命令应用程序文件位置一般在/bin和/sbin目录中&#xff0c;或为Shell内部指令通常在/usr/bin和/usr/sbin目录中主要用途完成对系统的基本管理工作完成相对独立的任务适用环境一般只在字符操作…