Запись матрицы изображений OpenCV CV_8UC3 в записываемое растровое изображение
У меня есть два монохроматических изображения в виде байта [], снятых с камер. Я хочу объединить эти изображения и записать объединенное изображение в записываемое растровое изображение.
Слияние изображений: OpenCV
Используя openCV, я создаю Mat
объекты (типа CV_8UC1
) из байтовых массивов (greenMat
для зеленого и redMat
для изображения канала красного цвета) и объединить их с помощью Cv2.Merge
Mat mergedMat = new Mat(greenMat.Height, greenMat.Width, MatType.CV_8UC3);
Mat emptyMat = Mat.Zeros(greenMat.Height, greenMat.Width, MatType.CV_8UC1);
Cv2.Merge(new[]
{
redMat, greenMat, emptyMat
}, mergedMat);
Теперь mergedMat.ToBytes() перенастраивает буфер размером 2175338. Почему этот размер? Объединение трех одноканальных матриц (CV_8UC1), если размер 2448x2048, в одну трехканальную матрицу (CV_8UC3) должно привести к буферу размером 15040512, или я что-то здесь упустил?
Показать объединенное изображение: WriteableBitmap
Я хочу отобразить объединенное изображение, записав его в существующий WriteableBitmap
инициализируется через
ImageSource = new WriteableBitmap(
width, //of the green image
height, //of the green image
96, //dpiX: does not affect image as far as I tested
96, //dpiY
PixelFormats.Rgb24, //since the combined image is a three channel color image
null); //no bitmap palette needed for used PixelFormat
Это правильная инициализация? Я не уверен насчет PixelFormat
Вот. dpiX
а также dpiY
значения также, кажется, не имеют никакого эффекта. Как они используются?
Сложность, с которой я не могу сейчас нормально работать - это записать данные изображения в WriteableBitmap
,
Использование следующего кода для получения байтового массива объединенного изображения и использование WriteableBitmap
Метод ' WritePixels' с шагом в соответствии с PixelFormat ImageSources дает System.ArgumentException: 'Buffer size is not sufficient.'
var mergedBuffer = mergedMat.ToBytes();
var bytesPerPixel = (PixelFormats.Rgb24.BitsPerPixel + 7) / 8;
var stride = bytesPerPixel * width;
((WriteableBitmap)ImageSource).WritePixels(
new Int32Rect(0, 0, width, height),
mergedBuffer,
stride,
0)
Изменить: Stride рассчитывается в соответствии с этим ответом, хотя это не обязательно с фиксированным PixelFormat
как здесь.
Почему буфер слишком маленький? Я инициализировал WriteableBitmap
с правильной шириной и высотой и PixelFormats.Rgb24
, Я правильно рассчитываю свой шаг?
Решение
Благодаря предложениям @Micka в комментариях я понял, mergedMat.ToBytes
Кажется, метод не делает то, что я исключил. Вместо этого я попытался использовать mergedMat.Data
указатель вроде так:
var mergedBufferSize = (int)(mergedMat.Total() * mergedMat.Channels());
byte[] mergedBuffer = new byte[mergedBufferSize];
System.Runtime.InteropServices.Marshal.Copy(
mergedMat.Data,
mergedBuffer,
0,
mergedBufferSize);
Все работает нормально таким образом.