2015-10-14 45 views
3

我想將YCrCb分割爲Y,Cr和Cb通道。將YCrCb圖像分割爲其強度通道

代碼運行良好,但是當我爲每個Y,Cr,Cb顯示imshow("Y", y)的通道時,所有通道看起來都是灰色的。

只有Y通道必須是灰色的,其他人應該是多彩的。我對嗎?或者代碼有什麼問題?

Mat RGBImage; 
    RGBImage = imread("xx.jpg");  
    cvtColor(RGBImage, YCrCb, CV_RGB2YCrCb); 

    vector<Mat> ycc_planes; 
    split(YCrCb, ycc_planes); 

    Mat y = ycc_planes[0]; 
    Mat Cr = ycc_planes[1]; 
    Mat Cb = ycc_planes[2]; 

我的最終目標是平均濾鏡應用到圖像的Y分量,然後與合併其他組件(Cr和Cb)改回RGB。最後,我將獲得原始RGB圖像的模糊版本。然而我的意思是過濾器總是返回灰色模糊的圖像。我雖然可能是因爲我的Cr,Cb組件是灰色的。

+1

你將3通道圖像分成3個1通道圖像。 1通道圖像是灰度,並將顯示爲灰色sh。他們的像素值實際上是一個顏色信息的事實是無關緊要的,他們仍然是灰度圖像。所以,你的代碼是好的,只是你的解釋是不正確的。 – Miki

+0

爲了使它們變得豐富多彩,我應該在我的代碼中添加什麼?@Miki – Blu

+1

'cvtColor(RGBImage,YCrCb,CV_BGR2YCrCb);'也許更好 – sturkmen

回答

5

當你分割一個3通道圖像分成3單通道圖像,每個圖像是灰度級。他們代表色彩信息的事實是無關緊要的。

原圖:

enter image description here

的YCrCb渠道:

enter image description here

你可以,但是,應用顏色效果:

enter image description here


您可以模糊Y通道,然後合併3個單聲道,並轉換回BGR:

enter image description here

這裏供參考全碼:

#include <opencv2/opencv.hpp> 
#include <vector> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat3b bgr = imread("path_to_image"); 

    Mat3b ycrcb; 
    cvtColor(bgr, ycrcb, COLOR_BGR2YCrCb); 

    vector<Mat1b> planes; 
    split(ycrcb, planes); 

    // Collage planes 
    Mat1b collagePlanes(bgr.rows, bgr.cols*3); 
    for (int i = 0; i < 3; ++i) 
    { 
     planes[i].copyTo(collagePlanes(Rect(i*bgr.cols, 0, bgr.cols, bgr.rows))); 
    } 

    Mat1b gray(bgr.rows, bgr.cols, uchar(128)); 

    // Y 
    vector<Mat1b> vy(3); 
    vy[0] = planes[0]; 
    vy[1] = gray.clone(); 
    vy[2] = gray.clone(); 
    Mat3b my; 
    merge(vy, my); 

    // Cr 
    vector<Mat1b> vcr(3); 
    vcr[0] = gray.clone(); 
    vcr[1] = planes[1]; 
    vcr[2] = gray.clone(); 
    Mat3b mcr; 
    merge(vcr, mcr); 

    // Cb 
    vector<Mat1b> vcb(3); 
    vcb[0] = gray.clone(); 
    vcb[1] = gray.clone(); 
    vcb[2] = planes[2]; 
    Mat3b mcb; 
    merge(vcb, mcb); 



    // Collage planes 
    Mat3b collageColor(bgr.rows, bgr.cols * 3); 
    my.copyTo(collageColor(Rect(0, 0, bgr.cols, bgr.rows))); 
    mcr.copyTo(collageColor(Rect(bgr.cols, 0, bgr.cols, bgr.rows))); 
    mcb.copyTo(collageColor(Rect(2 * bgr.cols, 0, bgr.cols, bgr.rows))); 

    cvtColor(collageColor, collageColor, COLOR_YCrCb2BGR); 


    //////////////////////////// 

    // Blur Y 
    boxFilter(planes[0], planes[0], CV_8U, Size(7,7)); 

    Mat3b blurred; 
    merge(planes, blurred); 
    cvtColor(blurred, blurred, COLOR_YCrCb2BGR); 


    imshow("Original", bgr); 
    imshow("YCrCb planes", collagePlanes); 
    imshow("YCrCb planes colored", collageColor); 
    imshow("Blurred", blurred); 
    waitKey(); 


    return 0; 
} 
+0

哇!非常感謝你的回答,我學到了很多問這個問題! =))@Miki – Blu

+0

也謝謝! @Berriel – Blu

2

由於@Miki在評論中表示,拆分3聲道圖像會給你3個1聲道圖像,而1聲道圖像是灰度!另外,@sturkmen指出了一個重要的事情:OpenCV圖像存儲爲BGR,因此您需要使用CV_BGR2YCrCb而不是CV_RGB2YCrCb中的cvtColor

但是,我看到很多材料以豐富多彩的方式向他們展示(單個頻道),如Hays教授的this

如果您想以這種方式查看它們,您需要爲其他通道設置固定值並將其合併回去。這樣你可以實現下面圖像的第一行。第二行是個別頻道。欲瞭解更多信息,您可以閱讀這post或看這video

YCrCb sample

+0

尼斯博客btw,現在我知道SO用戶在安裝OpenCV時遇到問題時要連接什麼:D – Miki