三步就能在OpenHarmony中实现车牌识别

介绍

本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现。EasyPR 是一个开源的中文车牌识别系统,基于 OpenCV 开源库开发。

本项目使用润和 HiSpark Taurus AI Camera(Hi3516DV300) 摄像头开发板套件(以下简称 Hi3516)实现拍照车牌并显示识别结果。采用的系统是 OpenAtom OpenHarmony (简称“OpenHarmony”) 3.1 Release 小型系统。

首先将 Hi3516 中的摄像头对准车牌,其距离约为 60cm~70cm 如下所示:

运行程序后按下 1 拍照、按 2 输出识别结果如下所示:

开发流程

本车牌识别项目使用 OpenHarmony 中的媒体子系统实现。

代码基于停车场景下的本地车牌识别。进行讲解,其代码结构如下:

三方库移植

EasyPR 实现是基于 OpenCV 实现,因此实现 EasyPR 首先得移植 OpenCV。移植的方式采用 Gn 调用 Shell 脚本,Shell 脚本调用 Makefile 实现。

├── BUILD.gn
├── include 
│   ├── camera.h                                       // 摄像头定义
│   ├── local_net_communication.h          // 设备协同主要功能定义
│   ├── local_net_def.h                             // 设备协同打印日志
│   ├── local_net_dlist.h                            // 设备协同设备列表定义
│   ├── local_net_message.h                    // 设备协同传输消息定义
│   ├── local_net_udp.h                             // 设备协同udp协议定义
│   ├── local_net_utils.h                            // 设备协同通用工具定义
│   ├── log.h                                              // 打印日志定义
│   └── wpa_work.h                                   // wifi设置定义
└── src├── base64.cpp                                     // 图片转base64格式功能代码 ├── camera.cpp                                     // 摄像头实现├── local_net_communication.c            // 设备协同主要功能实现├── local_net_dlist.c                              // 设备协同设备列表实现├── local_net_message.c                      // 设备协同传输消息实现├── local_net_udp.c                              // 设备协同udp协议实现├── local_net_utils.c                              // 设备协同通用工具实现├── main.cpp                                         // 主程序└── wpa_work.c                                     // wifi设置实现

下面介绍移植的大致流程,具体细节可参考小型系统上运行开源项目车牌识别及移植 opencv 库。

移植OpenCV

下载源码

获取源码将 OpenCV 库源码放在 OpenHarmony 根目录下的 third_party 下:

生成Makefile

在 OpenCV 源码根目录新建 build 目录生成 Makefile 文件:

使用 cmake-gui 来配置编译环境:

cd build
make-gui ..

显示的 UI 界面如下图:

点击 Configure 进行配置,选择第四个选项进行配置,如下图:

配置工具链:

点击 Generate 生成 Makefile。

**创建 Shell 脚本 **

在 OpenCV 源码根目录新增 build_opencv.sh:

