2015-10-14 115 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