Basler USB Camera байтовый буфер для преобразования изображений - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть USB-камера Basler acA3800.

            IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);
            // Image grabbed successfully?
            if (grabResult.GrabSucceeded)
            {
                byte[] buffer = grabResult.PixelData as byte[];
                ImageWindow.DisplayImage(0, grabResult);

                pictureBox1.Image = ImageFromRawBgraArray(buffer,3840,2748,PixelFormat.Format8bppIndexed);
                MessageBox.Show(grabResult.PixelTypeValue.ToString());
            }

В этом разделе кода отображается само окно изображения.

У меня есть данные пикселей снятого изображения.Исходное изображение хорошо, но когда я конвертирую его в изображение, оно искажается.И вот моя функция преобразования.

    public Image ImageFromRawBgraArray(byte[] arr, int width, int height, PixelFormat pixelFormat)
    {
        var output = new Bitmap(width, height, pixelFormat);
        var rect = new Rectangle(0, 0, width, height);
        var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);

        // Row-by-row copy
        var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8;
        var ptr = bmpData.Scan0;
        for (var i = 0; i < height; i++)
        {
            Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);
            ptr += bmpData.Stride;
        }

        output.UnlockBits(bmpData);
        return output;
    }

Original image

Image from byte buffer

Я думаю, что этоо типе пикселей.Я выбрал формат пикселя PixelFormat.Format8bppIndexed.Другие не работают.

                MessageBox.Show(grabResult.PixelTypeValue.ToString());

В этом окне сообщения отображается тип пикселя.и это говорит "BayerBG8".Что это значит?Что я должен сделать, чтобы получить четкое изображение?

1 Ответ

0 голосов
/ 26 апреля 2018

Странные цвета, которые вы получаете, связаны с тем, что Format8bppIndexed является палитрой, и вы никогда не редактируете палитру, то есть она сохраняет сгенерированную по умолчанию палитру Windows.Но в вашем случае эта палитра не имеет значения, потому что изображение не 8-битный индексированный формат;он должен быть обработан для преобразования его в RGB.

Быстрый Google для BayerBG8 получил мне эту страницу .В разделе Байера показано, что это довольно своеобразное преобразование, состоящее в использовании специфических шаблонных индексов на изображении в виде R, G и B.

Bayer pattern

В Википедии есть целая статья о том, как этот материал обычно обрабатывается, но это видео на YouTube показывает основы:

Bayer to RGB Demosaicing

Обратите внимание, что это скользящее окно;для первого пикселя, цвета

R G
G B

но для второго пикселя они будут

G R
B G

и для одного ряда вниз будет использоваться первый

G B
R G

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

public static Byte[] BayerToRgb(Byte[] arr, ref Int32 width, ref Int32 height, ref Int32 stride, Boolean greenFirst, Boolean blueRowFirst)
{
    Int32 actualWidth = width - 1;
    Int32 actualHeight = height - 1;
    Int32 actualStride = actualWidth*3;
    Byte[] result = new Byte[actualStride*actualHeight];
    for (Int32 y = 0; y < actualHeight; y++)
    {
        Int32 curPtr = y*stride;
        Int32 resPtr = y*actualStride;
        Boolean blueRow = y % 2 == (blueRowFirst ? 0 : 1);
        for (Int32 x = 0; x < actualWidth; x++)
        {
            // Get correct colour components from sliding window
            Boolean isGreen = (x + y) % 2 == (greenFirst ? 0 : 1);
            Byte cornerCol1 = isGreen ? arr[curPtr + 1] : arr[curPtr];
            Byte cornerCol2 = isGreen ? arr[curPtr + stride] : arr[curPtr + stride + 1];
            Byte greenCol1 = isGreen ? arr[curPtr] : arr[curPtr + 1];
            Byte greenCol2 = isGreen ? arr[curPtr + stride + 1] : arr[curPtr + stride];
            Byte blueCol = blueRow ? cornerCol1 : cornerCol2;
            Byte redCol = blueRow ? cornerCol2 : cornerCol1;
            // 24bpp RGB is saved as [B, G, R].
            // Blue
            result[resPtr + 0] = blueCol;
            // Green
            result[resPtr + 1] = (Byte) ((greenCol1 + greenCol2)/2);
            // Red
            result[resPtr + 2] = redCol;
            curPtr++;
            resPtr+=3;
        }
    }
    height = actualHeight;
    width = actualWidth;
    stride = actualStride;
    return result;
}

Параметры greenFirst и blueRowFirst указывают, является ли зеленыйпервый встреченный пиксель на изображении, и синие пиксели на первой или второй строке.Для вашего формата "BG" оба значения должны быть ложными.

Исходя из этого, с помощью отрегулированных ширины, высоты и шага вы можете преобразовать это в новое изображение, используя метод, который вы уже использовали,но с Format24bppRgb в качестве пиксельного формата.

Лично я использую несколько более продвинутый метод, который учитывает шаг ввода и может обрабатывать проиндексированный контент.Если вам интересно, этот метод можно найти здесь .

Обратите внимание, что приведенный выше метод демозаики - очень базовый, и покажет многие изожидаемые артефакты .Существуют более продвинутые методы анализа данных и получения более точных результатов в зависимости от того, как было получено изображение, но, вероятно, вам понадобится немало исследований, чтобы все это выяснить и реализовать самостоятельно.

Вот небольшой тест, который я провел, начиная с отфильтрованного по Байеру изображения, которое я нашел в сети , который я преобразовал в 8-битный массив (показанный здесь как изображение в градациях серого).Как вы можете видеть, мое собственное демозаечение (второе изображение) гораздо менее точно, чем исправленная версия, которую они из него получили (третье изображение).

Bayer demosaicing test

...