touch build_opencv.sh
chmod 777 build_opencv.sh
vim build_opencv.sh
##添加如下内容
#!/bin/sh
processor=`cat /proc/cpuinfo|grep processor | sort -u | wc -l`
cd build
make -j$processor
cp lib/* $1/libs/

创建Gn文件

在 OpenCV 源码根目录新增 BUILD.gn 将 OpenCV 库加入编译构建:

移植EasyPR

下载源码

获取源码 EasyPR 库源码放在源码根目录下的 third_party 下:

生成Makefile

在 EasyPr 源码根目录新建 build 目录:

mkdir build
cd build
cmake-gui ..

显示的 UI 界面如下图:

点击 Configure 进行配置,选择第四个选项进行配置,如下图:

配置工具链:

点击 Generate 生成 Makefile。

创建Shell脚本

在 EasyPR 源码根目录新增 build_easypr.sh:

创建Gn文件

在 EasyPR 源码根目录新增 BUILD.gn 加入至编译构建:

vim BUILD.gn#BUILD.gn中添加如下内容
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/ndk/ndk.gni")root_build = rebase_path(root_build_dir)build_ext_component("easypr_lib") {command = "sh build_easypr.sh $root_build"exec_path = "$root_build/../../../third_party/EasyPR"
}lite_component("easypr") {deps = ["//third_party/opencv:opencv",":easypr_lib"]features = []
}

最终 OpenCV 与 EasyPR 在 third_party 目录如下图所示:

在 OpenHarmony 实现 EasyPR 需要主要分为如下三步:

  1. GN 构建,将 EasyPR 加入编译构建;
  2. 拍照,调用 OpenHarmony 拍照接口,拍摄车牌;
  3. EasyPR 本地识别,调用 EasyPR 识别车牌接口并返回识别结果。

GN构建

GN 构建中包含了 EasyPR 的头文件路径 、链接 EasyPR 动态库、编译依赖 EasyPR。如下所示:

拍照

拍照功能是基于官方文档拍照开发指导开发的,其 demo 样例在如下目录:

在停车场景中二维码识别与车牌识别共用同一份拍照代码 ,为提高二维码识别率在拍照初始化时须将分辨率设置为 1280*720。该改动在进行车牌识别时不会影响 ,初始化拍照代码如下图:

设置照片保存路径在文件 camera.h 下:

因为在停车场景中二维码扫码与车牌识别都会调用拍照接口,因此使用 s_runAi 作区分:

int main(int argc,char **argv)
{int ret;char licensePlate[32] = {0};char input;InitCamera();PlateInit();while(cin >> input) {switch (input) {case '1':RunAICamera();                                                  // 拍照break;case '2':memset(licensePlate, 0, sizeof(licensePlate));ret = GetPlateString(IMG_PATH, licensePlate);   // 识别车牌SAMPLE_INFO("ret -> %d, licensePlate->%s", ret, licensePlate);break;case 's':PlateDeinit();ExitCamera();return 0;default:SAMPLE_ERROR("input Error");break;}}return 0;
}

进行拍照后会进入拍照数据处理,当 s_runAi 为 false 说明是二维码识别,直接调用二维码识别接口即可。当 s_runAi 为 true 时须将拍照的数据保存为图片:

将拍照数据以图片保存路径为“/sdcard/CaptureAi.jpg” 。

EasyPR本地识别

编写主程序 main.cpp 设置程序功能为按 1 拍照、按 2 显示结果 :

编译烧录

前文大致概括了 OpenCV 和 EasyPR 的移植步骤,更详细的关于环境搭建、烧录以及项目源码构建的步骤,请查看参考文章本地车牌识别。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对拍器/对数器 赛前抱佛脚

“对拍器/对数器的使用前提是该题你会暴力解法,如果不会,那么对拍器/对数器也没啥用。” 对拍器/对数器 应用背景 你有一个绝对对的暴力cpp代码,但时间会T,只适用于小范围的数据。所以你写了一个聪明的非暴力cpp代码&#xff0c…

【ctf.show】获得百分之百的快乐

1.打开靶场 2.根据页面代码,get请求值只能小于4位数,否则会回显hack! 尝试后确实是这样的: 请求值小于4位数,页面无变化: 发送请求值ls查看内容 3.根据2返回的值,发送值为?1>nl 创建一个nl…

vivado 使用基本触发器模式

使用基本触发器模式 基本触发器模式用于描述触发条件 , 即由参与其中的调试探针比较器组成的全局布尔公式。当“触发器模式 (Trigger Mode) ”设置为 BASIC_ONLY 或 BASIC_OR_TRIG_IN 时 , 即启用基本触发器模式。使用“基本触发器设置 (Basic Trig…

【面试题】细说mysql中的各种锁

前言 作为一名IT从业人员,无论你是开发,测试还是运维,在面试的过程中,我们经常会被数据库,数据库中最经常被问到就是MySql。当面试官问MySql的时候经常会问道一个问题,”MySQL中有哪些锁?“当我…

数据结构-----Lambda表达式

文章目录 1 背景1.1 Lambda表达式的语法1.2 函数式接口 2 Lambda表达式的基本使用2.1 语法精简 3 变量捕获3.1 匿名内部类3.2 匿名内部类的变量捕获3.3 Lambda的变量捕获 4 Lambda在集合当中的使用4.1 Collection接口4.2 List接口4.3 Map接口 HashMap 的 forEach() 5 总结 1 背…

第十三届蓝桥杯真题:x进制减法,数组切分,gcd,青蛙过河

目录 x进制减法 数组切分 gcd 青蛙过河 x进制减法 其实就是一道观察规律的题。你发现如果a这个位置上的数x&#xff0c;b这个位置上的数是y&#xff0c;那么此位置至少是max(x,y)1进制。一定要把位置找对啊 #include <bits/stdc.h> using namespace std; typedef l…

如何卸载干净 IDEA(图文讲解)

更新时间 2022-12-20 11:一则或许对你有用的小广告 星球 内第一个项目&#xff1a;全栈前后端分离博客项目&#xff0c;演示地址&#xff1a;Weblog 前后端分离博客, 1.0 版本已经更新完毕&#xff0c;正在更新 2.0 版本。采用技术栈 Spring Boot Mybatis Plus Vue 3.x Vit…

如何开辟动态二维数组(C语言)

1. 开辟动态二维数组 C语言标准库中并没有可以直接开辟动态二维数组的函数&#xff0c;但我们可以通过动态一维数组来模拟动态二维数组。 二维数组其实可以看作是一个存着"DataType []"类型数据的一维数组&#xff0c;也就是存放着一维数组地址的一维数组。 所以&…

【C++成长记】C++入门 | 命名空间、输入输出、缺省参数

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C​​​​​​​❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、C和C语言的区别和联系 二、命名空间 1、命名空间定义 2、命名空间使用 三、C输…

基于yolov9来训练人脸检测

YOLOv9是一个在目标检测领域内具有突破性进展的深度学习模型&#xff0c;尤其以其在实时性与准确性上的优秀表现而受到广泛关注。针对人脸检测这一特定任务&#xff0c;YOLOv9通过其架构创新和算法优化提供了强大的支持。 YOLOv9在继承了YOLO系列&#xff08;如YOLOv7、YOLOv8&…

二叉树--相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true 思路 一、…

JavaEE 初阶篇-深入了解 CAS 机制与12种锁的特征(如乐观锁和悲观锁、轻量级锁与重量级锁、自旋锁与挂起等待锁、可重入锁与不可重入锁等等)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 乐观锁与悲观锁概述 1.1 悲观锁&#xff08;Pessimistic Locking&#xff09; 1.2 乐观锁&#xff08;Optimistic Locking&#xff09; 1.3 区别与适用场景 2.0 轻…

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程 1.1、operator()的引入 现在需要完成这样一个需求&#xff1a;有一个函数每次调用返回的结果不一样。例如&#xff1a;两次调用的返回值都不一样那么就可以达到这种目的 1.1.1、简单点的写法 可以给一个全局的变量&#xff08;静态变量&#xff09;&#xff…

深入理解JVM垃圾收集器

相关系列 深入理解JVM垃圾收集算法-CSDN博客 目前市面常见的垃圾收集器有Serial、ParNew、Parallel、CMS、Serial Old、Parallel Old、G1、ZGC以及有二种不常见的Epsilon、Shenandoah的&#xff0c;从上图可以看到有连线的的垃圾收集器是可以组合使用&#xff0c;是年轻代老年代…

Input DropDown 拼接成 select组件(基于antd和react)

前言&#xff1a;为什么不直接用select&#xff0c;还要舍近求远搞inputdropdown这种缝合怪&#xff0c;是因为antd的select不支持选中项再编辑&#xff0c;效果如图 比如&#xff1a;选中的lucy文案变成了placeholder不能再编辑了 封装此组件虽然比较简单&#xff0c;但还是有…

PLC互连全攻略:Profinet和EthernetIP实操演示

在今日的技术分享中&#xff0c;将详细探讨实现Profinet和Ethernet/IP的通信配置&#xff0c;以连接西门子PLC&#xff08;Profinet&#xff09;和罗克韦尔PLC&#xff08;Ethernet/IP&#xff09;。本篇将重点介绍专为通信而设计的Profinet转Ethernet/IP网关&#xff0c;在联接…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件&#xff0c;它遵循JMS1.1规范&#xff08;Java Message Service&#xff09;&#xff0c;是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高…

【R语言从0到精通】-3-R统计分析(列联表、独立性检验、相关性检验、t检验)

上两次教程集中学习了R语言的基本知识&#xff0c;那么我们很多时候使用R语言是进行统计分析&#xff0c;因此对于生物信息学和统计科学来说&#xff0c;R语言提供了简单优雅的方式进行统计分析。教程参考《Rlearning》 3.1 描述性统计分析 3.1.1 载入数据集及summary函数 我…

【力扣题】关于单链表和数组习题

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

(Java)数据结构——图(第五节)Kruskal的实现最小生成树(MST)

前言 本博客是博主用于复习数据结构以及算法的博客&#xff0c;如果疏忽出现错误&#xff0c;还望各位指正。 Kruskal算法&#xff08;Kruskal的实现原理&#xff09; Kruskal算法的原理&#xff1a; 就是每次取最小的边&#xff0c;看看是不是与已经选择的构成回路&#x…