【opencv】dnn示例-scene_text_detection.cpp 场景文本区域检测

server/2024/10/20 22:17:31/

1231720d3cfefd83730932b9a6cf53c6.png

63d560da5bec4e2b1459facb13d50753.png

模型下载:

- 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.https://drive.google.com/drive/folders/1T9n0HTP3X3Y_nJ0D1ekMhCQRHntORLJG
https://drive.google.com/drive/folders/1qzNCHfUJOS0NEUOIKn69eCtxdlNPpWbq

代码地址:

https://github.com/MhLiao/DB
https://github.com/opencv/opencv/blob/4.x/samples/dnn/scene_text_detection.cpp

这个程序是一个基于OpenCV和C++的文本检测应用。它使用了不同的二值化(Differentiable Binarization)算法来实时检测场景文本,并用多边形框出。它主要适用于两种模式:一种是处理输入图片并显示结果,另一种是基于指定的数据集做性能评估。

程序的核心流程分为以下几个部分:

定义命令行参数:用于获取从命令行传递进来的参数,如输入图像的路径,模型的路径,输入模型的高、宽,二值化阈值,多边形阈值,候选区域的最大数量,unclip比例,以及是否是评估模式等信息。

参数解析和检查:解析命令行输入的参数,并进行简单的检查,确保必要的参数没有遗漏,并且路径有效等。

载入文本检测模型:装载预训练的DB(TextDetectionModel_DB)模型。此外,还设置了模型的一些参数,如二值化阈值(binarizeThreshold)、多边形阈值(polygonThreshold)、unclip比例(unclipRatio)以及最大候选项(maxCandidates)等。

处理图像:通过Object Detection API的接口设置输入参数(scale、inputSize、mean),处理图像并使用网络模型进行文本检测。读取图片,对图片进行处理,并使用检测器检测图中的文本。

显示结果:将检测到的文本区域通过多边形(polyline)画在图像上,并显示出来。如果是评估模式,还会额外显示每个测试图像的标注信息。

如果是评估模式,程序还会处理一个包含多个测试图像路径的列表,对每个图像进行处理,并显示原始图像以及标注信息。

总的来说,此程序可以读取图片或从摄像头获取图像,然后应用一种深度学习文本检测方法高效地检测图像中的文本区域,并将检测到的文本用绿色的多边形框起来。在评估模式下,程序会在指定的数据集上运行,并显示性能评估结果,通常这涉及预测准确度的度量。程序最后通过OpenCV窗口展示检测的结果,如果是在评估模式下,则同时显示真实的标注框。

