exponenta event banner

Сквозное внедрение конвейера обработки цифровых камер

Этот пример показывает реализацию традиционного конвейера обработки камеры, который визуализирует RGB-изображение из RAW Bayer-массива цветных фильтров (CFA). В примере также показан альтернативный рабочий процесс создания RGB с использованием функций поддержки формата RAW на панели инструментов, таких как rawread, rawinfo, и raw2rgb.

Введение

Цифровые однообъективные зеркальные (DSLR) фотоаппараты и многие современные телефонные фотоаппараты могут сохранять данные, собранные с датчика фотоаппарата, непосредственно в файл RAW. Каждый пиксель данных RAW представляет собой количество света, захваченного соответствующим фотодатчиком камеры. Данные зависят от фиксированных характеристик аппаратных средств камеры, таких как чувствительность каждого фотодатчика к определенному диапазону длин волн электромагнитного спектра. Данные также зависят от настроек захвата камеры, таких как время экспозиции, и факторов сцены, таких как источник света.

Это основные этапы обработки в традиционном конвейере обработки камеры:

  1. Импорт содержимого файла RAW

  2. Линеаризация полученного изображения CFA

  3. Масштабирование данных CFA до подходящего диапазона

  4. Применить корректировку баланса белого

  5. Демосаик и поворот

  6. Преобразование изображения CFA в изображение RGB

Можно также применить дополнительные шаги постобработки, такие как обесценение, отсечение подсветки и корректировка контрастности.

Импорт содержимого файла RAW

Камеры получают изображения и создают файлы RAW. Эти файлы RAW содержат:

  • Изображение CFA, записанное фотодатчиком камеры

  • Метаданные, содержащие всю информацию, необходимую для визуализации изображения RGB

Файл RAW может также содержать созданное камерой изображение JPEG для предварительного просмотра или миниатюру JPEG, однако для реализации конвейера камеры необходимы только изображение CFA и метаданные.

Считывание тестового изображения CFA из файла с помощью rawread и отобразить его.

fileName = "colorCheckerTestImage.NEF";

cfaImage = rawread(fileName);
whos cfaImage
  Name             Size                 Bytes  Class     Attributes

  cfaImage      4012x6034            48416816  uint16              
imshow(cfaImage,[])
title("Linear CFA Image")

Figure contains an axes. The axes with title Linear CFA Image contains an object of type image.

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

Например, используйте rawinfo для извлечения метаданных из тестового образа CFA. В метаданных обратите внимание, что значение столбца в VisibleImageSize поле меньше, чем в CFAImageSize поле. rawread функция по умолчанию считывает только видимую часть CFA.

fileInfo = rawinfo(fileName);

if fileInfo.CFASensorType ~= "Bayer"
    error( "The input file %s has CFA Image created by a % sensor." + ...
           "The camera pipeline in this example will work only for a CFA Image created by a Bayer sensor", ...
           fileName,fileInfo.CFASensorType );
end

disp(fileInfo.ImageSizeInfo)
                 CFAImageSize: [4012 6080]
             VisibleImageSize: [4012 6034]
    VisibleImageStartLocation: [1 1]
             PixelAspectRatio: 1
                ImageRotation: 0
            RenderedImageSize: [4012 6034]

Линеаризация полученного изображения CFA

Многие камеры применяют нелинейное сжатие дальности к захваченным сигналам, прежде чем хранить их в файлах RAW. Для создания линейных данных при подготовке к преобразованию данных CFA необходимо обратить это нелинейное сжатие диапазона. Камеры обычно хранят это сжатие диапазона как таблицу поиска (LUT). Если камера не применяет сжатие диапазона, LUT содержит сопоставление идентификаторов. rawread функция автоматически применяет этот LUT к данным CFA и возвращает значения линеаризованного света.

Постройте график подмножества значений в LinearizationTable поле метаданных тестового изображения.

linTable = fileInfo.ColorInfo.LinearizationTable;

plot((0:length(linTable)-1), fileInfo.ColorInfo.LinearizationTable) 
title("Linearization Table")

Figure contains an axes. The axes with title Linearization Table contains an object of type line.

Масштабировать изображение

Метаданные файла RAW включают значение черного уровня, fileInfo.ColorInfo.BlackLevel, и значение белого уровня fileInfo.ColorInfo.WhiteLevel. Диапазон значений пикселей в изображении CFA: [fileInfo.ColorInfo.BlackLevel, fileInfo.ColorInfo.WhiteLevel]. Эти значения можно использовать для масштабирования изображения.

