您的位置:首页 > 理论基础

【小白学OpenCV】(零)——计算机图像基础

2016-03-05 23:29 309 查看
最近开始接触图像处理,开始学习大名鼎鼎的OpenCV。都说分享才是最好的学习,能用自己的语言向别人解释清楚才是真正的理解透彻了,所以我决定在学习的同时不断总结、在这里和大家分享自己的所悟。

学习OpenCV最好的教程应该是官方的教程文档了,在解压后opencv\build\doc下有tutorial和refman(接口介绍),但是都是英文写的,文字很多很密集,好吧其实我有密集恐惧症。所以我推荐大家看一下中文站点翻译的教程,快速入门,尽快建立整体框架概念,后续可以回过头有针对性的去看官方教程: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html。这里写的比较简单,很多算法并没原理解释,没有基础的筒子们会非常难理解。好吧,其实我初看的时候也是不懂,就让我来为大家做补充吧,保证一看就懂哦~~~

好了,不多啰嗦了,回到正题。图像处理或者说机器视觉,要处理的都是图像,所以咱们先不急着去搞OpenCV,先捋一下图像基础,温故而知新哈~

一、黑白2值(二进制图)

我们从简单说起,首先是80后童年的掌上游戏机那种,黑白2值的点阵图,如下图:



这种图片的原理非常简单:需要显示的小格子涂黑,背景白色,刚好就对应了计算机中的0/1两种状态了。这种用矩阵来表示就非常简单啦:这样就沿着”1“画出一根斜线了。这种图像的元素取值范围是0或1,所以就叫2值图了。

特点及应用:2值图是最简单的图像,体积小处理速度非常快,很多时候为了提高算法效率我们会使用2值图,而且很多函数要求的输入参数也是2值图。通常我们可以用阀值化、compare()、inrange等对矩阵的运算得到2值图。

二、灰度图

只有0/1明显是弱爆了,将元素的取值范围扩大,就成了灰度图。比如我们常用的8位灰度图,就是亮度值取值在[0,255]之间的整数,0代表纯黑,255代表纯白,中间的数值做过渡。这样的话,就能反应出颜色的深浅了。如下图:



这里就引出一个概念:图像的位深。对比矩阵的话,矩阵的元素的取值范围所对应的存储位数就是位深了。比如说8位无符号,那就是2的8次方,即256。16位浮点,32位这些都是一样理解的,位深越大就是说颜色表现的越精细,图片的体积也就越大了。

特点及应用:只有黑白色,以很小的体积来比较好地表现图像细节,处理速度较快,是图像处理中运用最广的一种图片。获取灰度图的方法很多,可以分离彩色图像得到、可以直接转换成灰度图等。

颜色空间缩减:为了提高处理的速度,我们很多时候并不需要那么高精度来区分亮度值。比如[0, 255]之间,[0, 9]这个区间内的值都用0表示,[10,19]之间都用10来表示等,这样就可以减少数据量,提高处理速度了。这里用了C++里面int类型除法自动截余的特点,new=old/10*10。如old=16,则new=16/10*10=1*10=10。通过这样的替换,就可以用26个数字代表256种亮度值了。

通常我们还会预先计算好所可能用到的替换值,然后通过查表赋值的方法来取代直接计算,为了进一步提高运算效率。

三、RGB图(RGBA)

接着就是彩色图了。色彩里面有个三原色:蓝、绿、红。这3种颜色不同比例的混合可以产生各种颜色。为了显示彩色,我们需要将上述矩阵的元素再扩张,改为由代表3个原色的值来表示。如下图(搬官方教程的,大家当做彩色的看吧):



简单点分一下就是:

这里就又引出了一个概念:通道。所谓通道,就是说你这个图片里面的每个点的颜色由几方面共同控制的。常见的RGB图片,每个点都是由红蓝绿3个原色控制的,所以就是有RGB3通道了。另外还有个RGBA通道的图片是怎么回事呢?这个A代表的是透明度,虽然说3原色已经可以表示所有颜色,但是在两张图片叠加的时候,透明度这个通道可以控制叠加的比重,得到我们想要的半透明效果。最简单的例子就是我要把一个圆形叠加到另外的图片去,计算机中图像都是矩形的,圆四周是有留白的。但叠加的时候留白是不要的,那可以在透明度通道设置为0,那在叠加的时候这里就不会出现留白了。这里跟掩码的效果是一样的。



特点及应用:符合人眼认知,包含的信息量大。

彩色图里面又有几种分类(不是说bmp、jpg、png这些图片格式哦),有RGB、HSV这些。

各个颜色系统,各有自身优势:

RGB是最常见的,这是因为人眼采用相似的工作机制,它也被显示设备所采用。
HSV和HLS把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
YCrCb在JPEG图像格式中广泛使用。
CIE L*a*b*是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的距离。

每个组成元素都有其自己的定义域,取决于其数据类型。如何存储一个元素决定了我们在其定义域上能够控制的精度。最小的数据类型是 char ,占一个字节或者8位,可以是有符号型(0到255之间)或无符号型(-127到+127之间)。尽管使用三个 char 型元素已经可以表示1600万种可能的颜色(使用RGB颜色空间),但若使用float(4字节,32位)或double(8字节,64位)则能给出更加精细的颜色分辨能力。但同时也要切记增加元素的尺寸也会增加了图像所占的内存空间。

PS:采用什么颜色系统要根据实际情况来决定,从运算效率的角度来看,我们一般不直接对彩色图做处理,所以我们要选择适当的颜色系统,然后通过分离或其他运算提取出包含信息最多的灰度图来进行处理。

关于图像的基础就先总结到这里,其他内容以后再来补充吧~~~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OpenCV 图像处理 C++