2016-10-05 4 views
4

Есть ли способ конвертировать из RGB в формат YUYV (YUY 4: 2: 2)? Я заметил, что OpenCV имеет обратную операцию, но не RGB для YUYV по какой-то причине. Может быть, кто-то может указать на код, который делает это (даже вне библиотеки OpenCV)?Преобразование из RGB в YUYV в OpenCV

ОБНОВЛЕНИЕ

Я нашел libyuv библиотеку, которая может работать для этой цели, делая BGR, чтобы ARGB преобразования, а затем ARGB в формат YUY2 (надеюсь, это то же самое, как YUYV 4: 2: 2). Но, похоже, это не работает. Вы случайно не знаете, как выглядят размеры/тип буфера yuyv? Каков его шаг?

Чтобы уточнить, YUYV и YUY2 - это те же форматы, если это помогает.

UPDATE 2 Вот мой код, используя libyuv библиотеки:

Mat frame; 
    // Convert original image im from BGR to BGRA for further use in libyuv 
    cvtColor(im, frame, CVX_BGR2BGRA); 
    // Actually libyuv requires ARGB (i.e. reverse of BGRA), so I swap channels here 
    int from_to[] = { 0,3, 1,2, 2,1, 3,0 }; 
    mixChannels(&frame, 1, &frame, 1, from_to, 4); 
    // This is the most confusing part. Not sure what argb_stride suppose to be - length of a row in bytes or size of single value in the array? 
    const uint8_t* argb_data = frame.data; 
    int argb_stride = 8; 

    // Also it is not clear what size of yuyv frame should be since we duplicate one Y 
    Mat yuyv(frame.rows, frame.cols, CVX_8UC2); 
    uint8_t* yuyv_data = yuyv.data; 
    int yuyv_stride = 16; 
    // Do actual conversion 
    libyuv::ARGBToYUY2(argb_data, argb_stride, yuyv_data, yuyv_stride, 
    frame.cols, frame.rows); 
    // Then I feed yuyv_data to video stream buffer and see green or purple image instead of video stream. 

UPDATE 3

Mat frame; 
    cvtColor(im, frame, CVX_BGR2BGRA); 

    // ARGB 
    int from_to[] = { 0,3, 1,2, 2,1, 3,0 }; 
    Mat rgba(frame.size(), frame.type()); 
    mixChannels(&frame, 1, &rgba, 1, from_to, 4); 
    const uint8_t* argb_data = rgba.data; 
    int argb_stride = rgba.cols*4; 

    Mat yuyv(rgba.rows, rgba.cols, CVX_8UC2); 
    uint8_t* yuyv_data = yuyv.data; 
    int yuyv_stride = width * 2; 
    int res = libyuv::ARGBToYUY2(argb_data, argb_stride, yuyv_data, yuyv_stride, rgba.cols, rgba.rows); 

enter image description here

+0

Я не гарантирую, но [здесь] (http://study.marearts.com/2012/11/yuv-color-format-444-422-411-simple.html) – Miki

+0

@Miki Знаете ли вы какой размер/тип выходного массива должен быть? Какова ценность img_stride из приведенного вами примера? –

+0

Я задаю, что размер и тип совпадают. Тип должен быть 3 'uint8/uchar', который является OpenCV' Vec3b'. Шаг - это длина между двумя последовательными строками, в основном количество столбцов, если данные непрерывны (вам может потребоваться умножить на 3, если у вас есть 3 канала). – Miki

ответ

1

Оказывается, что хотя метод называется ARGBToYUY2 него требуется порядок каналов BGRA (нет t reverse).

+0

И вот доказательство: https://github.com/Shamim1977/libyuv/blob/master/source/row_common.cc#L650 –

Смежные вопросы