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

2023-05-16

前言
接梦飞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的深度学习框架,以及lenet,CNN,caffe,tensorflow等,可能是识别效果和占用资源的关系,最新的openmv源码中深度学习框架只保留了tensor-flow;

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%以上;
总的来说,openmv采用的算法优化策略主要包括,ARM-cortex-M指令集优化(thumb指令集),内联汇编优化,定点化计算优化等策略,另外还在内存,flash,图像采集方法上做了很多优化;

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openmv底层算法剖析---梦飞openmv前传 的相关文章

  • 基于Python的ZED2教程 0.ZED2介绍

    本文主要介绍了ZED2的基本简介和硬件配置 基本简介 ZED2双目深度传感立体相机是位于美国旧金山Stereo labs公司制作的一款产品 xff0c 其与Kinect相机等流行的深度图像原理不同 xff0c 该深度相机的深度计算是通过双目
  • 基于Python的ZED2教程 1.打开ZED2

    本教程简单的对ZED相机进行了配置和打开 xff0c 然后打印出ZED 相机的串口号 xff0c 接着关闭相机 准备工作 由于ZED SDK在GPU上运算 xff0c 因此需要先在 nvidia com下载最新版的Cuda 然后 xff0c
  • 2.Open3D教程——文件读取和保存

    文件读取和保存 本教程演示了Open3D如何读写基本数据结构 1 点云 下面的代码读取和写入点云 span class token keyword print span span class token punctuation span s
  • 7.Open3D教程——表面重建

    在许多情况下 xff0c 我们希望生成密集的三维几何体 xff0c 即三角形网格 然而 xff0c 从多视点立体方法 xff0c 或深度传感器 xff0c 我们只能获得一个非结构化的点云 为了从非结构化输入中得到三角形网格 xff0c 我们
  • PASCAL VOC数据集

    一 简介 PASCAL pattern analysis statistical modelling and computational learning VOC visual object classes 该挑战赛的竞赛项目主要包括 图像
  • ubuntu python 通过奥比中光摄像头获取深度图片和彩色图片

    1 依赖 安装Openni Openni下载Openni添加至环境 xff08 要通过全局变量找到Openni头文件和库 xff09 安装primesense和openni pip install primesense pip instal
  • ROS tf使用报错:ImportError: dynamic module does not define module export function (PyInit__tf2)

    1 报错内容 Traceback span class token punctuation span most recent call last span class token punctuation span File span cla
  • ubuntu cuda cudnn tensorRT的卸载和安装

    1 安装显卡驱动 显卡安装教程 查看N卡驱动支持的最高cuda版本 nvidia smi 2 卸载 span class token function sudo span span class token function apt get
  • 初识VSCode

    Visual Studio Code xff08 以下简称vscode xff09 是一个轻量且强大的代码编辑器 xff0c 跨平台支持Windows xff0c Mac OS X和Linux 内置JavaScript TypeScript
  • Modbus通信及数据存储读取

    1 存储区代号 代码号功能1区输入线圈0区输出线圈3区输入寄存器4区输出寄存器 2 功能码 代码功能0x01读取输出线圈0x02读取输入线圈0x03读取输出寄存器0x04读取输入寄存器0x05写入单个线圈0x06写入单个寄存器0x0F写入多
  • 着色器语言 GLSL (opengl-shader-language)入门大全

    GLSL 中文手册 基本类型 类型说明void空类型 即不返回任何值bool布尔类型 true falseint带符号的整数 signed integerfloat带符号的浮点数 floating scalarvec2 vec3 vec4n
  • Data structure alignment (数据结构对齐 / 内存对齐)

    开篇的话 在比较老的编译器里 xff0c 如果没有对变量取地址的操作 xff0c 那么有些局部变量是通过寄存器保存的 xff0c 不占栈上内存 xff0c 根本不存在内存中如何排列的问题 xff0c 比如TurboC 2 0这种 在一些较新
  • C++primer plus和C++ primer的读书心得

    C 43 43 两本巨著primer plus和primer太过于经典 xff0c 以至于读过多次 xff0c 每次阅读仍然有新的收获 xff0c 所以将一些零碎的知识点整理在这里 xff0c 与大家共同进步 1 i 43 43 与 43
  • VINS 外参在线标定

    在VINS中相机的外参 R i c R ic R i c 是可以在线动态标定的 xff0c 实现函数为 xff1a 6
  • A-LOAM源码阅读

    LOAM 论文地址 xff1a https www ri cmu edu pub files 2014 7 Ji LidarMapping RSS2014 v8 pdf A LOAM地址 xff1a https github com HKU
  • LeGo-LOAM 跑通与源码学习

    论文链接 xff1a https www researchgate net LeGO LOAM 源码仓库 xff1a https github com RobustFieldAutonomyLab LeGO LOAM 本人注释 xff1a
  • SLAM中evo评估工具(用自己的数据集评估vinsFusion)

    目录 xff1a 配置标题文件修改源码修改第一处第二处第三处重新编译工程 安装evo1 安装命令2 常用指令 运行vinsFusion生成位姿估计文件使用evo评估轨迹 配置标题文件修改 主要根据自己的设备 xff0c 修改自己传感器的RO
  • Ubuntu中USB端口与外设绑定,ROS读取IMU模块数据

    目录 xff1a 1 根据设备ID绑定1 1 查看ID1 2 编写USB规则文件1 3 查看绑定结果 2 根据电脑USB口绑定2 1 找到USB端口名称2 2 编写绑定规则 3 通过ROS读数据 1 根据设备ID绑定 方法原理 xff1a
  • 实现外网Ping通WSL(网卡桥接方式实现)

    目录 xff1a 前言 xff1a 实现原理 xff1a 实现步骤1 开启hyper v2 编写桥接网络powershell脚本3 编写网络配置脚本 实现结果取消桥接最后 前言 xff1a 在我们经常和机器人打交道的这群人中有一个需求 xf
  • 如何在markdown中插入表情包

    我们平时经常使用markdown完成一些诸如博客的文档写作 xff0c 但是有时像我这种语言比较乏力的急需要在文档写作过程中插入表情包来完整的表达我想要表达的意思 xff0c 所以我去网上查了一下 xff0c 还真有 比如我想要表达开心即s

