openmv底层算法剖析---梦飞openmv前传

这篇具有很好参考价值的文章主要介绍了openmv底层算法剖析---梦飞openmv前传。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言
接梦飞openmv博客,本篇重点剖析openmv的算法和功能实现。openmv是国外开源团队依托mirco-python架构开发的一套基于stm32内核优化算法的图像识别模组,其目的是让图像视觉算法应用开发更加简便,算法运行效率更高,其底层代码全部由C语言实现,上层代码用micro-python开发。经问世以来,受到广大高校学生和开发者的追捧和喜爱,常常在电赛上使用,并且也可帮助快速学习嵌入式和图像识别;笔者作为openmv源码二次开发者和3年开发经验的嵌入式工作者,在此简单分析openmv的算法实现和其优劣势;

openmv集成了哪些功能?
(1)sensor驱动
作为一款机器视觉模块,支持多种摄像头是必须的,openmv开发了一套完整且有效的coms–sensor驱动框架,其核心数据结构是sensor功能结构体,包括sensor ID,分辨率,图像格式,sensor功能配置函数等,用结构体的方式定义了整个sensor的全部功能,在实现上只需要实现每个sensor对应得功能函数即可,方便接入各种不同的图像传感器;当然openmv也集成了很多其他硬件模块,如wifi模块,LCD,servo驱动,测距模块等,不过其硬件价格稍贵;
(2)图像处理算法
openmv上基本实现了大部分传统图像处理算法和机器视觉算法,具体包括图像滤波如均值滤波,中值滤波,盒子滤波,高斯滤波,拉普拉斯滤波等等,另外集成了整套RGB/YUV/以及灰度图像的颜色空间转换处理算法,其中包括LAB颜色空间变换,YUV颜色空间变换等;并且openmv上实现了基于sensor自带的3A算法和图像控制处理算法,如图像任意方向旋转,畸变矫正,透视变换,3D旋转等;
(3)传统图像识别算法
在色块识别上,openmv最常用的功能是色块识别算法,其实现方式是联通域标记,其算法优势是遍历一遍即可标记所有的联通区域,方便快速实现色块定位,支持灰度和LAB颜色标记;
在形状识别上,openmv基于霍夫变换算法实现了直线,圆,矩形识别等算法;
在常见标签和条码识别上,openmv集成了开源的zbar,quirc等用于二维码解码和条形码识别,支持datamatrix识别,另外还支持了apriltag标签识别,可用于目标3D标记和跟踪定位;
在目标跟踪上,集成了目标关键特征点keypoints标记orb算法,以及帧差分算法可用于移动侦测;
在特征算法上,集成了光流特征,HOG特征计算,边缘特征CANNY算法等
在模式识别上,集成NCC模板匹配算法,可进行任意模板匹配;
在传统机器学习算法上,openmv集成了haarcascade小波特征检测算法,可基于opencv训练的各种haar特征,将其转换成openmv支持的haar文件,支持任意目标的检测;
(4)深度学习算法
openmv集成了各种框架的深度学习算法,其中包括基于ST cube-AI的深度学习框架,以及CNN,tensorflow-lite micro等,由于CNN占用资源太大且不能使用CMSIS-nn推理加速,最新的openmv源码中深度学习推理框架只保留了tensor-flow lite micro;

