OpenCV cvtColor () изменяет размеры моего изображения и имеет неправильные цвета

Я использую openCV C ++ API и пытаюсь преобразовать буфер камеры (YUV_NV12) в формат RGB. Однако размеры моего изображения изменились (ширина уменьшилась с 720 до 480), и цвета неправильные (вроде фиолетового / зеленого цвета).

unsigned char* myYUVBufferPointer = (something passed as argument)
int myYUVBufferHeight = 1280
int myYUVBufferWidth = 720

cv::Mat yuvMat(myYUVBufferHeight, myYUVBufferWidth, CV_8U, myYUVBufferPointer);
cv::Mat rgbMat;
cv::cvtColor(yuvMat, rgbMat, CV_YUV2RGB_NV12);
cv::imwrite("path/to/my/image.jpg",rgbMat);

Есть идеи? * (Меня больше интересует размер, измененный, чем цвет, так как я в конечном итоге преобразую его в CV_YUV2GRAY_NV12, и это работает, но размер — нет). *

1

Решение

Ваш код создает одноканальное (в градациях серого) изображение, называемое yuvMat из серии unsigned chars. Когда вы пытаетесь — принудительно — преобразовать одноканальное изображение из YUV 4: 2: 0 в многоканальный RGB, библиотека OpenCV предполагает, что в каждой строке содержится 2/3 полной информации 4: 4: 4 (1 x height x width за Y а также 1/2 height x width за U а также V каждый вместо 3 x height x width для нормального YUV) поэтому ваша ширина конечного изображения уменьшается до 2/3 от первоначальной ширины. Можно предположить, что половина данных, считанных с исходного изображения, поступает из нераспределенной памяти, хотя исходное изображение имеет только width x height ucharно 2 x width x height ucharс читаются из памяти!

Если твой uchar буфер уже правильно отформатирован для серии байтов, представляющих YUV_NV12 (4: 2: 0 субсэмплинг) в обычном width x height байт на канал, все, что вам нужно сделать, это создать свой оригинальный yuvMat как CV_8UC3 и ты в порядке. Выше предполагается, что все чередование и позиционирование канала уже реализованы в буфере. Скорее всего, это не так. YUV_NV12 данные приходят с width x height ucharс Y, с последующим (1/2) width x (1/2) x height of 2 x ucharс представляет UV вместе взятые. Вы, вероятно, должны написать свой собственный читатель, чтобы прочитать Y, U, а также V данные отдельно и построить 3 одноканальных Matс размером width x height — заполнение горизонтальных и вертикальных пробелов в обоих U а также V каналы — тогда используйте cv::merge() объединить эти одноканальные изображения в 3-канальный YUV Перед использованием cv::cvtColor() конвертировать это изображение с помощью CV_YUV2BGR вариант. Обратите внимание на использование BGR вместо RGB,

3

Другие решения

Возможно, что «что-то передано в качестве аргумента» не имеет достаточно данных для заполнения 720 строк. В некоторых видеокамерах не все три канала представлены с одинаковым количеством битов. Например, при захвате видео на iPhone три канала используют 8-4-4 байта вместо 8-8-8. Я не использовал этот тип камеры с OpenCV, но, скорее всего, проблема здесь.

0

По вопросам рекламы [email protected]