自然界中任何一种色光都可由R、G、B三基色按不同的比例相加混合而成,当三基色分量都为0(最弱)时混合为黑色光;当三基色分量都为k(最强)时混合为白色光。任一颜色F是这个立方体坐标中的一点,调整三色系数r、g、b中的任一系数都会改变F的坐标值,也即改变了F的色值。在计算机中编程RGB每一个分量值都用8位(bit)表示,可以产生256*256*256=16777216中颜色,这就是经常所说的“24位真彩色”。
一幅RGB 图像就是M×N×3 大小的彩色像素的数组, 数组的数据类决定了它们的取值范围,如果一幅RGB 图像的数据类是double,那么取值范围就是 [0,1]。
RGB颜色空间采用物理三基色表示,因而物理意义很清楚,适合彩色显像管工作。然而这一体制并不适应人的视觉特点。实际上RGB并不是感知均匀的色彩空间。就是说,两种具有一定差距的颜色可能看起来非常接近,而另外两种具有同样差距的颜色看起来却差别很大。为解决这个问题,引入了一些具有感知均匀特性的颜色表示法。CIEL*a*b*就是一种这样的颜色模型。把图像转换到这种表示法后,就可以真正地使用图像像素与目标颜色之间的欧几里德距离,来度量颜色之间的视觉相似度。
Example 1:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std;int main( int argc, char** argv ) {Mat image = cv::imread("yunfung_color.jpg");if (!image.data){cout << "Could not open or find the image" << std::endl ;return -1;}cout << "image.size().height = " << image.size().height << "\n"<<"image.size().width = "<< image.size().width<<endl ;namedWindow("YungFung Image", WINDOW_NORMAL);imshow("YungFung Image", image);Mat result;vector<cv::Mat> planes; //destination array/*Mat planes[3];merge(planes,3,result );*/split( image,planes); //split sourcenamedWindow("Output Image", WINDOW_NORMAL);//imwrite("blue.png",planes[0]); //blue channel B-G-R//cout << "planes[0] = \n " << planes[0] << "\n";planes[0]=255-planes[0]; //here the negative color is calculated!planes[1]=255-planes[1];planes[2]=255-planes[2];merge(planes,result );imshow("Output Image",result);waitKey();return 0; }
实际的像素值范围取决于指定的色彩空间和目标图像的类型。例如,CIE L*a*b*色彩空间中的L通道表示每个像素的亮度,范围是0~100;在使用8位图像时,它的范围就会调整为0~255。a和b通道表示色度组件。这些通道包含了像素的颜色信息,与亮度无关。它们的值的范围是-127~127;对于8位图像,为了适合0到255的区间,每个值会加上128。但是要注意,进行8位的颜色转换时会产生舍入误差,因此转换过程并不是完全可逆的。
HSV和HLS这两种色彩空间把颜色分解成加值的色调和饱和度组件或亮度组件,用这种方式来描述颜色会更加自然。可以把彩色图像转换成灰度图像,输出是一个单通道图像也可以进行反向的转换,但是那样得到彩色图像的三个通道是相同的,都是灰度图像中对应的值。