3--OpenCV:图像色彩模型转换

什么是色彩模型

颜色模型指的是某个三维颜色空间中的一个可见光子集,它包含某个色彩域的所有色彩。一般而言,任何一个色彩域都只是可见光的子集,任何一个颜色模型都无法包含所有的可见光(通俗一点讲就是表示颜色的一种方式)

RGB颜色模型

RGB模型

在计算机体系中,最常用的颜色空间是RGB模型,常用于颜色显示和图像处理,三维坐标的模型形式,主要是易于实现RGB三原色的组合表达各种颜色方便屏幕显示。学过物理的我们应该知道,可见光谱是连续的,而三原色RGB混合能形成其他的颜色,并不是说物理上其他颜色的光是由三原色的光混合形成的,每种单色光都有自己独特的光谱,如黄光是一种单色光,但红色与绿色混合能形成黄色,原因是人的感官系统所致,因为人眼感光细胞就是由红绿蓝三种感光细胞组成的。只能说“将三原色光以不同的比例复合后,对人的眼睛可以形成与各种频率的可见光等效的色觉。”

原点到白色顶点的中轴线是灰度线r、g、b三分量相等,强度可以由三分量的向量表示。RGB是通过红绿蓝三原色来描述颜色的颜色空间。是图像处理中最基本、最常用、面向硬件的颜色空间。我们采集到的彩色图像,一般就是被分成R、G、B的成分加以保存的。RGB色彩空间采用物理三基色表示,因而物理意义很清楚,适合电子显示屏工作。然而这一体制并不适应现实世界里人对于颜色的描述。因而,产生了其它不同的色彩空间表示法

RGB 的局限

  • RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。

  • 自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。

  • 眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。

所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理

RGB分类

  • RGB16:每个像素用16比特位表示,占2个字节

    • RGB565:RGB分量分别使用5位、6位、5位

    • RGB555:RGB分量分别使用5位、5位、5位

    • 小知识--->如何获取各个5位上的值

      #include <iostream>
      using namespace std;
      struct Color 
      {
          unsigned int color : 15;
      };
      void getValueRGB555() 
      {
          Color xColor = { 0b110000011100011 };
          //0b11000 00111 00011
          cout <<"xColor:" << xColor.color << endl;
          int R = xColor.color >> 10;
          //0x03E0: 0000 11 1110 0000
          int G = (xColor.color & 0x03E0) >> 5;
          //0000  0001 1111
          int B = xColor.color & 0x001F;
          cout << "R:"<< R << endl;
          cout << "G:" << G << endl;
          cout << "B:" << B << endl;
      }
      int main() 
      {
          getValueRGB555();
          return 0;
      }
  • RGB24格式:每个像素用24比特位表示,占3个字节,在内存中RGB各排列顺序为:BGR

  • RGB32格式:每个像素用32比特位表示,占4个字节R,G,B分量分别用8个bit表示,存储顺序为B,G,R,最后8个字节保留

    • ARGB32:本质就是带alpha通道RGB24,与RGB32的区别在与,保留的8个bit用来表示透明,也就是alpha的值

    • 小知识--->如何获取各个8位上的值

    #include <iostream>
    using namespace std;
    void getValueRGB32()
    {
        int color = 0x0F0A0B0C;
        cout << "color:" << color << endl;
        int B = color >> 24;                    //第一个8位
        int G = (color & 0x00FF0000) >> 16;     //第二个8位
        int R = (color & 0x0000FF00) >> 8;      //第三个8位
        int A = color & 0x000000FF;             //最后一个8位
        cout << "B:" << B << endl;
        cout << "G:" << G << endl;
        cout << "R:" << R << endl;
        cout << "A:" << A << endl;
    }
    int main() 
    {
        getValueRGB32();
        return 0;
    }

HSV颜色模型

HSV模型

HSV(Hue, Saturation,Value)根据颜色直观特性创建的一种颜色空间,也称六角锥体模型(Hexcone Model),参数分别为色调(H),饱和度(S),明度(V)

色调H

用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°;

饱和度S

饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。

明度V

明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)

取值范围

HSV颜色空间规定,H:0-360,S:0-1,V:0-1

opencv中的HSV范围,H:0-179,S:0-255,V:0-255