openmv算法为什么能在单片机上运行这么快?
首先,openmv的算法是不同于opencv的,openmv的算法底层优化策略是基于ARM-cortex-M指令集优化的,其类似于采用ARM的NEON指令集作一些算法优化,由于单片机并不具备强大的DSP,GPU,NPU这些专用数字处理模块,stm32也仅集成了具备较弱DSP功能的FPU,支持单/双精度浮点运算;因此,想要让算法跑的更快,只能在单片机内核上和算法实现策略上下功夫。
(1)指令集优化
值得称赞的是openmv算法团队将传统的图像处理算法(如滤波算法),图像分割(联通域算法)等重新优化并实现了一遍。举一个简单的例子来说,openmv上实现卷积的方式是采用32位乘加指令smlad,利用内联汇编实现的优化计算,另外对于传统数学计算,也采用了内联汇编的优化方式,这是其算法运行效率得到大幅度提升的关键因素;
(2)定点计算优化
openmv做了很多定点化计算,也是就我们常用的查表法,进一步加快算法运算速度,将一些确定的计算和数据提前算好并保存在一个数组中,直接查表计算;
(3)数据处理优化
openmv在图像像素处理上做了很多优化,如取像素,存像素,数据转换等,最大程度上适应32位处理器架构;
(4)ROI感兴趣区域
openmv在算法运行上,支持roi区域计算,只取部分区域图像进行运算,方便多种算法配合执行,这也算一个优化项;
(5)图像前处理优化
由于openmv是顺序执行,先解析python代码,再调用C函数,由于sensor图像采集一般为RGB565的图像或者YUV的图像,要处理成算法直接能运行的图像,需要作一些图像格式转换,这部分图像采集和转换处理做了单缓存,双缓存,和三缓存优化,使得图像采集速度更快,并在DCMI中断中做图像格式变换,以及图像拷贝操作,最大程度提升图像前处理的效率,使得采集出来的图像直接进入算法处理环节;
(6)资源分配优化
由于stm32的分散内存特性,openmv将文件系统缓存分配给CCM快速内存,可以方便micro-python代码的快速读取和解析,这算一个隐藏的优化项,另外支持从底层图像缓存中分配内存用于算法计算,提高了内存的利用率,不管是flash还是内存,openmv在芯片的资源利用率基本上能达到90%以上;
(7)ARM-CMSIS加速
ARM公司提供了整套基于ARM-cortex系列的内核加速计算库,包括很多指令计算库,汇编计算,还有CMSIS-NN神经网络推理加速库,openmv使用的stm32单片机引用了ARM官方计算库,因此在一些复杂的计算上,能节省很大一部分时间,这也是openmv能运行一些AI算法的基本条件;
总的来说,openmv采用的算法优化策略主要包括,ARM-cortex-M指令集优化(thumb指令集),内联汇编优化,定点化计算优化等策略,另外还在内存,flash,图像采集方法上做了很多优化;

梦飞在openmv上做了哪些事?
前面的博客文章有介绍梦飞自己设计的openmv的硬件并自己开发了底层的固件,这里重点讲解梦飞在开发openmv底层代码上做的几件事:
(1)梦飞在openmv4上做了一些算法集成和硬件集成,其中算法主要为了保证openmv支持更多的机器学习和深度学习,在底层代码上,支持ST cube-AI运行的mnist手写数字识别(但是不能支持自己训练,自己训练之后要转换到底层才能使用,如果有需要我们会提供整套代码和模型转换方法),支持lenet,CNN训练的模型算法,支持最新的mobilenet训练的模型;另外,收集了很多haarcascade训练的模型文件,通过openmv提供的工具转换成cascade模型,可在openmv上运行,支持行人检测,口罩检测,车辆识别,车牌检测,笑脸检测,动物,水果检测等等;
(2)梦飞在stm32F407上实现了整套openmv代码的集成,基于openmv源码和自主移植支持了大部分openmv3支持的算法,进一步降低了openmv硬件的成本,并在其基础上开发了一些识别例程,其中包括颜色识别,二维码识别,巡线识别,基于模板匹配的数字识别,手势识别,标记识别,人脸识别等;还有基于haarcascade的行人,车辆,口罩检测等,除了不支持深度学习,其他很多基本的算法都能使用,能在一些对硬件成本较敏感的实际应用上使用,另外梦飞支持的摄像头和LCD价格也更低;

openmv的优劣势
在传统算法性能上,openmv运行的传统图像处理和图像识别算法确实具备很大的优势,前面也分析了其算法优化的策略和实现;特别表现在色块识别,条码识别等传统算法上,这可能是openmv能转换到实际应用上的一个优势;
但是其在深度学习上没有优势,一般带AI核的芯片都能运行一些大型的深度学习框架和网络模型,但是openmv一般只能运行轻量化的神经网络模型,就算使用带SDRAM的openmv4plus也只是在内存上占优势,依然不能运行像yolov3这样的网络模型,可想而知,硬件算力限制了其作为机器视觉模块的前景;
未来趋势,尽管openmv依托stm32芯片表现出其劣势的一面,但是不影响其未来发展,目前ARM已经设计了cortex-M55的架构,也就是说未来单片机是支持AI算力的,并且最新的openmv源码中已经开始集成cortex-M55的底层库,未来前景依然是客观的;
总结启示
openmv虽然是一个MIT开源且不受限制的项目,但是有人将其硬件注册商标并指定其为官方的做法限制了很多人的学习道路,至少对于那些资金有限而勤奋好学的学生是不公平的,在此,梦飞智能自主开发的硬件将持续发光发热,通过学习和开发openmv,对于个人能力和认知的提升和进步是非常有益的,在其C语言部分个人学到了非常多有用的知识,虽然短期内还未将其完全学懂学透,从长远来看学习它是一个不错的选择。文章来源地址https://www.toymoban.com/news/detail-638675.html

