数字图像处理不得不知的点(1)

数字图像处理不得不知的点(opencv)

【如有问题,欢迎讨论或斧正】

比较杂,但是都还比较重要


一、读图并显示:

//IplImage跟的显示方式
IplImage *img = cvLoadImage(argv[1]);
cvNamedWindow("Example1", 0);
cvShowImage("Example1", img);
cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("Example1");

//Mat 的显示方式
Mat img = imread("logo.jpg");
namedWindow("游戏原画");
imshow("游戏原画", img);
waitKey(0);

//相同点,都可以在那么后面添加0或者1来让用户决定是否要选择用鼠标对图像进行缩放显示。


二、什么是像素

比如右击一幅图片->属性。

可以看到横向是154个像素

数字图像处理不得不知的点(1)_第1张图片

什么是widthStep

就是这个图片这一行所占的字节数。

对于这个widthStep = width*通道数【彩图是3,灰图是1

像素:


像素就是图像元素 原来写作picture Element你发现就是图片元素,然后这样太长了,然后发明了一个合成词 叫pixel,为了可能是发音或者什么的习惯吧,比如你知道一个单词叫做:breakfastlunch,然后就有了一个早午饭的名词:branch。都是这样。对于计算机来讲,很多颜色点,拼合在一起就是你看到的图像,其实美术中,我记得当时学水彩的时候,有一个点彩的作业。老师说有颜色的互相渗透,一个深色的葡萄酒瓶上面不可能只是深色,必然有灯光以及其他地方映到瓶子上的浅色,如果你这个视角后面是白色的墙,那么就应该把很少的白色点在瓶子上,同时白色的墙上也应该有深色瓶子的印记,并且两个色区越是靠的近这种渗透就要越多,如果越远渗透就越小。想说的是,计算机采用图像点的方式并非没有依据,相反我的没有学过计算机的美术老师都在教我们使用点彩这种绘画方式,就可见其具有一定的原理。【并且点彩也应该不是近代才有,所以我猜早在文艺复兴时候就有这样一个美术的分支领域开始启蒙。】

 

既然认为图像的确可以有像素点,也就是图片元素点组成。那么每一个点怎么标定,也就是一个点是怎么组成的?如果是彩色图的话,描述着一个点需要三个通道的信息。为什么是三个通道?什么是通道?如果是灰图的话需要一个通道的信息。


感觉还是什么也没说,简单点儿理解:像素就是就是图像的基本元素,是一个点。一堆有意义的点的排列就是我们看到的计算机图片。

 

三、通道:

http://baike.baidu.com/link?url=by-P1h_WijBBeiLykB-eohOqZowdxV9Pzos9SDy5rXQDZ3M23JjZwhuD1pnuOemZZzxM8XII4mu8bT_o6h4MIJk5EJstTL6JA4xaFl9lmYy

这个里面解释的比较详细,简单来讲,就是某一种颜色空间对于图片的描述方式。什么是颜色空间?举个简单的例子来了解什么是颜色空间:我们小学美术知道三原色是红黄蓝,学习水彩也是红黄蓝,通过这三个基本颜色,我们可以按照比例来调配出我们想要的任何一种颜色,那么对于这种描述方式来讲,他就有三个通道,通过红黄蓝来描述一个颜色的比如我们知道 黄色+蓝色=绿色,那么对于绿色的描述就是R(红色)Y(黄色)B(蓝色)(0,100,100)由于本身黄色和蓝色的浓度也不相同,如果我们设从0-255表示一个黄色从不黄到很黄,【我们忽略不黄这个颜色到底是什么,(但是假设不黄是很淡的白色)这很复杂,也就是为什么有必要引入颜色空间这回事儿,看了颜色空间你就会发现,这个真儿没有必要较。因为描述颜色本身十分复杂】那么我们可以通过改变YB的颜色来决定这个绿色是浅绿和深绿,并且(0,200,200)一定会是一个比0,100,100深的绿色。

 

所以通道就是用来描述一种颜色时,需要的信息的维度,对于红黄蓝这种描述方式来说它的通道就是3,对于后来中学时候学习的物理里面涉及的红绿蓝它的通道就是3.对于CMYK这种描述方式来说它的通道就是4,对于lab它的通道就是3.所以我们需要具体来聊聊什么是颜色空间。

 

四、颜色空间:


为什么要有颜色空间:

