當前位置: 妍妍網 > 碼農

OpenCV築基之影像色彩空間

2024-02-08碼農

1. 影像色彩空間

影像色彩空間 是用於定義顏色範圍的數學模型。

它規定了影像中可以使用的顏色以及它們之間的關系。它決定了影像中可以顯示的顏色範圍。不同的色彩空間可以包含不同的顏色範圍,因此選擇合適的色彩空間對於確保影像在不同裝置上看起來一致非常重要。

影像色彩空間的意義主要體現在以下幾個方面:

  • 統一顏色標準 :色彩空間提供了一種統一的顏色標準,使得不同裝置之間能夠相互理解和交流顏色資訊。

  • 確保顏色一致性 :色彩空間可以確保影像在不同裝置上顯示時顏色一致。

  • 提高影像品質 :色彩空間可以提高影像品質。

  • 簡化影像處理 :色彩空間可以簡化影像處理過程,提高影像處理效率。

  • 促進色彩管理 :色彩空間是色彩管理的基礎。色彩管理是指確保影像在不同裝置上顯示時顏色一致的過程。透過使用色彩空間,我們可以將影像轉換為與目標裝置的色彩空間相匹配的色彩空間,從而確保影像在不同裝置上顯示時顏色一致。

  • 2. 最常見的影像色彩空間

    2.1 RGB

    RGB 色彩空間 是一種基於紅、綠、藍三原色的 加色 色彩空間。它是用於顯視器和電視機的顏色空間,也是用於大多數數位影像的色彩空間。

    RGB 色彩空間使用三個分量來表示顏色:紅色、綠色和藍色。每個分量都是一個介於 0 到 255 之間的數位,其中 0 表示該原色不存在,255 表示該原色完全存在。透過混合不同強度的紅、綠、藍光,可以建立各種顏色。例如,混合相等強度的紅、綠和藍光會產生白色光。混合全強度紅色和全強度綠色會產生黃色光。

    RGB圖1.png
    RGB圖2.png

    RGB 色彩空間根據每個分量在電腦中占用的儲存字節數的幾種常見情況:

  • RGB24: 每個分量占用8位元,共24位元,是最常見的RGB格式。

  • RGB565: R分量占用5位,G分量占用6位,B分量占用5位,共16位元。這種格式可以節省儲存空間,但顏色精度較低。

  • RGB555: R分量、G分量和B分量各占用5位,共15位。這種格式與RGB565類似,但顏色精度更低。

  • RGB32: 每個分量占用8位元,共32位元。增加了透明度通道,可以用於表示透明影像。這種格式可以提供更高的顏色精度,但需要更多的儲存空間。

  • 2.2 HSV

    HSV 色彩空間 是一種使用色相、飽和度和值來表示顏色的色彩空間。它是一種直觀的色彩空間,與人眼感知顏色的方式更加接近。

    HSV 色彩空間的三個分量:

  • 色相 (Hue):指的是顏色的基本內容,例如紅色、黃色、綠色等。色相通常用角度來表示,範圍為0-360度。

  • 飽和度 (Saturation):指的是顏色的純度,也就是顏色中灰色成分的多少。飽和度越高,顏色越純凈;飽和度越低,顏色越灰暗。飽和度通常用百分比來表示,範圍為0-100%。

  • (Value):指的是顏色的亮度,也就是顏色的明暗程度。值越高,顏色越明亮;值越低,顏色越暗淡。值通常用百分比來表示,範圍為0-100%。

  • HSV 是一種將 RGB 色彩空間中的點在倒圓錐體中的表示方法。360度的圓作為色相,飽和度的值就是色相切點指向圓心的線,此時的顏色還是不夠用於表示。再引入一個亮度,圓錐的垂線,越往上圖片越亮,反之越暗。

    HSV圖1.png
    HSV圖2.png

    HSV 色彩空間主要套用在以下幾個方面:

  • 影像分割 :可以根據顏色範圍來提取影像中的特定物件。

  • 顏色校正 :可以調整影像的飽和度或明度來改善影像品質。

  • 特效處理 :可以改變影像的顏色或建立特殊效果。

  • 電腦圖形 : 可以用於建立逼真的物體和場景。

  • HSV 顏色對應 RGB 分量範圍(透過實驗計算的模糊範圍)

    hsv 對應的 rgb 分量範圍.png

    2.3 HLS

    HLS 色彩空間 是一種使用色相、飽和度和明度來表示顏色的色彩空間。

    HLS 色彩空間的三個分量:

  • 色相 (Hue): 色相是指顏色的基本內容,通常用角度來表示,範圍為0°到360°。0°代表紅色,120°代表綠色,240°代表藍色,360°又回到紅色。

  • 飽和度 (Saturation): 飽和度是指顏色的純度,取值範圍為0%到100%。0%表示灰色,100%表示完全飽和。

  • 明度 (Lightness): 明度是指顏色的亮度,取值範圍為0%到100%。0%表示黑色,100%表示白色。

  • HLS.png

    下面整理了 HLS 和 HSV 色彩空間的區別:

    特性 HLS HSV
    色相 相同 相同
    飽和度 顏色與同亮度、無彩色(灰色)的最大差異程度 顏色純度
    亮度 感知到的明暗程度 顏色的明度
    幾何形狀 雙圓錐體和圓球體 倒圓錐體
    適用範圍 圖形設計、使用者介面 影像處理、電腦圖形

    HLS和HSV對比.png

    2.4 YUV

    YUV 色彩空間 是一種使用亮度(Y)和兩個色度分量(U和V)來表示顏色的顏色空間。它主要用於電視和視訊領域。

    YUV 色彩空間的三個分量:

  • Y :代表亮度,也就是灰度值。

  • U :代表藍色和黃色之間的色度分量。

  • V :代表紅色和青色之間的色度分量。

  • YUV.png

    由上圖可知,亮度和顏色無關只是黑白灰的程度不同,因此 UV 資訊代表顏色。

    YUV 色彩空間的常見格式:

  • YUV420:一種常見的 YUV 格式,每個像素占用 1.5 個字節。其中 Y 分量占用 1 個字節,U 和 V 分量各占用 0.25 個字節。

  • YUV422:另一種常見的 YUV 格式,每個像素占用 2 個字節。其中 Y 分量占用 1 個字節,U 和 V 分量各占用 0.5 個字節。

  • YUV444:每個像素占用 3 個字節,其中 Y、U 和 V 分量各占用 1 個字節。這種格式提供最高的影像品質,但需要最多的儲存空間。

  • YUV 色彩空間常見格式:

    格式 Y U V 儲存空間 影像品質
    YUV444 8位元 8位元 8位元 24位元 最高
    YUV422 8位元 8位元 (每隔一個像素采樣) 8位元 (每隔一個像素采樣) 16位元 中等
    YUV420 8位元 4位元 (每隔兩個像素采樣) 4位元 (每隔兩個像素采樣) 12位元 較低

    另外,還有 YCbCr,YCbCr 是從 YUV 色彩空間衍生而來,但 YCbCr 采用了更復雜的數學公式,以便更好地利用人眼的視覺特性。

    2.5 CMY & CMYK

    CMY 色彩空間 是一種基於 減色原理 的顏色空間,使用青色 (Cyan)、品紅 (Magenta) 和黃色 (Yellow) 三原色來表示顏色。它通常用於印刷和出版領域,因為CMY油墨可以很好地吸收光線,從而產生各種各樣的顏色。

    CMY.png

    CMY 色彩空間的工作原理:白色光包含所有可見光譜。當白色光穿過 CMY 油墨時,油墨會吸收部份光譜。未被吸收的光線會反射到我們的眼睛中,我們看到的就是 CMY 顏色。

    CMYK 是 CMY 的擴充套件增加了黑色分量。這是因為 CMY 無法完美地再現黑色,因此添加黑色分量可以提高陰影和暗調的準確性。

    CMY 和 CMYK 色彩空間的比較:

    特性 CMY CMYK
    顏色分量 青色、品紅、黃色 青色、品紅、黃色、黑色
    顏色模式 減色 減色
    適用範圍 印刷 印刷
    黑色分量
    色彩範圍 較小 較大
    印刷成本 較低 較高

    2.6 Lab

    Lab 色彩空間 是一種基於人眼感知的色彩空間,比其他顏色空間(如 RGB 和 CMYK)更接近於感知顏色。

    Lab 色彩空間的三個分量:

  • L :代表亮度,取值範圍為 0-100,0 表示黑色,100 表示白色。

  • a :代表從紅色到綠色的範圍,取值範圍為 -128 到 127,-128 表示綠色,127 表示紅色。

  • b :代表從藍色到黃色的範圍,取值範圍為 -128 到 127,-128 表示藍色,127 表示黃色。

  • Lab 色彩空間的特性:

  • 感知均勻性好 :Lab 色彩空間與人眼感知顏色方式更接近,因此具有較好的感知均勻性。

  • 顏色範圍大 :Lab 色彩空間可以表示比 RGB 和 CMYK 更廣泛的顏色範圍。

  • 與裝置無關 :Lab 色彩空間與裝置無關,因此可以在不同的裝置之間準確地轉換顏色。

  • Lab.png

    3. 影像色彩空間轉換

    影像色彩空間轉換 是指將影像從一個色彩空間轉換到另一個色彩空間的過程。

    OpenCV 提供了 cv::cvtColor() 函式進行影像色彩空間轉換,常見的轉換方法:

  • RGB 到 HSV:

  • cv::cvtColor(src, dst, cv::COLOR_RGB2HSV);

  • HSV 到 RGB:

  • cv::cvtColor(src, dst, cv::COLOR_HSV2RGB);

  • RGB 到 YUV:

  • cv::cvtColor(src, dst, cv::COLOR_RGB2YUV);

  • YUV 到 RGB:

  • cv::cvtColor(src, dst, cv::COLOR_YUV2RGB);

  • RGB 到 Lab:

  • cv::cvtColor(src, dst, cv::COLOR_RGB2Lab);

  • Lab 到 RGB:

  • cv::cvtColor(src, dst, cv::COLOR_Lab2RGB);

    下面的例子,展示了在 OpenCV 中使用 cvtColor() 函式將原圖轉換到各種色彩空間。

    #include"opencv2/imgproc.hpp"
    #include"opencv2/highgui.hpp"
    usingnamespacestd;
    usingnamespace cv;
    intmain(int argc, char **argv){
    Mat src = imread(".../flower.jpg");
    imshow("src", src);
    Mat gray;
    cvtColor(src, gray, cv::COLOR_BGR2GRAY);
    imshow("gray", gray);
    Mat hsv;
    cvtColor(src, hsv, cv::COLOR_BGR2HSV); // BGR 轉換到 HSV 色彩空間
    imshow("hsv", hsv);
    Mat hls;
    cvtColor(src, hls, cv::COLOR_BGR2HLS); // BGR 轉換到 HLS 色彩空間
    imshow("hls", hls);
    Mat yuv;
    cvtColor(src, yuv, cv::COLOR_RGB2YUV); // BGR 轉換到 YUV 色彩空間
    imshow("yuv", yuv);
    Mat lab;
    cvtColor(src, lab, cv::COLOR_RGB2Lab); // BGR 轉換到 Lab 色彩空間
    imshow("lab", lab);
    waitKey(0);
    return0;
    }






    原圖和灰度圖.png

    hsv和hls色彩空間.png

    yuv和lab色彩空間.png

    4. 顏色分割

    下面的例子,先將圖片轉換到 HSV 色彩空間,再透過 cv::inRange() 函式將女孩從綠色背景分離出來,最後用藍色背景替換原先的綠色背景。

    #include"opencv2/imgproc.hpp"
    #include"opencv2/highgui.hpp"
    usingnamespacestd;
    usingnamespace cv;
    intmain(int argc, char **argv){
    Mat src = imread(".../girl.jpg");
    imshow("src", src);
    Mat hsv;
    cvtColor(src, hsv, cv::COLOR_BGR2HSV); // BGR 轉換到 HSV 色彩空間
    imshow("hsv", hsv);
    cv::Scalar lower_green(354346);
    cv::Scalar upper_green(77255255)// 定義綠色的 HSV 範圍
    Mat mask;
    inRange(hsv, lower_green, upper_green, mask); // 透過 inRange 函式實作二值化
    imshow("mask", mask);
    Mat kernel = getStructuringElement(MORPH_RECT,Size(7,7),Point(-1,-1));
    morphologyEx(mask, mask, MORPH_OPEN, kernel, Point(-1-1), 1);
    imshow("open", mask);
    GaussianBlur(mask,mask,Size(45,45),0,0);
    imshow("blur", mask);
    bitwise_not(mask,mask);
    imshow("fg", mask);
    // 重新定義背景顏色
    Vec3b color;
    color[0] = 255;
    color[1] = 0;
    color[2] = 0;
    int height = src.rows;
    int width = src.cols;
    Mat result(src.size(),src.type());
    double w = 0.0;
    int b = 0,g = 0, r = 0;
    int b1 = 0,g1 = 0, r1 = 0;
    int b2 = 0,g2 = 0, r2 = 0;
    for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
    int m = mask.at<uchar>(row,col);
    if(m == 255){ //前景
    result.at<Vec3b>(row,col) = src.at<Vec3b>(row,col);
    elseif(m==0){ //背景
    result.at<Vec3b>(row,col) = color;
    else{
    w = m/ 255;
    b1 = src.at<Vec3b>(row,col)[0];//前景
    g1 = src.at<Vec3b>(row,col)[1];
    r1 = src.at<Vec3b>(row,col)[2];
    b2 = color[0];//背景
    g2 = color[1];
    r2 = color[2];
    b = b1*w+b2*(1.0-w);
    g = g1*w+g2*(1.0-w);
    r = r1*w+r2*(1.0-w);
    result.at<Vec3b>(row,col)[0] = b;
    result.at<Vec3b>(row,col)[1] = g;
    result.at<Vec3b>(row,col)[2] = r;
    }
    }
    }
    imshow("result",result);
    waitKey(0);
    return0;
    }














    原圖以及轉換到hsv.png

    生成mask和形態學開操作.png

    高斯模糊和bitwise_not操作.png

    替換背景.png

    下面簡單介紹一下 cv::inRange() 函式:

    voidinRange(InputArray src, InputArray lowerb,
    InputArray upperb, OutputArray dst)
    ;

    第一個參數 src: 輸入影像,可以是單鍊結或多通道影像。

    第二個參數 lowerb: 顏色範圍的下限,可以是純量或陣列。

    第三個參數 upperb: 顏色範圍的上限,可以是純量或陣列。

    第四個參數 dst: 輸出影像,與輸入影像大小相同,型別為 CV_8U。

    對於影像中的每個像素, cv::inRange() 函式會將其與 lowerb 和 upperb 進行比較。如果像素值在兩者之間,則輸出影像中的對應像素設定為 255,否則設定為 0。所以,實作了影像的二值化。

    5. 總結

    影像色彩空間在影像處理和顯示中起著重要的作用。

    除了本文介紹的影像色彩空間之外,還有許多其他影像色彩空間,每種色彩空間都有自己的優勢和劣勢。

    影像色彩空間可以確保顏色一致性、提高影像品質、簡化影像處理並促進色彩管理。隨著技術的不斷發展,影像色彩空間也在不斷發展。

    系統化學習直接掃碼檢視

    推薦閱讀