一、前言
老猿是个 C++的老程序员,到底有多老呢,估计现在各平台发技术文章的博主中,很难有年龄比老猿大的。程序员这个活,是年轻人干的,并不怎么适合象我这种年纪的人,工作中也很少需要自己动手开发的。
2019 年,各种因缘际会,老猿想学习一下 Python,4 月入住国内某程序员汇聚的知名技术博客,开启了老猿学习 Python 并分享学习体会之路,先是 Python 基础,接着是 Python 爬虫,然后是 Python 图像界面开发的 PyQt,再接着是 Python 的音视频剪辑 Moviepy,前后花费了 1 年半左右的时间,这期间发布了近 1000 篇博客,当然有灌水的内容,也有精华的文章,都是老猿自己学习的总结。
老猿是个对细节蛮纠结的人,很容易钻到各种学习的细节中去,优点就是有些深度的认识和收获,发布的博客文章有区别于别人的内容,缺点有两条,一是学习进展慢,二是有时耗时很久都钻不出某个问题,人很抓狂。不管怎么说,由于文章是老猿从小白的基础上去学习知识的总结,还是圈了一群粉,目前在博客网站粉丝已超 5 万,并且获得了该网站 2020 年博客之星评选的季军,也算是无心插柳了。
2020 年下半年,一个老同学联系老猿,他开办的公司主要负责计算机视觉应用类软件的开发,例如用于石油行业钻井平台的监控,识别违规操作,提醒作业人员遵章守纪,主要使用 OpenCV 和人工智能 YOLO3 进行开发。但是遇到了一些难以解决的问题,一是基于 AI 的目标检测,依靠训练数据产生的目标识别能力存在不可控的问题,可能绝大多数情况识别都没有问题,但一旦存在问题时很难去解决,无法说出所以然,二是目标识别在多目标出现交叉重叠时无法精准识别,如多个人用不同姿势前后交叉站立,后排人员被遮挡后有些场景无法识别出来每个人。他想基于 AI 的目标识别加上对象组件化来解决这个问题,利用 AI 识别各个组件,如人的脑袋、手、足、躯干等,然后再基于这些组件去识别一个人,而不是用 AI 直接识别一个人,这样应该更精确。
老猿对 AI 根本没有研究,连图像处理都没学过,感觉帮不上他多少忙,但他给我打开了计算机视觉这扇门,于是从 2020 年 8 月开启了计算机视觉的学习之路。
二、计算机视觉涵盖的范围
在介绍学习经历前,我们先简单介绍一下计算机视觉,而在研究计算机视觉前,一个必须探讨的课题就是数字图像处理,数字图像处理从简单的图像对比度增强到图像识别再到计算机视觉,从简单图像处理到 AI,涉及的领域跨度很大,并且没有明显的界限,但这一广袤的范围并不全都属于数字图像处理研究的范围。
一种常见的方法是将数字图像处理到计算机视觉这一广袤的范围划分成低级、中级、高级三个阶段:
- 低级处理:涉及图像的初级操作,如降噪处理、对比度增强、锐化处理,其特征是输入、输出都是图像;
- 中级处理:输入为图像,但输出是从图像中提取的特征,如边缘、轮廓、物体标识的识别;
- 高级处理:识别图像整体、与视觉相关的认知。
这一年多的学习,老猿学习进展缓慢,还停留在数字图像处理的低级处理的初始阶段,目前学习了图像处理的部分基础概念和一些基础操作,包括图像处理的步骤、像素间的关系、图像空间相关和卷积、图像滤波、灰度变换、形态变换、图像直方图等相关概念,以及图像读取、保存、鼠标操作、事件捕获、阈值处理、算术运算、图像形态变换以及直方图均衡等 OpenCV-Python 的操作方法。可见学习进展缓慢。
三、老猿的计算机视觉学习过程
老猿离开大学太多年,高等数学知识已经忘光,同时以前没有学习过图像处理相关知识,导致在计算机视觉学习过程中步履艰难。老猿这一年多的学习过程基本分为三个阶段:
- 老猿 2020 年 8 月开始学习 OpenCV,从基本的图像读写开始、到图像显示窗口的回调处理、阈值处理及自适应阈值处理、几何图像绘制、颜色空间转换到图像的算术运算、位运算、腐蚀膨胀等形态变换。在这阶段学习基本都很顺利,但形态变换中的击中击不中变换理解还是有些困难的,这个花了老猿 1 个多星期的时间才真正理解,这些知识的学习到 2020 年 12 月上旬;
- 2020 年 12 月开始学习仿射变换、透视变换,发现自己线性代数完全忘光了,导致仿射变换、几何变换难以理解,于是在 2021 年 1 月开始重新学习高数集合、极限、线性代数相关知识,学完再回头研究仿射变换、透视变换;
- 2021 年 4 月学习空间变换,发现自己图像处理基础知识太弱,理解相关知识太困难,为此从 4 月开始学习冈萨雷斯的《数字图像处理》,在学习到《数字图像处理》直方图处理概念时,发现需要导数和微积分的知识,于是 2021 年 6 月重头学习导数、微分、不定积分、定积分相关知识,到 2021 年 8 月才学习完这些数学知识,又开始学习直方图的相关知识,包括直方图基础知识、直方图匹配、局部直方图处理以及 OpenCV 的实现,到 10 月底学习到 OpenCV 对比度受限的自适应直方图均衡 CLAHE 算法时,发现存在几个没有想明白的地方,特别是关于 CLAHE 算法的插值处理,没有查到相关资料,只好下载源码,捡起已经丢弃了 10 多年的 C++,反复测试,花了 4 个月时间到最近才终于将 CLAHE 算法完全理解,关于这方面的介绍请参考老猿昨天的博文。
以上是老猿学习的艰难过程,导致这么进展缓慢的原因主要有三个方面,一是缺乏数学知识,二是没有好的可以指导的老师,三是老猿自己过于纠结,钻到一些很多人没关注的细节,并且不弄清楚不放弃,虽然从某种角度讲是个好精神,但在缺乏指导的情况下,这种方式效率太低。
四、学习计算机视觉需要的基础知识
以老猿现阶段已经学习的内容,谈谈计算机视觉学习需要掌握的基础知识,因尚在初级阶段学习,肯定不全,抛砖引玉罢了。
-
必须掌握好高数知识。计算机视觉和其他 AI 方向,都离不开高等数学
√ 图像的加减乘除、位运算、线性变换、图像相关与卷积、形态变换、仿射变换等,都与矩阵知识紧密相关;
√ 图像的集合运算需要用到集合运算相关知识;
√ 图像灰度变换用到的插值需要用到插值相关知识;
√ 图像灰度处理经常使用概率论相关知识;
√ 图像直方图处理需要了解直方图相关的概率统计知识以及微积分相关知识;
√ ......。
老猿大学毕业已经好多年,高数知识都忘光了,为此断断续续花了 4 个月时间将集合、线性代数、导数、微积分知识的基础知识全部重新学习了一遍,并且学习时自己被这些数学知识真正的吸引,比大学阶段的被动学习完全不可同日而语。所以如果大学刚毕业没多久,高数知识还在的同学,在学习计算机视觉和其他 AI 方向时就有很好的基础。
-
必须有好的 C++语言基础。计算机视觉及图像处理有多种开发库,这些库大部分都是 C++来实现的,因此掌握好 C++语言对于深入研究相关技术非常有必要。老猿使用的是 OpenCV 库,才开始使用的是 OpenCV-Python,如果是光应用库的 API 可以,但要理解其后的算法和技术则非要阅读 C++源码。老猿最近刚研究清楚 CLAHE 算法,查各种资料都解决不了自己的疑问,没办法只好安装 Visual Studio2019 的 VC++版本,下载 OpenCV 库源码进行研究才弄清楚,其中的插值算法就断断续续花了近四个月时间才终于弄明白(请参考《计算机视觉算法探究:OpenCV CLAHE 算法详解| 社区征文》);
-
必须有好的 Python 基础知识。现在的人工智能库,基本都是 Python 语言的,同时 Python 之上的开源库很多,包括 OpenCV 都有 Python 库,因此掌握 Python 是去进行实践验证的基础。如果尚未学习 Python 的,个人推荐《Python 基础教程》第 3 版(Magnus Lie Hetland 著,袁国忠译);
-
必须学习图像处理基础知识,这方面冈萨雷斯《数字图像处理》是很好的参考资料,建议中英文版本一起对照学习;
-
计算机视觉是当代人工智能的一大方向,了解人工智能和机器学习的相关基础知识对于计算机视觉的深入学习很有必要,这方面推荐 周志华编著的《机器学习》;
-
学习 OpenCV 相关的操作,这方面参考 OpenCV 官方文档的帮助文档即可;
-
......
限于见识,就计算机视觉需要的基础知识老猿目前仅能说这么多,希望于大家有益。
五、给准备学习计算机视觉的同好的三点个人建议
在上面介绍了老猿所知的学习计算机视觉需要掌握的基础知识,在这里要谈三点非技术方面的建议:
- 好好学习一下高数,特别是对于高效在校学生,如果想要在计算机视觉乃至人工智能方面有所建树,一定不要浪费学校的时光,学习好高数;
- 找个好老师,这个老师不一定是真正意义上的身份上的老师,只要是在计算机视觉和人工智能方面有杂实基础的先行者都可以,有个老师指导和自己瞎摸索完全是两个不同的学习状态,如果你有幸有这样一个老师,那应该好好珍惜这难得的机会;
- 不光是对程序开发感兴趣,而且要多学习点理论知识,计算机视觉乃至人工智能已经有很多系统化的理论知识,学习了这些理论知识再结合实操,进展肯定比单纯的程序开发要快和好。
最后,衷心祝愿所有学习计算机视觉的同好们在虎年学习进步,大展宏图!