OpenCV 2 学习笔记(14): 颜色空间转换

来源:互联网 发布:重庆软件测试招聘 编辑:程序博客网 时间:2024/05/16 02:44

RGB是以红,绿,蓝为三基色的颜色空间。之所以选择这三种主颜色是因为这三种颜色组合起来可以形成大量不同颜色。实际上,人类视觉系统也是基于视锥细胞对于红绿蓝光谱的三基色的感知。在数字图像中的颜色空间通常是不变的,这是因为它们获得光线的方法是默认的。捕捉的光线都经过红绿蓝滤波器。另外,在数字图像中,红绿蓝信道中的颜色等量时,就会获得一个从黑(0,0,0)到白(255,255,255)的灰度级。

         但是,使用RGB空间不太好计算相似两颜色之间的距离。实际上,RGB不是一个感知均匀的颜色空间。而CIE L*a*b*却是一种感知均匀颜色空间,通过它们之间的转换,两种颜色之间的欧拉距离对于测量它们是否视觉相似是非常有意义的。这一节我们就说一下两种颜色空间的转换。

我们更改一下上一节的列子。在转换颜色空间时可以使用OpenCV自带的函数cv::cvtColor

cv::Mat ColorDetector::process(const cv::Mat &image) {        // re-allocate binary map if necessary     // same size as input image, but 1-channel     result.create(image.rows,image.cols,CV_8U);     // re-allocate intermediate image if necessary     converted.create(image.rows,image.cols,image.type());     // Converting to Lab color space      cv::cvtColor(image, converted, CV_BGR2Lab);     // get the iterators of the converted image      cv::Mat_<cv::Vec3b>::iterator it= converted.begin<cv::Vec3b>();     cv::Mat_<cv::Vec3b>::iterator itend= converted.end<cv::Vec3b>();     // get the iterator of the output image     cv::Mat_<uchar>::iterator itout= result.begin<uchar>();     // for each pixel     for ( ; it!= itend; ++it, ++itout) {     …

上面的converted是在类里又增加的一个变量。

class ColorDetector {  private:     // image containing color converted image     cv::Mat converted;

当然我们也需要转换输入目标颜色。我们使用一个临时的包含一个像素的变量,但是在更改前一节的函数时不可以改变函数名,也就是说用户输入的仍然是RGB颜色。
/ Sets the color to be detected     void setTargetColor(unsigned char red,            unsigned char green, unsigned char blue) {         // Temporary 1-pixel image         cv::Mat tmp(1,1,CV_8UC3);         tmp.at<cv::Vec3b>(0,0)[0]= blue;         tmp.at<cv::Vec3b>(0,0)[1]= green;         tmp.at<cv::Vec3b>(0,0)[2]= red;         // Converting the target to Lab color space          cv::cvtColor(tmp, tmp, CV_BGR2Lab);         target= tmp.at<cv::Vec3b>(0,0);     }

当图像从一种颜色空间转换到另一种,在每个像素之间会发生线性或者非线性转换。颜色转换不仅可以在8位像素之间进行。哈可以使用float类型的像素,例如,像素值从0到1.0,或者整形像素,从0到65535。但是提取出的像素值都是由特定的颜色空间,例如,CIE L*a*b颜色空间,L信道是从0到100,而a和b色度组件是从-127到127.

         大部分常用的颜色空间是可用的。问题只是对于OpenCV提供正确的掩码。例如YCrCb,是用在JPEG压缩的颜色空间。从BGR转换到YCrCb,掩码必须是CV_BGR2YCrCb。再有就是记住RGB空间的颜色顺序是BGR。

         HSV和HLS颜色空间将颜色分解为色相和饱和度两部分,加上本身的值或者亮度分量。

         也可以将RGB转换为灰度图像

cv::cvtColor(color, gray, CV_BGR2Gray);

反过来也可以。