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;
}
}
效果:
这个程序主要是通过鼠标按键画一个矩形框,然后当松手时,在原图上形成一个高亮框。高亮框用以突出图像的某一部分,以便针对处理该区域。这个实验对人工界面的智能操作和模式识别具有重要的意义。
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;
}
}
效果:
这个程序主要是通过鼠标按键画一个矩形框,然后当松手时,在原图上形成一个高亮框。高亮框用以突出图像的某一部分,以便针对处理该区域。这个实验对人工界面的智能操作和模式识别具有重要的意义。
相关文章推荐
- OC内存管理
- linux内存操作-----ioremap
- 为什么很多大牛在写题的时候要加一堆宏?
- 关于oracle数据库读取数据的三种方式
- 如何处理iOS中照片的方向
- C语言str函数系列
- FileStream使用小记
- 第五章节 Servlet基础
- asp.net mvc3用file上传文件大小限制问题
- 两边空格的编程风格
- 轻松学习之 iOS利用Runtime自定义控制器POP手势动画
- Myeclipse j2ee版本切换
- awk学习笔记
- Naive Bayes在mapreduce上的实现
- ios animate简单动画体验
- Mantle 初步使用
- weak的生命周期:具体实现方法
- 如何实现Ping App的转场动画
- 关于oracle11g简单的网络配置
- C# 并行编程 之 PLINQ并行度的指定 和 ForAll的使用