2014-09-29 2 views
0

Я исследовал и снял свой предыдущий вопрос (Is there a way to avoid conversion from YUV to BGR?). Я хочу наложить несколько изображений (формат YUV) на получившееся изображение большего размера (подумайте об этом как о холсте) и отправьте его через сетевую библиотеку (OPAL) вперед, не преобразовывая ее в BGR.Наложение/слияние двух (и более) изображений YUV в OpenCV

Вот код:

Mat tYUV; 
    Mat tClonedYUV; 
    Mat tBGR; 
    Mat tMergedFrame; 
    int tMergedFrameWidth = 1000; 
    int tMergedFrameHeight = 800; 
    int tMergedFrameHalfWidth = tMergedFrameWidth/2; 

    tYUV = Mat(tHeader->height * 1.5f, tHeader->width, CV_8UC1, OPAL_VIDEO_FRAME_DATA_PTR(tHeader)); 
    tClonedYUV = tYUV.clone(); 

    tMergedFrame = Mat(Size(tMergedFrameWidth, tMergedFrameHeight), tYUV.type(), cv::Scalar(0, 0, 0)); 
    tYUV.copyTo(tMergedFrame(cv::Rect(0, 0, tYUV.cols > tMergedFrameWidth ? tMergedFrameWidth : tYUV.cols, tYUV.rows > tMergedFrameHeight ? tMergedFrameHeight : tYUV.rows))); 
    tClonedYUV.copyTo(tMergedFrame(cv::Rect(tMergedFrameHalfWidth, 0, tYUV.cols > tMergedFrameHalfWidth ? tMergedFrameHalfWidth : tYUV.cols, tYUV.rows > tMergedFrameHeight ? tMergedFrameHeight : tYUV.rows))); 


    namedWindow("merged frame", 1); 
    imshow("merged frame", tMergedFrame); 
    waitKey(10); 

Результат выше кода выглядит следующим образом: enter image description here

Я думаю, что изображение не правильно интерпретированы, поэтому картины остаться черный/белый (Y компонент), а под ними - U и V. Есть изображения, которые описывают проблему хорошо (http://en.wikipedia.org/wiki/YUV):

enter image description here

и: http://upload.wikimedia.org/wikipedia/en/0/0d/Yuv420.svg

Есть ли способ, чтобы эти значения, чтобы быть правильно читать? Думаю, я не должен копировать все изображения (их компоненты Y, U, V) прямо в рассчитанные позиции. Компоненты U и V должны быть ниже их и в правильном порядке, я прав?

+0

Тип tYUV должен быть CV_8UC3 (если вы хотите все 3 канала yuv). также, если у вас есть только пиксели w * h, вы не можете сделать изображение больше, чем вы. (что 'tHeader-> height * 1.5f' должно идти) – berak

+0

Я не могу найти в документации OpenCV какой-либо ключ, способен ли он выполнять суб-изображение copyTo() в режиме YUV (это должно быть ужасным беспорядком из-за к организации данных), факт в том, что изображение определенно не организовано как матрица больше – armel

+0

@berak Я не совсем понимаю, почему у меня должно быть три канала. AFAIK, если у меня есть изображение 'x' pixels wide и' y' pixels tall, в формате YUV я получу цифры 'x * y' для Y-компонента,' x * y/4' для U и 'x * y/4 'номера для V-компонента. Поэтому в целом у меня есть цифры «1.5 * x * y». Вот почему я ставлю эту 'tHeader-> height * 1.5f'. – y434y

ответ

0

Во-первых, существует несколько форматов YUV, поэтому вам нужно четко указать, какой из них вы используете.
Согласно вашему образу, ваш формат YUV составляет Y'UV420p.
Независимо от того, что гораздо проще конвертировать в работу BGR, а затем конвертировать обратно.

Если это не вариант, вам в значительной степени нужно управлять ROI самостоятельно. YUV обычно представляет собой плоский формат, в котором каналы не (полностью) мультиплексированы, а некоторые имеют разные размеры и глубину. Если вы не используете внутренние преобразования цветов, вам нужно будет знать точный формат YUV и самостоятельно управлять копированием ROI пикселей.

С изображением YUV спецификатор формата CV_8UC* не означает многого, кроме реальных требований к памяти. Он, конечно же, не указывает мультиплексирование пикселей/каналов.

Например, если вы хотите использовать только Y-компонент, то Y часто является первой плоскостью изображения, поэтому первая «половина» всего изображения может рассматриваться только как монохромное изображение 8UC1. В этом случае использование ROI легко.

+0

Я хочу масштабировать изображения, а затем копировать их на большом холсте (это похоже на экран для видеоконференции on-line). Поэтому мне нужно использовать все компоненты. Есть ли у вас какие-либо рекомендации при копировании U и V вручную? – y434y

+0

Вы должны действительно перейти к формату на основе канала, например BGR. 'cv :: resize' изменяет размер каждого канала независимо. Он предполагает фиксированное/известное количество мультиплексированных каналов одинакового размера.Если вы используете его (в большинстве форматов) YUV, он будет смешивать значения по каналам, если он не падает из-за разных размеров изображения канала (например, U и V каждый часто имеют 1/4 размера Y). –