Странные цвета, которые вы получаете, связаны с тем, что Format8bppIndexed
является палитрой, и вы никогда не редактируете палитру, то есть она сохраняет сгенерированную по умолчанию палитру Windows.Но в вашем случае эта палитра не имеет значения, потому что изображение не 8-битный индексированный формат;он должен быть обработан для преобразования его в RGB.
Быстрый Google для BayerBG8 получил мне эту страницу .В разделе Байера показано, что это довольно своеобразное преобразование, состоящее в использовании специфических шаблонных индексов на изображении в виде R, G и B.
В Википедии есть целая статья о том, как этот материал обычно обрабатывается, но это видео на YouTube показывает основы:
Обратите внимание, что это скользящее окно;для первого пикселя, цвета
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-битный массив (показанный здесь как изображение в градациях серого).Как вы можете видеть, мое собственное демозаечение (второе изображение) гораздо менее точно, чем исправленная версия, которую они из него получили (третье изображение).