所以看了这个图也就是想说的红是RGB255,0,0)但是不红,就很难说,白色 也是不红,黑色也是不红。还有一种不红,叫做有一杯水,我们加了红墨水。调到很浓,然后加水不断稀释,这个跟白色的那种红,也有区别,区别在于,白色的红不透光,而加水稀释的这种红后面是什么东西可以透过去。甚至我给你一个绿色,我问你,红么?你当让会回答不红。这就是这个不红很难界定的原因,也因此有很多种色彩空间都来描述这件事。


简单理解就是一种用以描述颜色的系统。空间的某一个位置可以唯一标定一个颜色。这样就会比较好理解。我们知道三维空间可以描述一个位置信息,那颜色空间,就可以唯一标定一个颜色。

常见的这种描述颜色的空间的系统有RGBCMYKHSVHSILAB等等。

http://baike.baidu.com/view/3427413.htm  //颜色空间

http://baike.baidu.com/view/974298.htm   //色彩空间

http://baike.baidu.com/view/1048787.htm  //色域

 有很多词条都来描述同一个东西。所以,不要较真儿,我们的重点不在这里,重要的是对于我们计算机要来操作来讲,或者编程来讲要理解的东西并没有这么多。


1、RGB(红绿蓝)

2、BGR(蓝绿红)

我们要理解的范畴大概限定在《学习opencv(中文版)》这本书的第67页的内容,知道了RGBBGR之后。发现后面有东西是RGBA,这个里面多了一个通道Aalpha),也就是透明度的意思,我记得在ps里面,从0-1表示透明度的变化,从透明到不透明。或者反过来。忘记了就是比原来多加了一个通道。现在还没用到。

 3、GRAY(灰)

接下来有一个转GRAY的,也就是变成灰度。通过一种计算方式,把彩色图变成灰度图。作为灰度图其实就黑白灰颜色的变化。

cvCvtColor(img, img4, CV_RGB2GRAY);

从彩图到灰图。

从灰图到黑白图:

cvThreshold(img4, img3, 0, 128, CV_THRESH_OTSU);

函数原型:

CVAPI(double)  cvThreshold( const CvArr*  src, CvArr*  dst,

                            double  threshold, double  max_value,

                            int threshold_type );

 【更多关于这个函数:http://www.cnblogs.com/letben/p/5459571.html】

根据上面的说法,那么灰度图其实只要一个字节来描述,从0255,所以是一个通道。因为一个值就可以描述清楚了。


然后是RGB565 RGB555,这个东西当时我是真的很萌比。其实还是原来的RGB只不过原来用一个字节的8位来表示颜色,现在用更少的位数来描述一个通道的数值大小。对于RGB555来说,就是每个颜色都用5位来描述。RGB565就是描述GREEN的时候用6位。

 

http://baike.baidu.com/link?url=JCKDvUfedXp3KXVPV8fqgRCGtW5VTUznPip9YAZKTnwsluC0vqZuLlQ3BZZd6lpL

 4、XYZ

3定义了CIE XYZ基色系统:与RGB相关的相像的基色系统,但更适用于颜色的计算;//百度词条中的编号,请勿混淆

5、xyy

4、定义了CIE xyY颜色空间:一个由XYZ导出的颜色空间,它把与颜色属性相关的xy从与明度属性相关的亮度Y中分离开;//百度词条中的编号,请勿混淆

为了解决颜色空间的感知一致性问题,专家们对CIE 1931 XYZ系统进行了非线性变换,制定了CIE 1976 L*a*b*颜色空间的规范。事实上,1976CIE规定了两种颜色空间,一种是用于自照明的颜色空间,叫做CIELUV,另一种是用于非自照明的颜色空间,叫做CIE 1976 L*a*b*,或者叫CIELAB。这两个颜色空间与颜色的感知更均匀,并且给了人们评估两种颜色近似程度的一种方法,允许使用数字量ΔE表示两种颜色之差。

CIE XYZ是国际照明委员会在1931年开发并在1964修订的CIE颜色系统(CIE Color System),该系统是其他颜色系统的基础。它使用相应于红、绿和蓝三种颜色作为三种基色,而所有其他颜色都从这三种颜色中导出。通过相加混色或者相减混色,任何色调都可以使用不同量的基色产生。虽然大多数人可能一辈子都不直接使用这个系统,只有颜色科学家或者某些计算机程序中使用,但了解它对开发新的颜色系统、编写或者使用与颜色相关的应用程序都是有用的。

6、什么是ycrcb

http://baike.baidu.com/link?url=lehHHtvuwMpXBk0tWJCgObEq17b-txSl8MYYNv-zqR-qLzFvTrSxRi7Rqcqv2zQ0F0ViBw1ClSbA8lVzuknoD_

