2015-10-14 2 views
3

Я хочу разделить YCrCb на каналы Y, Cr и Cb.Разделение изображения YCrCb на его каналы интенсивности

Код работает хорошо, но когда я показываю каналы с imshow("Y", y) для каждого Y, Cr, Cb, все каналы выглядят серыми.

Только 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 компонента изображения, а затем изменить его обратно в RGB с объединением других компонентов (Cr и Cb). Наконец, я собираюсь получить размытую версию оригинального изображения RGB. Однако мой средний фильтр возвращает всегда серое размытое изображение. Хотя это может быть так из-за того, что мои компоненты Cr, Cb серые.

+1

Вы разбивая трехканальное изображение на 3 1-канальные изображения. 1-канальные изображения имеют оттенки серого и будут отображаться как серый-sh. Тот факт, что их значения пикселей на самом деле является информацией о цвете, не имеет значения, они все еще имеют оттенки серого. Итак, ваш код в порядке, только ваша интерпретация неверна. – Miki

+0

Что я должен добавить в свой код, чтобы сделать их яркими[email protected] – 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

Wow !! Большое вам спасибо за ответ, который я многому научился, задавая этот вопрос! =)) @Miki – Blu

+0

Спасибо тоже! @Berriel – Blu

2

Как указано в комментариях, разделение 3-канального изображения даст вам 3 1-канальных изображения, а одноканальные изображения - в оттенках серого! Кроме того, @sturkmen указал на важную вещь: изображения OpenCV хранятся как BGR, поэтому вам нужно использовать CV_BGR2YCrCb вместо CV_RGB2YCrCb в cvtColor.

Однако я вижу много материалов, показывающих их (отдельные каналы) красочным образом, например this от профессора Хейса.

Если вы хотите увидеть их таким образом, вам нужно установить фиксированное значение на другие каналы и объединить их обратно. Таким образом, вы можете достичь первой строки изображения ниже. Вторая строка - это отдельные каналы. Для получения дополнительной информации вы можете прочитать это post или посмотреть это video.

YCrCb sample

+0

Хороший блог кстати, теперь я знаю, что нужно связывать, когда у пользователей SO возникают проблемы с установкой OpenCV: D – Miki