OpenCV转换颜色表示法

OpenCV转换颜色表示法,RGB色彩空间的基础是对加色法三原色(红、绿、蓝)的应用。选用这三种颜色作为三原色,是因为将它们组合后可以产生色域很宽的各种颜色,与人类视觉系统对应。这通常是数字成像中默认的色彩空间,因为这就是用红绿蓝三种滤波器生成彩色图像的方式。红绿蓝三个通道还要做归一化处理,当三种颜色强度相同时就会取得灰度,即从黑色(0, 0, 0)到白色(255, 255, 255)。

但利用RGB色彩空间计算颜色之间的差距并不是衡量两个颜色相似度的最好方式。实际上,RGB并不是感知均匀的色彩空间。也就是说,两种具有一定差距的颜色可能看起来非常接近,而另外两种具有同样差距的颜色看起来却差别很大。

为解决这个问题,引入了一些具有感知均匀特性的颜色表示法。CIE L*a*b*就是一种这样的颜色模型。把图像转换到这种表示法后,我们就可以真正地使用图像像素与目标颜色之间的欧几里得距离,来度量颜色之间的视觉相似度。本文将介绍如何转换颜色表示法,以便使用其他色彩空间。

如何实现

使用OpenCV的函数cv::cvtColor可以轻松转换图像的色彩空间。回顾一下策略设计模式比较颜色提到的ColorDetector类。在process方法中先把输入图像转换成CIE L*a*b*色彩空间:

        cv::Mat ColorDetector::process(const cv::Mat &image) {

          // 必要时重新分配二值图像
          // 与输入图像的尺寸相同,但用单通道
          result.create(image.rows, image.cols, CV_8U);

          // 转换成Lab色彩空间
          cv::cvtColor(image, converted, CV_BGR2Lab);

          // 取得转换图像的迭代器
          cv::Mat_<cv::Vec3b>::iterator it=   converted.begin<cv::Vec3b>();
          cv::Mat_<cv::Vec3b>::iterator itend= converted.end<cv::Vec3b>();
          // 取得输出图像的迭代器
          cv::Mat_<uchar>::iterator itout= result.begin<uchar>();

          // 针对每个像素
          for ( ; it! = itend; ++it, ++itout) {

转换后的变量包含颜色转换后的图像,被定义为类ColorDetector的一个属性:

        class ColorDetector {
          private:
          // 颜色转换后的图像
          cv::Mat converted;

输入的目标颜色也需要进行转换——通过创建一个只有单个像素的临时图像,可以实现这种转换。注意,需要让函数保持与前面几节一样的签名,即用户提供的目标颜色仍然是RGB格式:

        // 设置需要检测的颜色
        void setTargetColor(unsigned char red, unsigned char green,
                            unsigned char blue) {

          // 临时的单像素图像
          cv::Mat tmp(1,1, CV_8UC3);
          tmp.at<cv::Vec3b>(0,0)= cv::Vec3b(blue, green, red);

          // 将目标颜色转换成Lab色彩空间
          cv::cvtColor(tmp, tmp, CV_BGR2Lab);

          target= tmp.at<cv::Vec3b>(0,0);
        }

如果在上文的程序中使用这个修改过的类,它就会在检测符合目标颜色的像素时,使用CIE L*a*b*颜色模型。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!