您的位置:首页 > 其它

RGB颜色模型和HSV颜色模型及其应用的汇总

2015-06-05 09:06 573 查看
在图像处理中,最常用的颜色空间是RGB模型,常用于颜色显示和图像处理,三维坐标的模型形式,非常容易被理解。而HSV模型,是针对用户观感的一种颜色模型,侧重于色彩表示,什么颜色、深浅如何、明暗如何。第一次接触HSV,书本里首先抛出的是一个圆锥模型,由于很少使用HSV,所以印象不深刻,但看一些资料时,HSV的概念时不时出来骚扰一些人的神经,所以,弄清楚HSV与RGB的关系,建立直观的印象是很有必要的。

1. RGB模型。
三维坐标:



原点到白色顶点的中轴线是灰度线,r、g、b三分量相等,强度可以由三分量的向量表示。
用RGB来理解色彩、深浅、明暗变化:
色彩变化: 三个坐标轴RGB最大分量顶点与黄紫青YMC色顶点的连线
深浅变化:RGB顶点和CMY顶点到原点和白色顶点的中轴线的距离
明暗变化:中轴线的点的位置,到原点,就偏暗,到白色顶点就偏亮

RGB模型也称为加色法混色模型。它是以RGB三色光互相叠加来实现混色的方法,因而适合于显示器等发光体的显示。其混色规律是:以等量的红、绿、蓝基色光混合时。

如果是三原色光中的两种色光(注意,不是颜料)进行等比例混合的话,那么,得到的结果是品红、黄、青三色光。

红+绿=黄

红+蓝=品红

绿+蓝=青

红+绿+蓝=白

三种基色光全无=黑

这是色光混合,称为加色混合法。加色法的混色规律可用图表示。

其配色方程描述:

F(物体颜色)=R(红色的百分比)+G(绿色的百分比)+B(蓝色的百分比)

如果就是这三种颜料相混的话,那么,大体上,红+绿=暗灰红;红+蓝=紫色;绿+蓝=青绿色。

这是色彩混合,称为减色混合法。

切记,色光混合跟颜料混合是不同性质的。
PS: 光学的分析
三原色RGB混合能形成其他的颜色,并不是说物理上其他颜色的光是由三原色的光混合形成的,每种单色光都有自己独特的光谱,如黄光是一种单色光,但红色与绿色混合能形成黄色,原因是人的感官系统所致,与人的生理系统有关。
只能说“将三原色光以不同的比例复合后,对人的眼睛可以形成与各种频率的可见光等效的色觉。”

1,)HSV颜色模型

倒锥形模型:





这个模型就是按色彩、深浅、明暗来描述的。模型中颜色的参数分别是:色彩(H),纯度(S),明度(V)。
H是色彩
S是深浅, S = 0时,只有灰度
V是明暗,表示色彩的明亮程度,但与光强无直接联系,(意思是有一点点联系吧)。
  HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。
  HSV六棱锥
  H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,红、绿、蓝分别相隔120度。互补色分别相差180度。
  纯度S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S=0时,只有灰度。
  V表示色彩的明亮程度,范围从0到1。有一点要注意:它和光强度之间并没有直接的联系。

HSV对用户来说是一种直观的颜色模型。我们可以从一种纯色彩开始,即指定色彩角H,并让V=S=1,然后我们可以通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小V而S不变,同样增加白色可以减小S而V不变。例如,要得到深蓝色,V=0.4 S=1 H=240度。要得到淡蓝色,V=1 S=0.4 H=240度。
  一般说来,人眼最大能区分128种不同的色彩,130种色饱和度,23种明暗度。如果我们用16Bit表示HSV的话,可以用7位存放H,4位存放S,5位存放V,即745或者655就可以满足我们的需要了。
  由于HSV是一种比较直观的颜色模型,所以在许多图像编辑工具中应用比较广泛,如Photoshop(在Photoshop中叫HSB)等等,但这也决定了它不适合使用在光照模型中,许多光线混合运算、光强运算等都无法直接使用HSV来实现。

  顺便提一下,另外一种直观颜色模型是HSL模型,该模型中前两个参数和HSV一样,而L表示亮度。它的三维表示为一双棱锥。因为用的不多,这里就不详细讲了。

HSV在图像处理应用:
HSV在用于指定颜色分割时,有比较大的作用。
H和S分量代表了色彩信息。
分割应用:
用H和S分量来表示颜色距离,颜色距离指代表两种颜色之间的数值差异。