YCrCbYUV,主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(LuminanceLuma),也就是灰阶值;而“U”“V”表示的则是色度(ChrominanceChroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。亮度是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。色度则定义了颜色的两个方面色调与饱和度,分别用CrCb来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。

 

采用YUV色彩空间的重要性是它的亮度信号Y和色度信号UV是分离的。如果只有Y信号分量而没有UV分量,那么这样表示的图像就是黑白灰度图像彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。

 

在人脸检测中也常常用到YCrCb空间,因为一般的图像都是基于RGB空间的,在RGB空间里人脸的肤色受亮度影响相当大,所以肤色点很难从非肤色点中分离出来,也就是说在此空间经过处理后,肤色点是离散的点,中间嵌有很多非肤色,这为肤色区域标定(人脸标定、眼睛等)带来了难题。如果把RGB转为YCrCb空间的话,可以忽略Y(亮度)的影响,因为该空间受亮度影响很小,肤色会产生很好的类聚。这样就把三维的空间将为二维的CrCb,肤色点会形成一定得形状,如:人脸的话会看到一个人脸的区域,手臂的话会看到一条手臂的形态,对处理模式识别很有好处,根据经验某点的CrCb值满足:133Cr17377Cb127那么该点被认为是肤色点,其他的就为非肤色点。

 

7、HSV

8、 HSL

9、HSI

http://www.360doc.com/content/13/1105/14/10724725_326803150.shtml

目前在计算机视觉领域存在着较多类型的颜色空间(color space)HSLHSV是两种最常见的圆柱坐标表示的颜色模型,它重新影射了RGB模型,从而能够视觉上比RGB模型更具有视觉直观性。

 

hsv  hue saturation value

HSV 以人类更熟悉的方式封装了关于颜色的信息

 

hsi  hue saturation/chroma  Intensity/brightness

由于人的视觉对亮度的敏感 程度远强于对颜色浓淡的敏感程度,为了便于色彩处理和识别,人的视觉系统经常采用HSI色彩空间它比RGB色彩空间更符合人的视觉特性

 

hsl  hue saturation lightness

 HSV 以人类更熟悉的方式封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”。HSL颜色空间类似于HSV,在某些方面甚至比它还好。HSL的模型为双圆锥形状。

这两种表示在用目的上类似,但在方法上有区别。二者在数学上都是圆柱,但 HSV(色相,饱和度,明度)在概念上可以被认为是颜色的倒圆锥体(黑点在下顶点,白色在上底面圆心),HSL在概念上表示了一个双圆锥体和圆球体(白色在上顶点,黑色在下顶点,最大横切面的圆心是半程灰色)。

 

hsl hsv比较:

HSL 类似于 HSV。对于一些人,HSL更好的反映了“饱和度”和“亮度”作为两个独立参数的直觉观念,但是对于另一些人,它的饱和度定义是错误的,因为非常柔和的几乎白色的颜色在HSL可以被定义为是完全饱和的。

 

//我的总结就是HSL有些人很喜欢因为把饱和度和亮度作为两个独立的参数,让人有更加直观的感受,同时也更容易操作,但是被人诟病恰恰因为引入了这种错误的定义

hsl

数字图像处理不得不知的点(1)_第2张图片

hsv

数字图像处理不得不知的点(1)_第3张图片


五、CV_8UC3

 

了解了上面的许多,后面就比较容易知道这些东西都是什么了:

CV代表计算机视觉跟openCV里面的CV是一个概念。8就是一个通道的数值用8位也就是一个字节表示。C表示Channel表示通道的意思。3表示3通道。这样一个像素就由三个字节来描述。如果是CV_8UC1就是 单个通道一个通道8位。

 

#define CV_8U   0 //8位无符号整形

#define CV_8S   1//有符号

#define CV_16U  2

#define CV_16S  3

#define CV_32S  4

#define CV_32F  5//32位浮点型

#define CV_64F  6

#define CV_USRTYPE1 7//预置的用户类型

 

就是

#define CV_8UC1 CV_MAKETYPE(CV_8U,1)//单通道图像。

#define CV_8UC2 CV_MAKETYPE(CV_8U,2)//我猜是单通道+alpha

#define CV_8UC3 CV_MAKETYPE(CV_8U,3)//彩图

#define CV_8UC4 CV_MAKETYPE(CV_8U,4)//我猜是彩图+alpha

#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))//加一个预置类型,可以自己模。

 

关于某一个的详细推倒可以看一下:

http://www.cnblogs.com/letben/p/5420478.html

 

 

【未完待续】

目前就整理了这么多,再想到再弄,这些点有很多~~~


你可能感兴趣的:(C++,opencv,图像处理)