随机推荐

  • ROS多设备组网(WSL+miniPC+Nv Orin)

    目录 xff1a 前言硬件连接组网配置1 获取hostname和IP2 在主机添加从机的host信息3 在从机1中配置4 在从机2中配置 测试test1 话题订阅test2 rqt plot可视化传感器信息 最后 前言 实验室最近购买了两台
  • ZED 2i 双目-IMU标定

    目录 xff1a 前言IMU标定1 编译标定工具2 准备数据集3 标定 Camera IMU标定1 安装依赖2 编译Kaibr3 制作标定板下载标定板生成标定板target yaml文件 4 数据采集5 相机标定标定中遇到的问题问题1 xf
  • gazebo中给机器人添加16线激光雷达跑LIO-SAM

    目录 xff1a 前言1 下载雷达仿真包2 添加雷达支架描述文件3 添加雷达描述文件4 启动仿真5 添加IMU模块6 添加RGB D相机7 LIO SAM仿真安装依赖安装GTSAM编译LIO SAM运行 8 源码 遇到的问题1 error
  • ROS中的多线程使用

    目录 xff1a 单线程多线程订阅多个Topic xff0c 多个Spinner threads订阅一个Topic xff0c 多个Spinner threads订阅多个Topic xff0c 每个Subscriber一个Callback
  • 机器人端的图形界面ssh远程显示方案

    目录 xff1a 前言原理解析实现步骤机器人端 xff08 X client xff09 xff1a 1 安装一些必要的软件2 修改 96 etc ssh sshd config 96 中的四个地方 调试端 xff08 X server x
  • 报错 Key is stored in legacy trusted.gpg keyring

    目录 xff1a 1 找到警告相关源的key2 导出相应key到指定目录3 修改ros2源里指定加载key的路径 最近在安装ROS2的时候遇到一个关于密钥的报错 xff0c 这里记录一下 xff01 在 sudo apt update 的时
  • wsl中使用ROS工具rqt显示界面跑到窗口外面

    问题 xff1a 在WSL中使用ROS时确实会有一些小bug xff0c 比如下面这个 的rqt plot功能包时 xff0c 想通过rqt plot指令查看相应信息 xff0c 但是窗口弹出在窗口是空白的 xff0c 并且rqt那个功能界
  • RS雷达转Velodyne雷达数据Failed to find match for field ‘intensity‘

    目录 xff1a 问题分析解决 问题 因为目前很多SLAM框架支持的激光雷达都是Velodyne型号的 xff0c 对于速腾RS雷达的使用者来说 xff0c 需要对数据进行转换 xff0c 其实现在速腾的雷达已经支持输出XYZI和XYZIR
  • LIO-SAM中的mapOptmization

    前言 最近在学习LIO SAM源码的时候 xff0c 发现LIO SAM这套代码调用了比较多库的内置API xff0c 里面涉及的一些细节也比较多 xff0c 整个工程还是比较清晰的 xff0c 值得学习 xff01 LIO SAM这个框架
  • 使用D435i+Avia跑Fast-LIVO

    前言 最近Fast LIVO开源了 xff0c 之前看它的论文的时候发现效果很优秀 xff0c 于是用实验室现有的设备尝试一下 这里主要记录一下使用不带外触发功能的D435i 43 Avia跑Fast LIVO的过程 xff0c 为了适配代
  • CMakeList 中引用系统环境变量中的 include 文件,以及 lib 文件

    CMakeList 中引用系统环境变量中的 include 文件 xff0c 以及 lib 文件 cmake中对环境变量读写都是通过ENV前缀来访问环境变量 ENV ZLIB DIR 表示系统环境变量ZLIB DIR 所表示的路径 以ZLI
  • GroundTrue和里程计输出的位姿的参考坐标系不一致的情况

    这里写目录标题 前言数据集描述使用TF工具包获取使用Eigen库计算置换输出误差对比没做转换之前转换之后 前言 最近遇到一个数据集的ground true参考坐标和vSLAM输出的位姿的参考坐标不一样的问题 xff0c 记录一下 在之前参加
  • Protobuf报错CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):

    前言 Protobuf全称Protocol buffers xff0c 是Google研发的一种跨语言 跨平台的序列化结构的数据格式 xff0c 是一个灵活的 高效的用于序列化数据的协议 使用protobuf时 xff0c 既可以采用动态链
  • Ceres的自动求导实现原理剖析

    目录 数学原理实现原理总结 首先注意数值求导和自动求导在使用的时候的不同之处 实际上 xff0c 正是自动求导这个地方使用了类模板 xff0c 导致它不仅可以传入参数 xff0c 还可以传入Jet类型的数据 xff0c 从而实现了参数的雅可
  • SciPy 关于RBF插值出现Singular Matrix错误

    在使用SciPy的 RBFInterpolator 进行RBF模型插值时 xff0c 出现了Singular Matrix错误 xff0c 报错信息为 xff1a line 127 in build and solve system rai
  • Latex数学字体

    默认 mathsf mathtt mathit 花体 mathcal 空心体 mathbb
  • darknet训练自己的数据集

    参考博客https blog csdn net lilai619 article details 79695109 系统环境 Ubuntu 16 04 xff0d xff11 xff0e 在制作数据时最好先将所有图片重新命名 xff0c 这
  • 配置自己的ubuntu深度学习环境(ubuntu16.04)

    安装NVIDIA驱动 https blog csdn net xunan003 article details 81665835 安装CUDA xff08 最好是9 0 xff09 43 cudnn https blog csdn net
  • 用vscode配置C++编译环境(非常简单四步搭建)

    为什么会选择vscode 其实一直想用一下强大的vscode xff0c 最近正好想用C 43 43 刷题 xff0c 于是想在vscode上配置一下C 43 43 的编译环境 xff0c 用舒服的编辑器刷题应该会效率max也会坚持吧 但是
  • openmv底层算法剖析---梦飞openmv前传

    前言 接梦飞openmv博客 xff0c 本篇重点剖析openmv的算法和功能实现 openmv是国外开源团队依托mirco python架构开发的一套基于stm32内核优化算法的图像识别模组 xff0c 其目的是让图像视觉算法应用开发更加