Androutsos等人通过实验对HSV颜色空间进行了大致划分,亮度大于75%并且饱和度大于20%为亮彩色区域,亮度小于25%为黑色区域,亮度大于75%并且饱和度小于20%为白色区域,其他为彩色区域。

对于不同的彩色区域,混合H与S变量,划定阈值,即可进行简单的分割。

3. RGB与HSV的联系

  RGB转化到HSV的算法
  max=max(R,G,B)
  min=min(R,G,B)
  if R = max, H = (G-B)/(max-min)

  if G = max, H = 2 + (B-R)/(max-min)

  if B = max, H = 4 + (R-G)/(max-min)

  H = H * 60
  if H < 0, H = H + 360
  V=max(R,G,B)
  S=(max-min)/max
  HSV转化到RGB的算法
  if s = 0
  R=G=B=V
  else
  H /= 60;
  i = INTEGER(H)
  f = H - i
  a = V * ( 1 - s )
  b = V * ( 1 - s * f )
  c = V * ( 1 - s * (1 - f ) )

  switch(i)
  case 0: R = V; G = c; B = a;

  case 1: R = b; G = v; B = a;

  case 2: R = a; G = v; B = c;

  case 3: R = a; G = b; B = v;

  case 4: R = c; G = a; B = v;

case 5: R = v; G = a;B = b;

 

从上面的直观的理解,把RGB三维坐标的中轴线立起来,并扁化,就能形成HSV的锥形模型了。
但V与强度无直接关系,因为它只选取了RGB的一个最大分量。而RGB则能反映光照强度(或灰度)的变化。
v = max(r, g, b)
由RGB到HSV的转换:



"  HSV对用户来说是一种直观的颜色模型。我们可以从一种纯色彩开始,即指定色彩角H,并让V=S=1,然后我们可以通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小V而S不变,同样增加白色可以减小S而V不变。例如,要得到深蓝色,V=0.4
S=1 H=240度。要得到淡蓝色,V=1 S=0.4 H=240度。" --百度百科

代码:

#include <cv.h>

#include <highgui.h>

#include <stdio.h>

using namespace std;

bool g_isdown;

CvRect g_rect;

//鼠标回调函数

void my_callback(int event,int x,int y,int flags,void *param);

//将image图像的rect区域部分做加亮处理

void high_light(IplImage *image,CvRect rect);

int main()

{

IplImage *orginal_image=cvLoadImage("f.jpg");

//断言,如果条件返回错误,则终止程序执行

assert(orginal_image!=NULL);

IplImage *temp_image=cvCreateImage(cvGetSize(orginal_image),orginal_image->depth,orginal_image->nChannels);

assert(temp_image!=NULL);

cvNamedWindow("show");

cvSetMouseCallback("show",my_callback,(void *)temp_image);

while(1)

{

IplImage *temp_image=cvCloneImage(orginal_image);

if(true==g_isdown)

{

high_light(temp_image,g_rect);

}

else

{

high_light(temp_image,g_rect);

}

cvShowImage("show",temp_image);

cvSaveImage("result.jpg",temp_image);

if(27==cvWaitKey(30))//27是Esc键

{

break;

}

}

cvDestroyAllWindows();

return 0;

}

//回调函数

void my_callback(int event,int x,int y,int flags,void *praram)

{

IplImage *image=(IplImage *)(praram);

switch(event)

{

case CV_EVENT_LBUTTONDOWN://左键点击

{

g_isdown=true;

g_rect=cvRect(x,y,0,0);//起点

}

break;

case CV_EVENT_MOUSEMOVE://鼠标移动,计算矩形框的高和宽

{

if(true==g_isdown)

{

g_rect.width=x-g_rect.x;

g_rect.height=y-g_rect.y;

}

}

break;

case CV_EVENT_LBUTTONUP://左键松开

{

g_isdown=false;

if(g_rect.width<0)

{

g_rect.x=g_rect.x+g_rect.width;

g_rect.width*=-1;

}

if(g_rect.height<0)

{

g_rect.y=g_rect.y+g_rect.height;

g_rect.height*=-1;

}

high_light(image,g_rect);//加亮处理

}

break;

}

}

效果:




这个程序主要是通过鼠标按键画一个矩形框,然后当松手时,在原图上形成一个高亮框。高亮框用以突出图像的某一部分,以便针对处理该区域。这个实验对人工界面的智能操作和模式识别具有重要的意义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: