基于RK3576开发板的OCR文字识别算法
1. OCR笔墨辨认简介
笔墨辨认也是图象范畴一个罕见成绩。但是,关于天然场景图象,起首要定位图象中的笔墨地位,然后才干停止笔墨的辨认。以是普通包括两个步调:
笔墨检测:处理的成绩是那里有笔墨,笔墨的规模有几多。
笔墨辨认:对定位好的笔墨地区停止辨认,次要处理的成绩是每一个笔墨是甚么,将图象中的笔墨地区进转化为字符疑息。
我们的OCR算法是基于CTPN+CRNN设想的。CTPN是一种笔墨检测算法,能无效的检测出庞大场景的横背散布的笔墨,是今朝比拟好的笔墨检测算法。CRNN算法次要用于端到端天对没有定少的文本序列停止辨认,不必先对单个笔墨停止切割,而是将文本辨认转化为时序依靠的序列进修成绩,便是基于图象的序列辨认。
基于EASY-EAI-Orin-nano硬件主板的运转效力:
算法品种 | 模子巨细 | 运转效力 |
笔墨检测算法 | 3.31MB | 37ms |
笔墨辨认算法 | 6.19MB | 3ms |
2. 疾速上脚
假如您初度浏览此文档,请浏览:《进门指北/源码治理及编程引见/源码工程治理》,按需治理本人工程源码(注:此文档必看,并倡议采取【近程挂载治理】体例,不然有代码丧失风险!!!)。
2.1 开源码工程下载
先正在PC实拟机定位到nfs效劳目次,再正在目次中创立寄存源码堆栈的治理目次:
cd ~/nfsroot mkdir GitHub cd GitHub
再经过git东西,正在治理目次内克隆近程堆栈(需求装备能对中网停止拜访)
git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-3576.git

注:
* 此处能够会果收集缘由形成卡顿,请耐烦等候。
* 假如真实要正在gitHub网页高低载,也要把全部堆栈下载上去,不克不及独自下载本真例对应的目次。
2.2 开辟情况拆建
经过adb shell进进板卡开辟情况,以下图所示。
经过以下号令,把nfs目次挂载上nfs效劳器。
mount -t nfs -o nolock < nfs server ip >:< nfs path in server > /home/orin-nano/Desktop/nfs/

2.3 例程编译
然后定位到板卡的nfs的挂载目次(依照实践挂载目次),进进到对应的例程目次履行编译操纵,详细号令以下所示:
cd EASY-EAI-Toolkit-3576/Demos/algorithm-ocr/ ./build.sh

