
私密文章
输入密码解锁内容
TL;DR: 本博客起初是想随便写一些教程,给个大概的学习方向,但在整理我过往收藏的资料和学习的视频发现,视觉需要学习多而杂,特别是进入Ubuntu后的学习,需要了解和学习的东西很多,因此考虑到后面实验室视觉的发展,以及给将来的新生以及现在大一同学做一个全面的知识体系是非常有必要的。最近我看到大一同学刚安装好了虚拟机并且学习 Linux 的一些命令,回想我安装好Ubuntu学习的时候,完全是摸着石头过河,东看一些西看一些,也是比较迷茫,不知道要学什么,非常的有感触。于是就有了这个我熬夜吐血整理的简单学习入门教程,里面记录视觉可以学习的入门内容,不是每个都要搞懂,主要是搭建学习框架,不至于不知道往哪个方向学习,里面有表述不清楚或者错误的地方,欢迎批评斧正。
前言#
其实关于视觉学习的教程,网上已经有很多了,但都不太齐或者杂乱,这里统一记录下。之所以写这篇文章主要是为了方便自己看以及给小登一个学习方向——不管怎么说有一个统一的资料存放总是很方便的,写此教程送给我们可爱的小登们。
这里整理的是学习的知识体系,不是全部都要学懂学会,基础篇大部分是要求会的,同时给你们对视觉学习有个系统的了解,先了解每个部分具体的作用,再根据实际情况学习,注意里面推荐学习课程链接有些是片面或者过时,大家可以根据关键词自行找最新的资料教程。
本教程涉及知识面广,大概对应电赛无人机题所要学习的知识,读者自行判断。可以先看常见Q&A部分。
视觉成员需要掌握的知识#
基础篇#
- 📖 编程语言 Python && C/C++
- 📖 基础计算机知识:进行一些基础知识的扫盲
- 📖 Ubuntu:基于Linux的开源操作系统
- 📖 Shell:Linux 下的脚本编程,自动化任务的基础
- 📖 Git:代码版本管理,团队协作必备
- 📖 CMake:跨平台的构建工具,管理 C/C++ 项目的编译
- 📖 IDE:推荐 VSCode,插件丰富,高度自定义,非常好用。
- 📖 计算机科学基础:了解计算机底层原理
- 📖 视觉模块/运算平台:了解 minipc、jetson 等硬件平台
- 📖 串行通信 & CAN 总线:下位机通信的基础
- 📖 基础数学知识:线性代数、概率论等
- 📖 Markdown:记录你的笔记,推荐 Typora 或 Obsidian
- 📖 OpenCV:计算机视觉核心库,图像处理的基础
- 📖 数学基础(进阶):坐标变换、Eigen 库、相机模型
进阶篇#
- 📖 卡尔曼滤波:状态估计算法,用于目标跟踪和传感器融合
- 📖 机器学习 / 深度学习 / 神经网络:PyTorch 框架,神经网络原理
- 📖 基于CNN的目标检测方法(YOLO):目标检测网络选择与训练
- 📖 防止过拟合:正则化、数据增强、早停法
- 📖 其他:行为树、并行运算、特征工程
- 📖 ROS2:机器人操作系统,节点通信、传感器接入、导航框架
- 📖 定位导航:Nav2 框架,SLAM、路径规划
- 📖 数据结构与算法:基本的数据结构和常用算法
- 📖 相机标定:成像模型、畸变校正
- 📖 相机参数:曝光、帧率、白平衡、分辨率等
- 📖 科学上网:获取国外技术资料的必备技能,如稳定访问 GitHub
参考的知识体系和学习规划#
下面是笔者推荐的构建知识体系以及大学规划方面非常好的文章和资料,读者可自行查看:
- 推荐硕哥的机器人工程师学习计划 ↗:对于机器人学习讲得非常好,整体偏向软件,很适合视觉/算法组的同学参考
- 计算机视觉知识框架图 ↗:RM视觉学习的思维导图,可以参考
- 西安交大生存指南 ↗:这个生存指南看完,还是深受启发,非常不错
- 机器人工程师学习计划 ↗,写给高中生:机器人行业发展路线 ↗,大学生机器人竞赛团队的组织 ↗:Lain-Ego哥写的,特别是机器人工程师学习计划,对机器人学习整体讲解醍醐灌顶,非常好。
遇到问题怎么办#
- How-To-Ask-Questions-The-Smart-Way ↗:详细地介绍了提问的艺术,良好的问题描述有助于他人了解你的情况
会提问是一个非常重要的能力,不只是向学长学姐提问,还有向老师,技术交流群,开源社区提问,如果你能提出一个好问题,别人看到也会非常乐意去回答。
比如说你遇到一个问题,不要直接找学长,问:学长学长,这个报错怎么解决?,这样我们又得问:你现在做什么遇到这个问题,你是怎么遇到这个问题的?然后你又一顿描述,一来一回,效率非常低,我们认识熟悉的人还好,如果是社区和技术交流群,别人看到可能都不想搭理你,热心的还会提醒你把报错贴出来,但这也是一来一回也会浪费很多时间。推荐读一下上面那个文章,比较短的,很快就能读完。
Vibecoding(氛围编程),编程是一种思想#
现在在诸如 Cursor、Claude Code、Trae 这样的 AI 代码编辑器兴起之后,一个新的概念开始出现,也就是氛围编程。作为氛围编程,就是给AI写代码,我们在旁边加油打气,等待他写好,不合适再让他改,体验一种氛围。哈哈哈,开玩笑。氛围编程,本质上是通过自然语言描述需求,让模型替你生成代码。这背后有一个值得思考的道理:编程语言只是外在的载体,真正驱动程序的,是解决问题的那套思维方式——这一点始终是相通的。
现在是 2026 年 6 月初,目前资源最多、便宜好用、资料教程最丰富的是 DeepSeek-V4-Pro + Claude Code 组合,可以在 VSCode 上面使用,它能看到你整个工程文件和代码,向它提问可以帮你架构和 debug,非常方便。至于如何配置,读者自行根据关键字查找相关教程即可。
不少读者对 AI 的使用还停留在豆包这类工具的层面——把代码复制进去,让它帮忙 debug 或给些建议。也有些读者对 AI 编程嗤之以鼻,不相信 AI 写出来的代码,甚至有些抵触或恐惧,毕竟 AI 编程看起来像个黑盒子,内部发生了什么完全看不清楚。在笔者看来,AI 编程如今已是一种趋势,AI 已经非常强大,但读者能力的上限就决定了 AI 的上限,所以提升自身能力是非常必要的。总的来说,AI 是一种工具,它放大了你的能力——你可以作为架构师去设计项目,它也可以是老师,不懂的问题向它请教。最好提问完记录下来自己遇到的问题,便于总结,因此做笔记是非常重要的。这里关于如何使用 AI,笔者不再过多赘述,仅仅表达个人的看法,仁者见仁,智者见智吧。
基础篇#
计算机科学基础#
- 参考 你缺失的那门计算机课 ↗:可以进行一些基础知识的扫盲,其中的前几个篇章都很有阅读的必要
- 计算机速成课 ↗:百万播放量的超人气课程,深入浅出短小精悍入门必看
- 模拟电路和数字电路速成 ↗:着重关注晶体管与逻辑门、数字逻辑电路层面的知识
- 学院派的计算机科学导论 ↗:广为流传的课程
编程语言 Python#
Python是一门非常方便的编程语言。它有大量的现成库可供调用,可以提高视觉算法的开发速度。Python入门非常简单,要大致明白动态类型的实现原理,知道Python对内存的管理方法。
下面一些学习资料,有时间打开编辑器敲一下即可,主要还是提升理解和debug。
- 廖雪峰Python教程(文档) ↗:适合入门的中文教程
- 小鱼视频 ↗:视频教程
- Python 3 教程-runoob ↗:菜鸟教程,适合查阅
tips:根据个人习惯,选一个看就行,不是全部都看完。
编程语言 C/C++#
面向对象编程是重要的编程思想,读者要理解并运用封装、继承和多态。可以利用C++11的多线程机制进行并发编程的程序开发,熟练运用这些新特性。 要求是:面向对象编程的思想;类的抽象和封装,构造和析构;类的继承和多态。 此外,C++11的一些新特性、标准库STL以及C++多种设计模式能够给算法构建带来很大的便利。
最好掌握C语言,并且能够将C++用作C with class的程度。
- C++教程:Cherno C++ ↗:高质量的现代C++教程
- 黑马程序员匠心之作|C++教程 ↗:适合零基础入门,我看的是这个。
- 推荐浙江大学翁恺教授 ↗:学院派风格
- C++多线程编程 ↗:进阶多线程
tips:新手不必在编程语言上斟酌得太过深入,可以在后续的应用实战中不断提高,毕竟编程语言只是人造的一门工具。 编程语言作为一种工具,在学习过程中最好能边学边动手,效果最好。
Shell#
Shell 是 Linux 系统下的命令行解释器,说白了就是你敲的命令,由 Shell 来解析并交给系统去执行。除了在终端里一条条敲命令,我们还可以把一系列命令写成一个脚本文件(.sh),让 Shell 自动批量执行——这就是 Shell 编程。
在日常视觉开发中,Shell 脚本能帮你做很多重复性工作:一键安装依赖、批量重命名图片、自动配置环境变量、写个脚本启动多个终端跑不同节点等等。掌握了 Shell 编程,相当于给你的 Linux 上加了个”遥控器”,让繁琐的操作自动化,省下时间去写更重要的代码。
- 掌握Shell编程,一篇就够了 ↗:知乎高赞教程
- Shell 编程快速入门 ↗:菜鸟教程
Linux下好用的的IDE#
VSCode:下载 ↗丰富的插件生态,配置完之后使用起来非常方便,上手容易且可定制化程度极高。
VSCode 的优势在于可以高度自定义和支持多种语言,学习 CMake 还能帮助你简化程序的编译、链接过程。VSCode 的插件也非常丰富,学会使用的话效率大大提高。不建议使用 Visual Studio 进行 C++ 的开发,虽然 VS 很方便但不便于移植代码。
Qt ↗:Qt也是一款跨平台的C/C++ IDE,在Qt上编写的GUI程序能够在所有平台上运行。用Qt可以方便地编写一些图形化的程序,比如串口调试助手、调参助手等。它的整体界面也算是比较清爽,适合新人使用。
Edge浏览器Linux版 ↗,可以方便同步 Windows 下的收藏夹、设置、插件等。集锦的功能非常好用。
Fsearch ↗和Windows下的everything类似,提供超快速的文件检索功能。
SimpleScreenRecorder ↗:一款录制屏幕的软件
qv4l2:Linux下相机驱动的图形界面,在Ubuntu软件商店可以找到,方便调节普通USB相机的参数。这里推荐使用qv4l2这款软件,可以方便的给相机调参并实时显示效果。
在 Linux 上使用 VSCode 进行代码编写已经完全能够满足了。 也推荐学习一下GNU工具链的使用和基本原理,至少熟悉编译、汇编、链接的过程。这样可以更深入的了解软件的运行,以便在开发过程中出现问题的时候,快速定位问题所在并找到解决方法。
视觉模块的学习#
常见的运算平台有这几种:定制的minipc、Intel NUC、jetson系列、DJI manifold2(有cpu版本和gpu版本,分别相当于同配置的i7-8265u的minipc和jetson tx2,不过manifold的体积很小)、工控主板/工控机、OpenMV、k230、k510等。其实选型的空间并不大,不过需要读者根据预算平衡一下性能和价格。
那么如何评价一个运算平台的性能呢,这里要提一下CPU和GPU运行的概念。CPU的时钟频率高,但是内部的运算单元(ALU、FPU等)数量有限,是为通用计算和程序控制所设计的,其实并不擅长进行大规模的并行运算,比较擅长单线程的流水线处理。GPU则相反,GPU有大量的低速运算单元,但是能够一次性处理巨量并行数据,因此尤其适合图形计算。
实验室目前(2026.06)有这两个模块:openmv 和 K230
OpenMV ↗:是一块专用视觉固件的 STM32 单片机(F7/H7 系列),本质是嵌入式视觉模块。它的优势是体积小、重量轻,使用 MicroPython 编程,门槛低、上手快。特别适合飞镖这类既要视觉识别又要兼顾运动控制的场景,也可以作为机器人的辅助视觉。不过受限于 32 位处理器,算力有限,跑不了复杂的深度学习模型,遇到高帧率、高分辨率需求会比较吃力。
K230:嘉楠科技(Canaan)推出的 AI 处理芯片,内置 KPU(Knowledge Processing Unit,神经网络硬件加速单元),可以在极低的功耗下高效运行神经网络推理。相比 OpenMV,K230 的 AI 算力高了一个量级,在同等价位和体积下非常有竞争力。同样支持 MicroPython(MaixPy)开发,适合对体积和功耗要求严格的嵌入式 AI 视觉场景,比如赛场上的目标识别、分类等任务。
对于这类视觉模块,不能只是跑官方的例程,想要学好,要去深入看官方封装好的库函数,了解常用库函数的内部结构原理,看懂,能知道怎么调用调试,以便根据题目跑出最大性能,因此能把这些视觉模块弄透也是非常好,非常厉害的,不必过度追求高性能开发板。
操作系统Ubuntu#
为什么使用Ubuntu?
Ubuntu是一个Debian系分支的第一大系统,是当前用户量最大的 Linux 发行版。因此,遇到任何问题一般都能够在用户社区 AskUbuntu ↗ 中得到解答。
Linux下开发C++程序相比Windows有无与伦比的优势,可以方便的配置各种第三方库和依赖。Linux的内核和上层系统都比Windows更加精简。Linux对于深度学习的支持比Windows更加友好,经常有sh脚本能够一键配置开发环境。
我们推荐下载并安装Ubuntu 22.04版本。使用Ubuntu作为开发时使用的系统,需自行安装,并且了解一些基本指令。
安装完Ubuntu后,各位需要熟悉Linux系统的一些基本命令行操作,如Ctrl+Alt+T打开一个终端,cd进入某个目录,sudo获取root权限,rm删除某个文件或文件夹等。初接触时可能觉得繁琐,但熟练运用后你会觉得特别便捷高效。
如果你此前没有开发经验,建议优先尝试虚拟机作为安装方式。也可以使用双系统安装,即Ubuntu与Windows共存。安装相对简单,且重启电脑即可切换系统。
想要安装Ubuntu,可以参阅这篇教程:Ubuntu/Windows双系统的安装 ↗。当然,学习时使用虚拟机也是不错的选择,这能给你更大的试错空间,不用担心把系统搞崩溃。
⚠️ 安装提示:双系统安装不当容易出问题,例如引导损坏、分区丢失,甚至影响 Windows 正常启动。建议安装前多方收集资料,比如去 B 站找些流程视频先看一遍,明确了步骤再动手,最好有一定的电脑基础。如果心里没底,优先选择虚拟机。
我的方案:我是用 Ventoy ↗ 制作启动盘,镜像选用 Ubuntu 22.04 ↗(清华镜像源),后面还需要关闭系统的一些安全设置,具体过程不过多赘述。
命令行操作学习:
- Linux 101 ↗:中科大Linux教程
- linux常用命令行操作 ↗:常用命令汇总
- Ubuntu Tutorial ↗:Ubuntu官方教程
提到Linux就不得不提到命令行的使用,在Linux上进行开发常会使用到命令行,有些软件甚至只有命令行界面的版本。在一些时候,直接在命令行中用键盘操作可能要比数不清的鼠标点击快得多。你需要学习:
- cd、ls、pwd、mv、cp、touch、diff、rm、cat、mkdir、rmdir、echo、tar等文件系统的基本操作,grep、find 查找文件和目录
- 帮助手册 man 和 —help 参数
- sudo、su、chmod 等权限相关的操作
- ping、ifconfig、wget 等网络相关的操作
一定要亲手熟悉命令行的基本命令,切忌只看不动手!学习以上命令,戳这里 ↗
在使用系统的时候,建议大家有良好的文件分类习惯,把代码库、软件、开发环境分开存放,避免出现home目录乱糟糟的情况。
Linux的设计哲学是**”一切皆文件”**。它将所有的IO设备如网络接口、usb接口、显示屏、相机、键盘鼠标、应用都视为文件,和这些“文件”的交互就是以规定的方式进行读写。因此,有必要了解Linux下的基本目录和文件组织方式,其目录结构请参考 ↗
如果学习C++可以看这个: Linux下的C++开发教程 ↗
代码管理工具Git#
Git是目前世界上最先进的分布式版本控制系统,用于有效、高速的处理项目版本管理。Git本身就完全可以做到版本管理,但是其所有内容以及版本记录都只能保存在本机。 在团队协作中,你可能需要与队友合作编写大量代码。反复更改代码很容易产生混乱,此时学会使用强大的版本管理工具Git便显得格外重要。
使用Git,你可以看到自己和队友每次修改的内容,出现问题时也可以退回到任意一次修改之前。代码会被实时推送到云端服务器仓库中,即使电脑惨遭弹丸攻击,代码也会安然无恙。
如果想要将文件内容以及版本记录同时保存在远程,则需要结合远程的服务器仓库,将文件和记录托管到远程仓库。
我们实验室开始的时候都是用u盘拷贝程序,或者QQ打包压缩发送,效率太慢了,多了如果没有命名好版本,还容易搞混。git来实现版本控制非常的方便,如果代码改动太多,改不回来,还可以回退到之前保存的版本,建议实验室的成员都来使用git,无论是日常学习项目还是比赛时都用得上。
tips: 新手学习git容易把git用成百度网盘一样作为一个代码远程保存仓库。但事实上git核心在于代码版本的提交回溯和多分支管理合并,在使用中应该多寻找网上的资料拓展认知以及与身边的人多多交流。在学习Git的时候,**一定要动手跟着一起实践,切忌光看不动!**俗话说熟能生巧。
- Git命令行操作 ↗:官方文档,最权威
- 廖雪峰的git教程 ↗:中文教程,通俗易懂
- git简易指南 ↗:快速入门
- GitHub Guides ↗:GitHub官方指南
- 给傻子的Git教程-哔哩哔哩 ↗:视频教程
常用代码托管平台:gitee, github
CMake学习#
在 Linux 下开发 C++ 项目,通常不直接写 Makefile,而是使用 CMake 来管理构建过程。CMake 通过读取 CMakeLists.txt 文件自动生成 Makefile,支持跨平台编译,管理第三方依赖也非常方便。建议在 Ubuntu 下学习,和实际开发环境一致。
- CMake教程 ↗:视频教程
- cmake入门极简教程 ↗:快速入门
- CMake 保姆级教程 ↗:详细讲解
- CMake书籍 ↗:电子书
串行通信#
常用下位机通信方法之一串口(Serial Port)。为了方便简单起见,我们使用的都是异步串行通信,通过一个usb转串口芯片将解算好的数据发送。请参考 ↗
永久赋予串口权限,可以参考我的另一篇文章:串口权限配置。
CAN&总线通信#
这里我们简要介绍最常用的CAN。 CAN通信的基本知识:和串口一样,必然也需要一个通信协议。不同的是,其信号是通过其总线上电平的差值来表示的,这样能够有效抑制共模信号(因为噪声对两条线的影响通常是一样的,相减之后噪声的影响便被消除了),因此一般采用两条通信线。不过也最好连接地线,共地可以最大程度降低干扰。还有4-pin的CAN线,额外的一条线用于独立供电,适用于对信号质量特别高的场合,此电源专门为CAN收发器和信号电平供电。
基础数学知识#
高等数学、线性代数以及概率论是必修课。 网上有大量的相关课程,可以观看 MIT 的相关课程,即 高等数学-18.01 ↗、高等数学-18.02 ↗、线性代数-18.06 ↗。 在课程学习中容易在众多教程里面迷失方向,还没怎么开始学习就在挑选课程中看花了眼,不如花上一周先学完再说。 在这里笔者推荐 宋浩 ↗ 的相关课程,属于按照国内课程的教学大纲进行的常规讲解,尽管说不上鞭辟入里,但是胜在详细。同时对于线性代数这门可以理解为几乎最重要的数学课程,同样推荐读者观看 3Blue1Brown 的相关讲解 ↗。
推荐: 线性代数 ↗+3Blue1Brown 的线性代数的本质 ↗:不局限于国内教材的纯计算教学,国外课程能帮你理解概念本质,而不是只会套公式做题
机器人学基础 ↗:贯穿运动学、动力学、规划和控制的主线.
OpenCV#
视觉图像处理是视觉组最常见的工作内容,基于OpenCV开源视觉库进行图像处理是重点的学习内容,它是当前最具影响力的计算机视觉开源库。官网资料相当完整。 OpenCV最推荐的学习资料还是官网文档,其内容详尽、更新速度快。
在大部分时候我们都不需要设计底层的算法,而是直接调用封装好的API,设计更具体的应用于特定问题的算法。当然,有必要了解一下造轮子(底层算法的实现)的过程,这能够让我们深入理解算法内部的构造,从而更好地使用这些算法,出错的时候也能更快定位问题。如果只是调用API而不了解原理,那么只是简单的缝合+搭积木,对于提升自我的思考能力和逻辑思维没有任何帮助。应当要有*“使用科技的黑箱会使我惶惶不安”* 的觉悟。
我们最常用的OpenCV和一些神经网络模型都是开源的,它们都有优秀的注释和说明文档,尤其是OpenCV的Documentation和Tutorial十分详细,全是使用doxygen生成的标准文档系统。通过阅读这些材料,很快就能上手。
PS.大家可以适应阅读英文资料,因为后面开发中遇到的一些问题很难用中文查到。
image process
你需要安装OpenCV,可以参考Ubuntu下OpenCV+contrib模块完全安装指南-NeoZng ↗
若你要在多视图几何以及3D视觉上开发深度学习的应用,可以使用Kornia ↗,这是一个基于python/pytorch打造的兼容pytorch的库,其中使用到的数据使用pytorch基本的数据结构tensor。
书籍推荐阅读:《OpenCV4.0快速入门》
- 安装教程 ↗:Ubuntu下安装OpenCV
- OpenCV视频教程 ↗:B站视频教程
- OpenCV官网学习文档 ↗:官方文档,最权威
- RM 教程3-OpenCV 传统视觉 ↗:RM专项教程
- 东南大学的OpenCV入门教程 ↗:高校教程
tips:我是看了**OpenCV视频教程+《OpenCV4.0快速入门》**后面时间紧张就去做项目,也完全够了,不会的再去查找学习,大家也不要有看完全部再做项目,边做边学是最好的。
数学基础#
机器人的眼睛是相机。相机的作用就是将三维的真实世界投影到二维的图像数据中。我们需要在算法中利用降维的数据进行识别处理,使得机器人对三维世界具有一定的感知。
那么如何将三维世界降维到二维平面,又如何从二维平面反推到三维世界呢?这便是线性代数的一个重要应用——坐标变换(映射)。三维世界,我们一般称为世界坐标系(或笛卡尔坐标系),而相机图像的二维平面,一般称为像素坐标系。
如果考虑图像的深度信息、视角大小,我们就可以获得相机的三维坐标系。通过一些固定点在不同坐标系中的坐标,我们便可以通过旋转、平移变换获得坐标系之间的相对位姿,进而获得机器人的位姿。
数学基础在坐标变换中有很深的应用价值,在特征提取、数据处理(如卡尔曼滤波)中也有重要的应用。
在计算线性代数中的常用运算时,Eigen库是你提高计算速度的好帮手。这个库有丰富的接口来让你进行欧拉角、四元数、旋转矩阵、矩阵求逆等运算。此外,还可以方便地与OpenCV中的数据类型进行相互转换。
进阶篇#
卡尔曼滤波#
卡尔曼滤波是一种基于状态空间模型的最优估计算法,能够在存在噪声的测量数据中估计系统的真实状态。在 RoboMaster 中主要用于目标跟踪——通过历史观测数据预测装甲板的运动轨迹,即使短暂遮挡也能保持追踪。此外在传感器融合(如 IMU 与视觉数据融合)中也有广泛应用。
- 教程 ↗:图文并茂的教程
- 全网最简单!三小时搞懂【卡尔曼滤波】原理及代码实战 ↗:视频教程
- 卡尔曼滤波器 ↗:知乎详解
机器学习#
深度学习 PyTorch#
我们推荐使用Pytorch作为深度学习框架。如果你的笔记本电脑没有显卡或者显存较少,可以尝试仅仅安装它的CPU版本。如果你的电脑安装了可以跑深度学习的显卡,可以尝试安装好对应的开发环境,比如cuda、ROCm。
- Pytorch中文文档 ↗:官方中文文档
- cuda安装指引 ↗:NVIDIA CUDA安装
- 动手学深度学习书籍 ↗:非常推荐的一本书
类似还有 TensorRT、Openvino
神经网络#
- A visual proof that neural nets can compute any function ↗:直观解释神经网络如何拟合任意函数
- 3Blue1Brown神经网络 ↗:可视化讲解神经网络
基于CNN的目标检测方法(YOLO)#
网络选择 当下的最优选择大概是416x416(追求速度)、512x512(权衡)或640x640(精度)。320x320的模型速度虽然快,但是对远处的小目标效果明显下降(除非使用变焦相机或者双相机的策略),mAP也要远低于前述的三个模型。
推荐使用NanoDet进行上手,对新手的友好度非常高,且官方的ROCO数据集(下面马上会介绍到)就使用了COCO标注格式,可以直接进行训练。并且作者提供了各种推理框架的部署demo,包括OpenVINO、Tensorrt、MNN、NCNN、Mega-engine等等。其他的网络包括YOLOv5、YOLO-Fastest、上述的YOLOX以及百度的PicoDet都是可以尝试的对象
准备数据集 常见的数据集规范有COCO和VOC,也有简单的txt(yolo格式)
下面就是配置环境,训练,由于版本差异和笔者没有深入了解,就不叙述了。
防止过拟合#
正则化 Dropout正则化(随机丢弃)
数据增强 以图像分类为例,通过将训练集中的图像进行翻转、反转、裁切、旋转、变形和添加色彩偏差等方法来扩充数据集,是最廉价最简单的防止overfit的方法。虽然其效果不如收集更多的图片来得好,可架不住成本低、几乎无开销的特点。在小规模训练集上,数据增强是最有效的方法之一。
Early Stopping(提前停止、早停法) 非常容易极致简约的方法,如果训练的轮数过多导致模型过拟合了训练数据,那就减少训练轮数。在训练集上过度优化会导致过拟合
其他#
ROS2#
ROS2全称机器人操作系统,是用于构建机器人应用的软件库和工具集。其中的节点编写,节点通信、话题发布与订阅、节点参数等概念非常重要,建议系统学习。
我们可以非常方便且安全地通过编写多个节点的代码来实现多进程编程(注意区别于多线程),它也提供用于获取、编译、编写和跨计算机运行代码所需的工具和库函数。
ROS2提供了大量的工具,如:用于检测每个节点的发布频率和信息类型的许多命令行工具,可视化工具rviz,用于数据可视化的rqt_plot,用于仿真的gazebo,用于标定相机内参的工具等等。
使用Ubuntu 22.04作为开发环境,并直接选用ROS2-humble进行开发。需要注意的是,ROS与Ubuntu的版本是一一对应的,比如Ubuntu 20.04对应的是ROS-Noetic,ROS2必须要22.04以上的版本才能安装。
它们的设计理念是类似的,从ROS1迁移到ROS2只会让你感觉无比轻松方便。若你对ROS不熟悉,请直接开始ROS2的学习。通过ROS2,我们可以方便地构建视觉算法和建图定位、导航算法的框架,轻松接入各种传感器。
- ROS2 Wiki ↗:若有良好的阅读学习习惯,强烈推荐
- ROS2中文文档 ↗:中文翻译版
- 动手学ROS2视频 ↗:视频教程
定位导航SLAM#
在ros2环境下的Nav2项目力求以安全的方式让移动机器人从A点移动到B点。我们的导航基于Nav2项目进行自主研发,在这个过程中需要完成动态路径规划、计算电机的速度、避免障碍、恢复行为。实现导航的大致过程包括建图、定位、路径规划、相关参数调试。
环境:Ubuntu22.04 humble版本
学习渠道:鱼香ros2官方文档动手学ROS2 (fishros.com)
- SLAM框架 ↗:视频教程
- 局部路径规划 ↗:CMU开源项目
- 常用的全流程导航框架 ↗:Nav2官方仓库
- Nav2 — Nav2 1.0.0 文档 ↗:官方文档
tips:对于slam部分,笔者没有过多的项目经验,只看过动手学ROS2视频,目前也正在学习,有什么不对的地方,请谅解。
数据结构和算法#
个人认为没有必要专门买算法书来看,在实践中遇到相应的问题,查找资料即可。
- 推荐浙江大学的mooc ↗:浙大数据结构课程
- 算法基础简介 - OI Wiki ↗:可以当工具书查,过于复杂和艰深的算法没必要学习
- Data Structure Visualization ↗:算法和数据结构执行过程的可视化
相机标定#
相机标定来去除这种畸变以便还原图像中物体的真实位置。畸变主要分为切向畸变和桶型畸变,我们可以利用标定板和畸变的数学关系来进行相机标定,OpenCV中也有相关的函数可供调用。关于成像模型、畸变和标定,可以参阅相机标定 ↗和OpenCV官方文档中的CameraCaliberation ↗。在后续章节中我们还会提到这一点,并且给出了提供标定流程的参考文章。
- OpenCV相机标定完全指南 ↗:详细的标定教程
相机参数#
曝光:每一帧图像的感光时间,其值愈大则画面的整体亮度越大,曝光时间过长过短都可能会出现宽容度不够的情况(一片雪白或是漆黑无比),选择正确的曝光是算法能否奏效的关键。如传统的灯条特征选取算法就要求恰当的低曝光以保证灯条不会出现过曝而显现白色但同时又要能够看清装甲板中间的数字以便进行模板匹配、svm分类或其他数字识别;运用卷积神经网络的目标检测算法则需要相机采集到的画面能尽量接近数据集中图片的情况,一般来说需要高一些的曝光。
帧率:相机每秒钟能够获取的图像数。一般来说,如果你的图像处理算法的速度够快,那么帧率越高越好,这能够保证你处理结果的实时性。一些相机提供了硬件触发 功能,这样能够让相机以固定的时间间隔触发采样,保证两帧之间的时间相同,以便于和机器人的控制进行时间线同步。视觉算法处理、数据传输、电控算法处理、再到控制执行机构动作,最后子弹在空中飞行——这几个过程中都有时间延迟,累加之后算是非常可观。高速的算法和确定的延迟时间是打造预测算法的基础。
白平衡:设定白色是怎么样的“白”,本意是不管在任何光源下都让原本呈现白色的物体通过增加偏置而还原为白色。涉及到色温和颜色空间的概念,调节此参数即调整RGB三原色的混合比例。
图像保存格式:图像的编码方法,如JPEG, RGB, YUYV, YUY2等,不同的编码格式保存的信息量可能有差别。我们会在 5.0 节进一步了解相关信息。
分辨率:一张图像的像素数,常见的有1920x1080,1280x720,640x480,一般来说,分辨率越高则图像保留的细节就越多,但同时相机处理的数据量变大,会降低采集帧率和每秒传输的图像数量。在之后的图像处理中,同样意味着更大的开销和处理速度下降。
增益:调节感光单元在进行电荷信号放大时的增益(gain,一般是用dB表示的,这需要你注意数量级),对于图像的亮度和各颜色信息的保存都有影响。在低曝光的时候可以有效提高成像质量,但同时也可能提高噪声(不规则噪声信号也会被放大)。
对比度:图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,在高动态范围和高宽容度的时候,提高对比度可以凸显图像中亮度不同部分的区别,相当于用一把刻度更精细的尺子去测量物体能够得到更精细度量信息。某些情况下,提高对比度所指的则是直接增加亮暗之间的差别,让亮部更亮,暗部更暗。
饱和度:是HSV色彩空间中的概念,代表了一种颜色的纯度(Saturation)。
如果你能学到这里,你已经具备独立开发视觉程序的能力了,什么车牌识别也就不在话下了。
科学上网#
GitHub 有些读者可能进不去,Windows 系统的读者可以下载一个 Watt Toolkit(原 Steam++),开启加速后通常就能正常访问。Linux 下使用 Watt Toolkit 访问 GitHub 笔者试过但没能成功,可能是步骤有误。有能力的读者可以自行搭梯子,这里不过多阐述。
GitHub 是全球最大的开源社区,里面有大量优质项目、模板和学习资源,如ladder软件,简历模板,PPT制作方法等等,还有众多大佬的学习项目,推荐大家多多查找和利用,会有意想不到的效果。
有用的网站和资源#
- html ↗,css3 ↗,javascript ↗:前端学习
- ProcessOn ↗:方便画流程图和各种图,也推荐 VSCode 的 Draw.io 插件
- MathPages ↗:进阶数学知识的学习
- 力扣 ↗:刷题
- w3school 在线教程 ↗:W3C组织的在线学习教程
- 在线LaTeX公式编辑器 ↗:快速编写Latex公式,还提供了公式识图
- Wolfram|Alpha ↗:智能搜索引擎,计算数学问题
- SimpleTex - Snip & Get! ↗:公式OCR识别,好用准免费
- Kaggle ↗:数据科学竞赛平台
- Sci-Hub ↗:学术期刊下载,配合学校数据库使用
- 世纪图书馆 ↗、z-lib.org ↗:找电子书
常见Q&A#
欢迎补充。如果你有问题,也可以提出。
看完这个教程,感觉视觉要学的东西好多好难,怕自己坚持不下来,配个环境都快劝退,电赛真的要学这么多吗?
对于电赛视觉来说,三个方案:
-
目前主流的 K230 或同级别产品(如 MaixCam)已经基本能满足视觉要求,根据官网的教程,无论是识别还是训练,基本够用了。但不能只是跑官方的例程,要去深入看官方封装好的库函数及内部原理,以便根据题目发挥出最佳性能。
-
在1的基础上,加个树莓派或同性能的产品,运行opencv,帧率可以跑的更高,比如25年E题。
-
对比前面两个,买个minipc(带显卡驱动的,如n150)或者jetson nano,跑YOLO模型推理,或跑opencv,性能已经过剩。
-
前3个是对于控制题小车,这里控制题飞机,由于要上激光雷达,最低也得要树莓派,能再往上换个更好的最好,本篇更多知识点,包括ROS2,导航等等,是根据飞机题用到的知识点来写的。 如果只是小车题,准备K230,树莓派+opencv或yolo已经足够。
-
如果你时间充裕,对这方面感兴趣,推荐学习基础篇+机器学习神经网络那就行,之后再往ROS2建图导航这些方面学习。
-
根据自己的实际情况来。Linux 学习需要投入不少时间,如果离比赛时间紧迫,选用 K230 这类视觉模块是更务实的方案——部署简单、上手快,不需要折腾 Linux 环境。
视觉学习的成长路线确实比较长,要点的技能较多,不过只要按照顺序,把基础知识学好,往后的学习就不会有太大困难。如果你一上来就想要装Linux系统想要安装OpenCV,然而连计算机是怎么工作的都不清楚,那必然是难过登天的。当你觉得某些事物无法理解的时候,基本上不是所谓智商或者能力的问题,而是缺少前置知识。所以一定要从基础开始学习。
学视觉还要不要学 STM32?
非常有必要,但可能没有你电控写代码队友那么深入,但是也要正常学习大部分,能够自己做小项目,对于他的代码你至少能看懂个七七八八,最好全部能看懂,甚至帮他debug,写代码,还有一点是,串口部分最好你来写,不然收不到数据又要被压力,太苦了。 学习 STM32 得到的正反馈比视觉学习是要更多了,有句话说的好,视觉正确配置好环境已经完成一半了,在Linux上辛辛苦苦配的环境突然崩了,只有视觉的同学才能体会到。总之,多学一点总没错。
自学的效率太差,而且学完很快就忘了,学不会怎么办?
自学效率低、知识易遗忘,是很多人都会遇到的问题。如果纯自主学习难以坚持,可以搭配线上视频课程,跟着讲师的节奏推进。 自学最大的短板是缺少课后练习,学完知识点一定要立刻动手实践,以编程学习为例,看完教程务必亲手敲写代码,切忌只看不练。结合艾宾浩斯遗忘规律,知识只有反复使用,才能真正记牢。 想要提升效率、加深记忆,还可以搭配这些方法:及时整理笔记、撰写学习文档;学完一个内容后试着讲给他人听,或是输出学习博客,借助 “教学相长”或者说费曼学习法 巩固知识,慢慢摸索出适合自己的学习节奏。
参加电赛要花的时间多吗,会不会影响课内成绩?
抛开电子设计竞赛带来的附加价值不谈,参赛所需掌握的单片机、机器视觉等内容,大多不在课内教学范畴,需要利用课余时间自主学习。而备赛是否会影响课内成绩,因人而异。 一方面,竞赛知识能反哺课内学习:备赛过程会推动你把课本知识落地实践,在拓展学习的同时,也会对基础概念产生更深的理解。同时,竞赛内容高度依赖高等数学、物理等基础课程,这也会倒逼你夯实课内功底。但另一方面,竞赛中有不少知识与课堂学习无关,对文化课成绩提升并无帮助,这也是客观事实。 此外,备赛必然会占用课内学习的时间。如果你的首要目标是提升成绩、争取高 GPA,为保研或留学做准备,那就应当缩减竞赛投入,重心放在课内学习与习题训练上。投入竞赛的时间越多,留给预习、复习、消化课堂知识的时间就越少。因此需要结合自身的时间管理能力与学习效率,综合权衡。 电赛领域里,既有学业、竞赛、科研全面发展的优秀选手,也有因全身心投入比赛而荒废课内学业的案例,并不赞同后者。建议你先明确自身目标,再合理分配各个方向的时间与精力。
不少人会疑惑:电赛所做的内容日后能否派上用场?参与其中是不是单纯为了比赛而比赛??
课堂所学知识未必都能在未来落地应用,但只要深耕相关领域,电赛积累的单片机开发、PCB 设计技能与实操经验,在后续科研和职场中都能发挥实际作用。暂且不谈思维方式、做事方法上的提升,单看学到的技术就不难发现:如今视觉相关技术早已融入生活与产业。人脸识别随处可见,自动驾驶行业蓬勃发展;手机相册可自动分类图片,相机能实时识别、标注画面物体;以图搜图、AI 自动生成视频字幕、解析视频内容已是常态;AI 绘画、文案创作能力比肩人类;图像修图、美颜技术更是普及大众。与此同时,工业领域也在全面智能化,大型生产车间实现自动化运转,人力被智能设备逐步替代。小到各类智能硬件、终端设备,大到工业控制单元,都离不开单片机与 PCB 电路作为硬件根基,而软硬件结合、视觉应用、电路设计这些热门技术方向,正是电赛会接触和实践的内容。
有时候不想去实验室怎么办?
不想去太正常了。人大概都是贪图安逸的,我也不例外。刚进实验室的时候,我也满心只想抱大腿,只要没人催,我也不想上去。社会学里有个说法叫”责任分散效应”——人一旦身处集体之中,承担责任的意愿就会悄然下降。好像只要不去碰它,困难就追不上自己似的。
但逃避是会累积的。拖得越久,落下的越多,再去面对的时候反而更难。我现在回头看,那些真正让我成长的时刻,无一例外都是硬着头皮坐到工位上之后发生的。哪怕那天只写了几行代码、只调通了一个小模块,也比躺在床上刷手机强——不是因为效率高,而是因为你没有让”不想去”赢。
所以我没有太好的办法告诉你怎么克服惰性,只有一个笨办法:别想,去就行了。到了实验室,事情自然会开始。
而且环境是会推着你走的。当你坐在工位上,旁边的人在调代码、在焊板子、在讨论方案,你很难一直无所事事地刷手机。这种氛围不需要谁来督促,它本身就是一种隐性的约束。反过来,一旦你连续几天不去实验室,脱离了这个环境,再想捡起来就需要更大的意志力。所以与其在宿舍跟自己较劲,不如先把自己扔到那个环境里去——让环境替你完成最难的那一步。
不过说到底,硬逼自己也好、借环境的力量也好,都只是手段。真正能让你心甘情愿坐到工位前的,是你对这件事的热爱。当你真正喜欢一件事的时候,“不想去”这个问题本身就不存在了。你不是在逼自己,而是迫不及待。如果你现在还没有找到这份热爱,也不必焦虑——先去做,做着做着,热爱会在某个瞬间悄悄降临,后面纯粹为爱发电了,自然就不会觉得累。
后记#
以上是对计算机视觉的一些理解和拙见,管中窥豹,欢迎交流。