// 包含标准输入输出流库
#include <iostream>
// 包含文件输入输出流库
#include <fstream>// 包含OpenCV图像处理库
#include <opencv2/imgproc.hpp>
// 包含OpenCV高阶GUI处理库
#include <opencv2/highgui.hpp>
// 包含OpenCV深度神经网络模块库
#include <opencv2/dnn/dnn.hpp>// 使用命名空间cv,cv::dnn以简化代码
using namespace cv;
using namespace cv::dnn;// 字符串常量声明 (参数解析所需要的关键字和说明)
std::string keys ="{ help  h                          | | Print help message. }""{ inputImage i                     | td2.jpg| Path to an input image. Skip this argument to capture frames from a camera. }""{ modelPath mp                     | DB_IC15_resnet18.onnx| Path to a binary .onnx file contains trained DB detector model. ""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.}""{ 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. }""{ evaluate e                       |false| false: predict with input images; true: evaluate on benchmarks. }""{ evalDataPath edp                  | | Path to benchmarks for evaluation. ""Download links are provided in doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown}";// 定义一个用于字符串分割的静态函数
static
void split(const std::string& s, char delimiter, std::vector<std::string>& elems)
{// 首先清空传入的字符串向量elems.clear();// 初始化当前位置和之前位置变量size_t prev_pos = 0;size_t pos = 0;// 当能在字符串s中找到分隔符时执行循环体while ((pos = s.find(delimiter, prev_pos)) != std::string::npos){// 将分隔符之前的字符串添加到字符串向量elems中elems.emplace_back(s.substr(prev_pos, pos - prev_pos));// 更新之前位置为当前找到的分隔符之后的位置prev_pos = pos + 1;}// 当最后一个分隔符后还有字符时,将剩余部分添加到elemsif (prev_pos < s.size())elems.emplace_back(s.substr(prev_pos, s.size() - prev_pos));
}// 程序的主函数
int main(int argc, char** argv)
{// 解析命令行参数CommandLineParser parser(argc, argv, keys);// 提供脚本及其使用方法的简介parser.about("Use this script to run the official PyTorch implementation (https://github.com/MhLiao/DB) of ""Real-time Scene Text Detection with Differentiable Binarization (https://arxiv.org/abs/1911.08947)\n""The current version of this script is a variant of the original network without deformable convolution");// 如果未提供任何参数或需要帮助,则打印帮助信息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 modelPath = parser.get<String>("modelPath");double unclipRatio = parser.get<double>("unclipRatio");int height = parser.get<int>("inputHeight");int width = parser.get<int>("inputWidth");// 检查解析的参数是否有错误if (!parser.check()){// 如果有错误则打印错误信息并退出程序parser.printErrors();return 1;}// 载入模型CV_Assert(!modelPath.empty());// 构造文本检测模型对象TextDetectionModel_DB detector(modelPath);// 设置模型的参数detector.setBinaryThreshold(binThresh).setPolygonThreshold(polyThresh).setUnclipRatio(unclipRatio).setMaxCandidates(maxCandidates);// 模型输入的图像预处理参数double scale = 1.0 / 255.0;Size inputSize = Size(width, height);Scalar mean = Scalar(122.67891434, 116.66876762, 104.00698793);// 设置模型输入参数detector.setInputParams(scale, inputSize, mean);// 创建显示检测结果的窗口static const std::string winName = "TextDetectionModel";// 如果命令行参数中提供了评估模式开关if (parser.get<bool>("evaluate")) {// 进入评估模式// 从参数中获取评估数据集路径String evalDataPath = parser.get<String>("evalDataPath");CV_Assert(!evalDataPath.empty());// 构造评估数据集中的测试列表文件路径String testListPath = evalDataPath + "/test_list.txt";// 打开测试列表文件std::ifstream testList;testList.open(testListPath);// 检测测试列表文件是否成功打开CV_Assert(testList.is_open());// 创建一个用于显示真实标注信息的窗口static const std::string winNameGT = "GT";// 定义一个字符串变量用于存储测试图像路径String testImgPath;// 读取评估数据集中的图片列表,并进行处理// 进入循环,通过文件流逐行读取测试图片路径while (std::getline(testList, testImgPath)) {// 组合出完整的测试图片路径String imgPath = evalDataPath + "/test_images/" + testImgPath;// 打印图片路径std::cout << "Image Path: " << imgPath << std::endl;// 使用OpenCV函数读取图片Mat frame = imread(samples::findFile(imgPath), IMREAD_COLOR);// 确保图片读取成功CV_Assert(!frame.empty());// 复制一个frame以便后续的标注Mat src = frame.clone();// Inference// 存储检测结果的向量std::vector<std::vector<Point>> results;// 检测文本detector.detect(frame, results);// 使用多边形标注检测到的文本,并在窗口中显示polylines(frame, results, true, Scalar(0, 255, 0), 2);imshow(winName, frame);// load groundtruth// 从测试图片路径中除去后缀,获取图片名称String imgName = testImgPath.substr(0, testImgPath.length() - 4);// 组合出标注数据的完整路径String gtPath = evalDataPath + "/test_gts/" + imgName + ".txt";// 打开标注文件std::ifstream gtFile;gtFile.open(gtPath);// 确保标注文件打开成功CV_Assert(gtFile.is_open());// 存储真实标注数据的向量std::vector<std::vector<Point>> gts;String gtLine;// 逐行读取标注文件while (std::getline(gtFile, gtLine)) {// 检索到最后一个逗号的位置,因为之后的内容是文字标注size_t splitLoc = gtLine.find_last_of(',');// 提取文字标注String text = gtLine.substr(splitLoc+1);// 如果文字标注中含有忽略标记则跳过if ( text == "###\r" || text == "1") {// 忽略难识别的实例continue;}// 除去文字标注部分,只保留坐标数据gtLine = gtLine.substr(0, splitLoc);// 临时变量存储分割后的字符串std::vector<std::string> v;// 分割坐标数据split(gtLine, ',', v);// 存储解析后的坐标数据std::vector<int> loc;std::vector<Point> pts;// 将字符串类型的坐标数据转为整型,并逐点构造Point类型// 遍历解析完毕的字符串向量for (auto && s : v) {// 将字符串转换成整型并存储到整型向量中loc.push_back(atoi(s.c_str()));}// 从整型向量中构建Point对象,每个Point由一对坐标构成for (size_t i = 0; i < loc.size() / 2; i++) {// 创建点并添加到点集中pts.push_back(Point(loc[2 * i], loc[2 * i + 1]));}// 将点集添加到标准答案标注集中gts.push_back(pts);}// 在原图克隆图上标注真实的多边形文本区域polylines(src, gts, true, Scalar(0, 255, 0), 2);// 显示标注了真实文本区域的图片窗口imshow(winNameGT, src);// 等待任意键继续,用于暂停程序查看结果waitKey();}} else {// 如果不是评估模式,直接打开指定的图像文件CV_Assert(parser.has("inputImage"));// 读取指定路径的图像Mat frame = imread(samples::findFile(parser.get<String>("inputImage")));// 确保读取的图像非空CV_Assert(!frame.empty());// 存储检测结果的向量std::vector<std::vector<Point>> results;// 进行文本检测detector.detect(frame, results);// 将检测到的文本区域多边形轮廓标注在图像上polylines(frame, results, true, Scalar(0, 255, 0), 2);// 展示检测结果的窗口imshow(winName, frame);// 等待任意键继续,用于暂停程序查看结果waitKey();}// 程序正常退出,返回0return 0;
}