2.4 模子摆设
要完成算法Demo的履行,需求先下载法模子。
百度网盘链接为:https://pan.百度.com/s/1g4kpLTgMnYm1xop9LFeMIw?pwd=1234 (提与码:1234 )。
同时需求把下载的检测模子战辨认模子复造粘揭到Release/目次:
2.5 例程运转及结果
进进开辟板Release目次,履行下圆号令,运转示例顺序:
cd Release/ ./test-ocr test.jpg
运转例程号令以下所示:
后果图片以下所示:
API的具体阐明,和API的挪用(本例程源码),具体疑息睹下圆阐明。
3. OCR笔墨辨认API阐明
3.1 援用体例
为便利客户正在当地工程中间接挪用我们的EASY EAI api库,此处列收工程中需求链接的库和头文件等,便利用户间接增加。
选项 | 描绘 |
头文件目次 | easyeai-api/algorithm/ocr |
库文件目次 | easyeai-api/algorithm/ocr |
库链接参数 | -locr |
3.2 OCR检测初初化函数
设置OCR检测初初化函数本型以下所示。
int ocr_det_init(const char* model_path, rknn_app_context_t* app_ctx);
详细引见以下所示。
函数名: ocr_det_init | |
头文件 | ocr.h |
输出参数 | model_path:算法模子名字/途径 |
输出参数 | app_ctx:算法模子句柄 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
3.3 OCR检测运转函数
设置OCR检测运转本型以下所示。
int ocr_det_run(rknn_app_context_t* app_ctx, cv::Mat input_image, ocr_det_postprocess_params* params, ocr_det_result* out_result);
详细引见以下所示。
函数名:ocr_det_run | |
头文件 | ocr.h |
输出参数 | app_ctx:算法模子句柄 |
输出参数 | input_image:Cv::Mat输出图象 |
输出参数 | params:ocr检测算法参数 |
输入参数 | out_result:前往后果 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
3.4 OCR检测开释函数
设置OCR检测开释本型以下所示。
int ocr_det_release(rknn_app_context_t* app_ctx);
详细引见以下所示。
函数名:ocr_det_release | |
头文件 | ocr.h |
输出参数 | app_ctx:算法模子句柄 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
3.5 OCR辨认初初化函数
OCR辨认初初化函数本型以下所示。
int ocr_rec_init(const char* model_path, rknn_app_context_t* app_ctx);
详细引见以下所示。
函数名:ocr_rec_init | |
头文件 | ocr.h |
输出参数 | model_path:算法模子名字/途径 |
输出参数 | app_ctx:算法模子句柄 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
3.6 OCR辨认运转函数
OCR辨认运转函数本型以下所示。
int ocr_rec_run(rknn_app_context_t* app_ctx, cv::Mat input_image, ocr_rec_result* out_result);
详细引见以下所示。
函数名:ocr_rec_run | |
头文件 | ocr.h |
输出参数 | app_ctx:算法模子句柄 |
输出参数 | input_image:输出图象 |
输入参数 | out_result:前往后果 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
3.7 OCR辨认开释函数
OCR辨认开释函数本型以下所示。
int ocr_rec_release(rknn_app_context_t* app_ctx);
详细引见以下所示。
函数名:ocr_rec_release | |
头文件 | ocr.h |
输出参数 | app_ctx:算法模子句柄 |
前往值 | 胜利前往:0 |
掉败前往:-1 | |
留意事项 | 无 |
4. OCR检测算法规程
例程目次为Demos/algorithm-ocr/test-ocr.cpp,操纵流程以下。
#include < opencv2/opencv.hpp > #include < stdio.h > #include < sys/time.h > #include"ocr.h" using namespace cv; using namespace std; #define INDENT " " #define THRESHOLD 0.3 // pixel score threshold #define BOX_THRESHOLD 0.9 // box score threshold #define USE_DILATION false // whether to do dilation, true or false #define DB_UNCLIP_RATIO 1.5 // unclip ratio for poly type int main(int argc, char **argv) { if (argc != 2) { printf("%s < image_path >n", argv[0]); return -1; } /* 参数初初化 */ const char *img_path = argv[1]; Mat input_image, rgb_img; input_image = imread(img_path); if (input_image.empty()) { cout < < "Error: Could not load image" < < endl; return -1; } cv::cvtColor(input_image, rgb_img, COLOR_BGR2RGB); rknn_app_context_t ocr_det_ctx, ocr_rec_ctx; memset(&ocr_det_ctx, 0, sizeof(rknn_app_context_t)); memset(&ocr_rec_ctx, 0, sizeof(rknn_app_context_t)); /* OCR算法检测模型&识别模型初始化 */ ocr_det_init("ocr-det.model", &ocr_det_ctx); ocr_rec_init("ocr-rec.model", &ocr_rec_ctx); struct timeval start; struct timeval end; float time_use=0; /* OCR算法检测模型运行 */ ocr_det_result results; ocr_det_postprocess_params params; params.threshold = THRESHOLD; params.box_threshold = BOX_THRESHOLD; params.use_dilate = USE_DILATION; params.db_score_mode = (char*)"slow"; params.db_box_type = (char*)"poly"; params.db_unclip_ratio = DB_UNCLIP_RATIO; gettimeofday(&start,NULL); int ret; ret = ocr_det_run(&ocr_det_ctx, rgb_img, ¶ms, &results); if (ret != 0) { printf("inference_ppocr_rec_model fail! ret=%dn", ret); } gettimeofday(&end,NULL); time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//微秒 printf("time_use is %fn",time_use/1000); /* 截取文字信息和画框 */ printf("DRAWING OBJECTn"); for (int i = 0; i < results.count; i++) { printf("[%d]: [(%d, %d), (%d, %d), (%d, %d), (%d, %d)] %fn", i, results.box[i].left_top.x, results.box[i].left_top.y, results.box[i].right_top.x, results.box[i].right_top.y, results.box[i].right_bottom.x, results.box[i].right_bottom.y, results.box[i].left_bottom.x, results.box[i].left_bottom.y, results.box[i].score); line(input_image, Point(results.box[i].left_top.x, results.box[i].left_top.y), Point(results.box[i].right_top.x, results.box[i].right_top.y), Scalar(0, 255, 0), 1, LINE_AA); line(input_image, Point(results.box[i].right_top.x, results.box[i].right_top.y), Point(results.box[i].right_bottom.x, results.box[i].right_bottom.y), Scalar(0, 255, 0), 1, LINE_AA); line(input_image, Point(results.box[i].right_bottom.x, results.box[i].right_bottom.y), Point(results.box[i].left_bottom.x, results.box[i].left_bottom.y), Scalar(0, 255, 0), 1, LINE_AA); line(input_image, Point(results.box[i].left_bottom.x, results.box[i].left_bottom.y), Point(results.box[i].left_top.x, results.box[i].left_top.y), Scalar(0, 255, 0), 1, LINE_AA); cv::Mat rgb_crop_image = GetRotateCropImage(rgb_img, results.box[i]); /* OCR算法识别模型运行 */ ocr_rec_result rec_results; ocr_rec_run(&ocr_rec_ctx, rgb_crop_image, &rec_results); // print text result printf("regconize result: %s, score=%fn", rec_results.str, rec_results.score); } cv::imwrite("result.jpg", input_image); return 0; } 审核编辑 黄宇