到了这里,关于openmv底层算法剖析---梦飞openmv前传的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 哈希表(底层结构剖析--下)

    由于哈希桶的本质就是一个存有结点指针的数组.所以哈希桶存储的数据类型便是结点指针类型. 哈希结点中包括两个内置成员: 1:K,V模型组成键值对pairK,V.(也可以是K模型) 2: 指向下一个结点的指针. 哈希桶的本质是一个指针数组. 其内置成员有两个: 1: 装有结点指针的vector. 2: 记

    2024年02月01日
    浏览(32)
  • 哈希表(底层结构剖析-- 上)

    1: 在顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系.因此,在查找一个元素时,必须要经过关键码的多次比较.我们知道顺序表查找的时间复杂度为0(N),平衡树中的查找的时间复杂度则为树的高度,即O(log2N),此时,搜索的效率取决于搜索过程中元素的比较次数

    2024年02月01日
    浏览(29)
  • ptmalloc底层原理剖析

    目录 一、概述 二、基础了解 2.1 32位进程默认内存布局 2.2 brk  sbrk  mmap 三、内存管理 2.1 结构 2.1.1 main_area 与 non_main_area 2.1.2 malloc_chunk 2.1.3 空闲链表bins 2.1.4 初始化 2.2 内存分配与释放 2.3 使用注意 三、ptmalloc、tcmalloc与jemalloc实现机制对比分析 ptmalloc是开源 GNU C Library (gli

    2024年02月16日
    浏览(38)
  • 深入剖析 Git 对象底层原理

    在我们日常使用 Git 时,通常的操作是: 在写完一段代码后,执行 git add 命令,将这段代码添加到暂存区中 然后再执行 git commit 和 git push 命令,将 本地 Git 版本库中的提交同步到服务器中的版本库中 Git 在中间做了什么,它如何存储不同的文件和内容,以及如何区分不同分支

    2024年01月20日
    浏览(47)
  • Spring Boot 常见的底层注解剖析

    Spring Boot 是一个用于创建独立的、基于Spring框架的Java应用程序的框架。它提供了许多注解,用于配置和定制应用程序的行为。以下是一些常见的Spring Boot底层注解的剖析: @SpringBootApplication :这是一个组合注解,用于标记一个主要的Spring Boot应用程序类。它包括 @Configuration 、

    2024年02月14日
    浏览(41)
  • 【C++干货铺】剖析string | 底层实现

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++专栏: C++干货铺 代码仓库: Gitee ========================================================================= 目录 成员变量 成员函数 构造和拷贝构造 赋值重载 析构函数 operator[ ] size 迭代器  rese

    2024年02月05日
    浏览(41)
  • Innodb底层原理与Mysql日志机制深入剖析

    大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。 主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器

    2024年02月21日
    浏览(42)
  • 【SpringBoot】| Spring Boot 常见的底层注解剖析

    目录 一:Spring Boot 常见的底层注解 1. 容器功能 1.1 组件添加 方法一:使用@Configuration注解+@Bean注解 方法二:使用@Configuration注解+@Import注解  方法三:使用@Configuration注解+@Conditional注解  1.2 原生xml配置文件引入 @ImportResource注解 1.3 配置绑定 方法一:@Component注解 + @Configu

    2024年02月17日
    浏览(42)
  • 【C++】深度剖析string类的底层结构及其模拟实现

    在上两篇中,我们已经学习了string类的一个使用,并且做了一些相关的OJ练习,相信大家现在对于string的使用已经没什么问题了。 那我们这篇文章呢,就来带大家对string进行一个模拟实现,这篇文章过后,有些地方大家或许就可以理解的更深刻一点。 那通过之前文章的学习我

    2023年04月17日
    浏览(107)
  • 【C++入门】STL容器--vector底层数据结构剖析

    目录  前言  1. vector的使用       vector的构造  vector迭代器  vector空间相关的接口  vector 功能型接口  find  swap  insert  erase 2. vector内部数据结构剖析 reserve  push_back和pop_back size、capacity、empty、operator[ ];  insert和erase resize swap  拷贝构造和赋值重载 构造函数补充  迭代器

    2024年01月25日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包