注意:

        ①函数cvtColor的使用,以及颜色模型的定义的规律---->2谐音to,表示转换的意思,下面COLOR_BGR2HSV的意思就是,颜色模型从BGR模式转换到HSV模式

        ②函数split的使用,分割Mat类型的img存入vector<Mat>类型中第一个维度即H,第二个维度就是S,第三个维度就是V

//split
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() 
{
    Mat  img = imread("mm.jpg");
    imshow("img", img);
    Mat  result;
    cvtColor(img, result, COLOR_BGR2HSV);
    imshow("result", result);
    //分割
    vector<Mat> hsv;
    split(result, hsv);
    imshow("H", hsv[0]);
    imshow("S", hsv[1]);
    imshow("V", hsv[2]);
    waitKey(0);
    return 0;
}
 

HLS颜色模型

HLS颜色空间,三个分量分别是色调(H)、亮度(L)、饱和度(S)

上图种可以看出,固定一个颜色(H),那么随着饱和度

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() 
{
    Mat  img = imread("mm.jpg");
    imshow("img", img);
    Mat  result;
    cvtColor(img, result, COLOR_BGR2HLS);
    imshow("result", result);
    waitKey(0);
    return 0;
}

(S,Chroma)的增加,颜色越来越深

取值范围

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() 
{
    Mat  img = imread("mm.jpg");
    imshow("img", img);
    Mat  result;
    cvtColor(img, result, COLOR_BGR2HLS);
    imshow("result", result);
    waitKey(0);
    return 0;
}

LAB颜色模型

LAB颜色组成

  • L- 亮度(光强)

  • a - 颜色组成部分,从绿色 到 品红;

  • b - 颜色组成部分,从 蓝色 到 黄色;

LAB颜色空间与RGB 颜色空间有着很大的不同。 在RGB颜色空间中, 色彩信息吧分为R、G、B三个空间,但它们都包含着亮度信息。与其不同,Lab颜色空间 L通道与颜色通道不想管,仅仅对亮度信息编码。 其他两个通道对颜色进行编码。

LAB特性

  • 颜色感知统一,与我们感知色彩近似;

  • 不依赖于对摄像和显示设备;

  • 在Adobe Photoshop中被广泛是使用;

通过复杂的转换方程从RGB空间进行相互转换

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int WinMain()
{
    Mat  img = imread("mm.jpg");
    imshow("img", img);
    Mat  result;
    cvtColor(img, result, COLOR_BGR2Lab);
    imshow("result", result);
    waitKey(0);
    return 0;
}

YCrCb颜色模型

YCbCr有的时候会被写作:YCBCR,是色彩空间的一种,通常会用于影片中的影像连续处理,或是数字摄影系统中。Y为颜色的亮度(luma)成分、而CB和CR则为蓝色和红色的浓度偏移量成分

YCrCb颜色组成

YCrCb颜色空间是从RGB颜色空间推导出来的,具有以下三个组成部分:

  • Y - 亮度部分,是通过伽马校正后的RGB获取

  • Cr = R - Y (反映了 R与Y的偏差)

  • Cb = B - Y (反映了B与Y的偏差)

YCrcb特性

  • 将亮度和色彩成分分离到不同的通道;

  • 在电视信息压缩传输中(Cr,Cb被降采样)被广泛使用;

  • 与设想和显示设备有关系;

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int WinMain()
{
    Mat  img = imread("mm.jpg");
    imshow("img", img);
    Mat  result;
    cvtColor(img, result, COLOR_BGR2YCrCb);
    imshow("result", result);
    waitKey(0);
    return 0;
}

opencv颜色模型转换

#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class CvtColor 
{
public:
    CvtColor(string filename) :mat(imread(filename)) {}
    void Show(string wname) 
    {
        imshow(wname, mat);
        cv::moveWindow(wname, 600, 100);        //移动wname窗口
    }
    void TransmitShow(string wname, int type) 
    {
        Mat result;
        cvtColor(mat, result, type);
        imshow(wname, result);
    }
private:
    Mat mat;
};
​
int WinMain()
{
    CvtColor* pC = new CvtColor("mm.jpg");
    pC->Show("原图像");
    pC->TransmitShow("hsv", COLOR_BGR2HSV);
    pC->TransmitShow("灰度", COLOR_BGR2GRAY);
    pC->TransmitShow("Lab", COLOR_BGR2Lab);
    pC->TransmitShow("YCrcb", COLOR_BGR2YCrCb);
    pC->TransmitShow("HLS", COLOR_BGR2HLS);
    waitKey(0);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值