Изображения RAW не имеют истинного черного значения. Даже если затвор закрыт, протекающее через датчики электричество вызывает ненулевое количество фотонов. Камеры используют значение маскированных пикселей для вычисления уровня черного изображения CFA. Различные форматы файлов RAW сообщают об этом черном уровне по-разному. Некоторые форматы файлов определяют уровень черного как одно скалярное значение на канал изображения CFA. Другие форматы, такие как DNG, определяют уровень черного как повторяющуюся область m-by-n, которая начинается в левом верхнем углу видимой части CFA.

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

blackLevel = fileInfo.ColorInfo.BlackLevel;
disp(blackLevel)
   0   0   0   0
if isvector(fileInfo.ColorInfo.BlackLevel)
    cfaMultiChannel = performPerChannelBlackLevelSub(cfaImage, fileInfo);
else
    cfa = performRegionBlackLevelSub(cfaImage, fileInfo);
    
    % Transforms an interleaved CFA into an (M/2-by-N/2-by-4) array, where
    % each plane corresponds to a specific color channel.
    
    % This transformation simplifies pipeline implementation
    cfaMultiChannel = raw2planar(cfa);
end

Чтобы исправить значения данных CFA, меньшие, чем значение черного уровня, установите значение 0.

cfaMultiChannel( cfaMultiChannel < 0 ) = 0;

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

cfaMultiChannel = double(cfaMultiChannel);

whiteLevel = max(cfaMultiChannel(:));
disp(whiteLevel)
        3366
scaledCFAMultiChannel = cfaMultiChannel ./ whiteLevel;

Применить корректировку баланса белого

Баланс белого - это процесс удаления нереальных цветных слепков из визуализированного изображения, так что он кажется ближе к тому, как человеческие глаза увидят предмет.

Сначала извлеките значение баланса белого из метаданных.

camWB = fileInfo.ColorInfo.CameraAsTakenWhiteBalance;

Затем масштабируйте множители так, чтобы значения G каналы 1.

gLoc = strfind(fileInfo.CFALayout,"G"); 
gLoc = gLoc(1);
camWB = camWB/camWB(gLoc);

disp(camWB)
    1.9336    1.0000    1.0000    1.2656
wbMults = reshape(camWB,[1 1 numel(camWB)]);
wbCFAMultiChannel = scaledCFAMultiChannel .* wbMults;

Объединение каналов для создания чередующегося изображения CFA.

cfaWB = planar2raw(wbCFAMultiChannel);

Преобразование чередующегося изображения CFA в 16-битное изображение.

cfaWB = im2uint16(cfaWB);

Демонстрация и поворот

Преобразуйте изображение CFA, закодированное в Bayer, в изображение с трюэколором путем демосейсинга и поворота. Это изображение находится в линейном пространстве камеры.

camspaceRGB = demosaic(cfaWB,fileInfo.CFALayout);

camspaceRGB = imrotate(camspaceRGB,fileInfo.ImageSizeInfo.ImageRotation);

imshow(camspaceRGB) 
title("Rendered Image in Linear Camera Space")

Figure contains an axes. The axes with title Rendered Image in Linear Camera Space contains an object of type image.

Преобразовать изображение CFA в изображение RGB

Можно преобразовать изображение CFA в изображение RGB с помощью функций преобразования пространства подключения профиля (PCS) или с помощью матрицы преобразования, возвращенной в метаданных файла RAW.

Использовать преобразование пространства подключения профиля

Преобразование изображения CFA в выходное цветовое пространство Adobe RGB 1998. Это преобразование состоит из следующих шагов:

  • Преобразование изображения из пространства линейной камеры в пространство соединения профиля, например XYZ.

  • Преобразуйте изображение из пространства подключения профиля XYZ в цветовое пространство Adobe RGB 1998.

cam2xyz = computeXYZTransformation(fileInfo);
xyzImage = imapplymatrix(cam2xyz,im2double(camspaceRGB));

% xyz2rgb function applies Gamma Correction for Adobe RGB 1998 color space
adobeRGBImage = xyz2rgb(xyzImage,"ColorSpace","adobe-rgb-1998","OutputType","uint16");

imshow(adobeRGBImage);
title("Rendered RGB Image in Adobe RGB 1998 Color Space");

