计算机视觉这种技术可以将静止图像或视频数据转换为一种决策或新的表示。所有这样的转换都是为了完成某种特定的目的而进行的。 输入数据可能包含一些场景信息,例如相机是搭载
输入数据可能包含一些场景信息,例如“相机是搭载在一辆车上的”或者“雷达发现了一米之外有一个目标”。一个新的表示,意思是将彩色图像转换为黑白图像,或者从一个图像序列中消除相机运动所产生的影响。
人类的视觉
因为我们是被赋予了视觉的生物,所以很容易误认为“计算机视觉也是一种很简单的任务”。计算机视觉究竟有多困难呢?请说说你是如何从一张图像中观察到一辆车的。你最开始的直觉可能具有很强的误导性。人类的大脑将视觉信号划分为许多通道,好让不同的信息流输入大脑。大脑已经被证明有一套注意力系统,在基于任务的方式上,通过图像的重要部分检验其他区域的估计。在视觉信息流中存在巨量的信息反馈,并且到现在我们对此过程也知之甚少。
肌肉控制的感知器和其他所有感官都存在着广泛的相互联系,这让大脑能够利用人在世界上多年生活经验所产生的交叉联想,大脑中的反馈循环将反馈传递到每一个处理过程,包括人体的感知器官(眼睛),通过虹膜从物理上控制光线的量来调节视网膜对物体表面的感知。
计算机的视觉
然而在机器视觉系统中,计算机会从相机或者硬盘接收栅格状排列的数字,也就是说,最关键的是,机器视觉系统不存在一个预先建立的模式识别机制。没有自动控制焦距和光圈,也不能将多年的经验联系在一起。大部分的视觉系统都还处于一个非常朴素原始的阶段。图 1 展示了一辆汽车。在这张图片中,我们看到后视镜位于驾驶室旁边。但是对于计算机而言,看到的只是按照栅格状排列的数字。所有在栅格中给出的数字还有大量的噪声,所以每个数字只能给我们提供少量的信息,但是这个数字栅格就是计算机所能够“看见”的全部了。我们的任务变成将这个带有噪声的数字栅格转换为感知结果“后视镜”。
图 2 给出了为什么计算机视觉如此困难的另一些解释。
图1:对于计算机来说,汽车的后视镜就是一组栅格状排列的数字
图2:视觉的不适定问题,物体的二维表示可能随着视点的不同完全改变
一个数学物理定解问题的解如果存在,唯一并且稳定的,则说明该问题是适定的(well-posed);如果不满足,则说明该问题是不适定的(ill-posed)。实际上,这一问题,正如我们之前所提出的,用“困难”已经不足以形容它了,它在很多情况下根本不可能解决。
给定一个对于 3D 世界的二维(2D)观测,就不存在一个唯一的方式来重建三维信号。即使数据是完美的,相同的二维图像也可能表示一个无限的 3D 场景组合中的任一种情况。
而且,前面也提到过,数据会被噪声和畸变所污染。这样的污染源于现实生活中的很多方面(天气、光线、折射率和运动),还有传感器中的电路噪声以及其他的一些电路系统影响,还有在采集之后对于图像压缩产生的影响。
在这一系列的影响之下,我们又该如何推动事情的进展呢?
在经典的系统设计中,额外场景信息可以帮助我们从传感器的层面改善获取信息的质量。
场景信息可以辅助计算机视觉
考虑这样一个例子,一个移动机器人需要在一栋建筑中找到并且拿起一个订书机。机器人就可能用到这样的事实:桌子通常放在办公室里,而订书机通常收纳在桌子里。这也同样给出了一个关于尺寸的推断:订书机的大小一定可以被桌子所收纳。更进一步,这还可以帮助减少在订书机不可能出现的地方错误识别订书机的概率(比如天花板或者窗口)。机器人可以安全忽略掉 200 英尺高的订书机形状的飞艇,因为飞艇没有满足被放置在木制桌面上的先验信息。
相对的,在诸如图像检索等任务中,数据集中所有的订书机图像都是来自真实的订书机,这样不合常理的尺寸以及一些奇形怪状的造型都会在我们进行图片采集的时候隐式消除——因为摄影师只会去拍摄普通的正常尺寸的订书机。人们同样倾向于在拍摄的时候将拍摄目标放在图片的中间,并且倾向于在最能够展现目标特征的角度拍摄。因此,通常也有很多无意的附加信息在人们拍摄照片的时候无意加进去。
场景信息同样可以(尤其是通过机器学习技术)进行建模。隐式的变量(比如尺寸、重力的方向等不容易被直接观测到的)可以从带标记的数据集中发现关系并推测出来。或者,可以尝试使用附加的传感器测量隐式变量的值,比如利用激光雷达来测量深度,从而准确得到目标的尺寸。
使用统计的方法来对抗噪声
计算机视觉所面临的下一个问题是噪声,我们一般使用统计的方法来对抗噪声。比如,我们很难通过单独的像素点和它的相邻像素点判断其是否是一个边缘点,但如果观察它在一个区域的统计规律,边缘检测就会变得更加简单了。
一个真正的边缘应该表现为一个区域内一连串独立的点,所有点的朝向都与其最接近的点保持一致。我们也可以通过时间上的累计统计对噪声进行抑制,当然也有通过现有数据建立噪声模型来消除噪声的方法。例如,因为透镜畸变很容易建模,我们只需要学习一个简单的多项式模型来描述畸变就可以几乎完美矫正失真图像。
基于摄像机的数据,计算机视觉准备做出的动作或决定是在特定的目的或者任务的场景环境中执行的。我们也许想要移除噪声或者修复被损坏的照片,这样安全系统就可以对试图爬上栏杆等危险行为发出警报,或者对于穿过某个游乐场区域的人数进行统计。
而在大楼中漫游的机器人的视觉软件将会采取和安全系统完全不同的策略,因为两种策略处于不同的语境中。一般来说,视觉系统所处的环境约束越严格,我们就越能够依赖这些约束来简化问题,我们最终的解决方案也越可靠。
OpenCV 的目标是为计算机视觉需要解决的问题提供工具。在某些情况下,函数库中的高级功能可以有效解决计算机视觉中的问题。即使遇到不能够一次性解决的问题,函数库中的基础组件也具有足够的完备性来增强解决方案的性能,以应对任意的计算机视觉难题。
在后一种情况下,也存在一些使用库的可靠方法,所有的这些方法都是从尽量多使用不同的组件库开始。通常,在开发了第一个粗糙的解决方案之后,就可以发现解决方案存在哪些缺陷并且使用自己的代码与聪明才智修复那些缺陷(更为熟知的说法是“解决真正存在的问题,而不是你想象中的那些问题”)。在此之后可以使用粗糙的解决方案作为一个评判标准,评价改善水平。从这一点出发,你可以解决任意问题。