段代码实现了使用OpenCV和预先训练的深度学习模型来检测图片中的文本区域的功能。通过解析命令行参数,用户能够指定图片路径、模型路径、输入图片大小以及相应的检测阈值等参数。程序支持两种模式操作:

普通模式:用户指定一张图片,程序将检测图片中的文本,并将检测结果以绿色多边形框标注在图片上,并将其展示出来。

评估模式:用户指定一个包含多个图片以及对应文本区域标记的数据集,程序将检测这些图片中的文本区域,并将检测结果和真实的文本标记一起在窗口中展示出来,用以评估模型的检测效果。

代码中还包含了图片的加载、模型参数的设置以及窗口创建等辅助步骤。


http://www.ppmy.cn/server/6111.html

相关文章

【计算机网络】网络协议

概述 网络协议&#xff1a;网络协议是为网络中数据的传输和交换建立的一种规则、标准或者约定。 就像公共交通系统&#xff0c;开通了很多道路之后&#xff0c;驾驶员、行人等都需要遵守交通规则&#xff0c;来确保交通的正常运转。 网络中的协议就想交通系统中的交通规则&…

Springboot项目中Controller层的单元测试

源码展示&#xff1a; 原来的controller类&#xff1a; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.*;RestController RequestMapping("/web") Slf4j Service public clas…

react中关于类式组件和函数组件对props、state、ref的使用

文章中有很多蓝色字体为扩展链接&#xff0c;可以补充查看。 常用命令使用规则 组件编写方式: 1.函数式 function MyButton() { //直接return 标签体return (<>……</>); }2.类 class MyButton extends React.Component { //在render方法中&#xff0c;return…

速盾:cdn可以加速哪些服务器

CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是一种通过将网站的静态资源部署到全球各地的服务器上&#xff0c;以提供更快速、更可靠的访问体验的技术。CDN可以加速许多类型的服务器&#xff0c;包括但不限于以下几种&#xff1a; 静态资源服…

抓取电商产品数据的方法|电商平台商品详情数据|批量上架|商品搬家|电商封装API数据采集接口更高效安全的数据采集

大量级电商数据采集时使用电商API接口有以下优势&#xff1a; 1. 数据准确性&#xff1a;通过电商API接口获取数据&#xff0c;可以保证数据的准确性和实时性&#xff0c;避免了手动采集可能出现的错误和延迟。 2. 自动化采集&#xff1a;API接口可以实现自动化的数据获取和更…

Flask + Bootstrap vs Flask + React/Vue:初学者指南

好的&#xff0c;让我为你提供一个初学者指南&#xff0c;并附上一些示例代码来说明 Flask Bootstrap 和 Flask React/Vue 的使用。 Flask Bootstrap&#xff1a; 安装 Flask 和 Bootstrap&#xff1a; 首先&#xff0c;确保你已经安装了 Python 和 pip。然后可以使用 pip …

【PHP快速上手(十四)】

目录 PHP快速上手&#xff08;十四&#xff09;PHP 中常用数据库操作使用 WHERE 子句进行条件查询使用 ORDER BY 子句进行排序使用 UPDATE 语句更新数据使用 DELETE 语句删除数据执行事务总结 PHP快速上手&#xff08;十四&#xff09; PHP 中常用数据库操作 当使用 PHP 中的…