Запись матрицы изображений 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);

Все работает нормально таким образом.

0 ответов

Другие вопросы по тегам