Figure contains an axes. The axes with title Rendered RGB Image in Adobe RGB 1998 Color Space contains an object of type image.

Использовать матрицу преобразования из метаданных файла RAW

Используйте матрицу преобразования в fileInfo.ColorInfo.CameraTosRGB поле метаданных файла CFA для преобразования изображения из линейного пространства камеры в линейное пространство sRGB.

% This transformation produces a linear sRGB image
srgbImageLinear = imapplymatrix(fileInfo.ColorInfo.CameraTosRGB, camspaceRGB,"uint16");

% Apply gamma correction for sRGB colorspace
srgbImage = lin2rgb(srgbImageLinear);

imshow(srgbImage)
title("Rendered RGB Image in sRGB Colorspace")

Figure contains an axes. The axes with title Rendered RGB Image in sRGB Colorspace contains an object of type image.

Сравнение трубопроводов

Как показано в этом примере, для преобразования изображения CFA в изображение sRGB можно использовать общие функции панели инструментов обработки изображений и метаданные файла RAW. Это преобразование также можно выполнить с помощью raw2rgb функция. При использовании raw2rgb функция не обеспечивает такой же гибкости, как использование метаданных, результаты сопоставимы. raw2rgb функция использует libraw 0.20.0 Библиотека обработки файлов RAW. Сравните результат raw2rgb преобразование в преобразование PCS для цветового пространства Adobe RGB 1998 и преобразование метаданных для цветовых пространств sRGB.

adobeRGBReference = raw2rgb(fileName,"ColorSpace","adobe-rgb-1998");

montage({adobeRGBReference, adobeRGBImage},"Size",[1 2]);
title("Adobe RGB 1998 Images: Left Image: raw2rgb, Right Image: MATLAB Pipeline")

Figure contains an axes. The axes with title Adobe RGB 1998 Images: Left Image: raw2rgb, Right Image: MATLAB Pipeline contains an object of type image.

srgbReference = raw2rgb(fileName,"ColorSpace","srgb");

montage({srgbReference, srgbImage});
title("sRGB Images: Left Image: raw2rgb, Right Image: MATLAB Pipeline");

Figure contains an axes. The axes with title sRGB Images: Left Image: raw2rgb, Right Image: MATLAB Pipeline contains an object of type image.

Вспомогательные функции

performPerChannelBlackLevelSub функция выполняет вычитание черного уровня при задании черного уровня в качестве скалярного значения для каждого канала.

function cfa = performPerChannelBlackLevelSub(cfa, fileInfo)
    % Transforms an interleaved CFA into an (M/2-by-N/2-by-4) array, where
    % each plane corresponds to a specific color channel.
    
    % This transformation simplifies pipeline implementation
    cfa = raw2planar(cfa);
    
    blackLevel = fileInfo.ColorInfo.BlackLevel;
    blackLevel = reshape(blackLevel,[1 1 numel(blackLevel)]);
    
    cfa = cfa - blackLevel;
end

performRegionBlackLevelSub функция выполняет вычитание черного уровня при задании его в области m-by-n.

function cfa = performRegionBlackLevelSub(cfa,fileInfo)
    % The m-by-n black-level must be repeated periodically across the entire image 
    repeatDims = fileInfo.ImageSizeInfo.VisibleImageSize ./ size(fileInfo.ColorInfo.BlackLevel);
    blackLevel = repmat(fileInfo.ColorInfo.BlackLevel, repeatDims);
    
    cfa = cfa - blackLevel;
end

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

function cam2xyz = computeXYZTransformation(fileInfo)
    % The CameraToXYZ matrix imposes an RGB order i.e 
    % [X, Y, Z]' = fileInfo.ColorInfo.CameraToXYZ .* [R, G, B]'.
    
    % However, the order of values for white balance mutlipliers are as per
    % fileInfo.CFALayout. Hence, we have to reorder the multipliers to
    % ensure we are scaling the correct row of the CameraToXYZ matrix.
    wbIdx = strfind(fileInfo.CFALayout,"R");
    gidx = strfind(fileInfo.CFALayout,"G"); wbIdx(2) = gidx(1); 
    wbIdx(3) = strfind(fileInfo.CFALayout,"B");
    
    wbCoeffs = fileInfo.ColorInfo.D65WhiteBalance(wbIdx);
    
    cam2xyz = fileInfo.ColorInfo.CameraToXYZ ./ wbCoeffs;
end