Реализуйте конвейер обработки цифрового фотоаппарата

В этом примере показано, как реализовать конвейер обработки камеры, который представляет изображение RGB от НЕОБРАБОТАННОГО изображения массива цветового фильтра (CFA) шаблона Байера.

Камеры цифрового отражения одно линзы (DSLR) и много современных телефонных камер, могут сохранить данные, собранные от датчика камеры непосредственно к НЕОБРАБОТАННОМУ файлу. Каждый пиксель Необработанных данных является количеством света, полученным соответствующим фотодатчиком камеры. Данные зависят от фиксированных характеристик оборудования камеры, таких как чувствительность каждого фотодатчика к конкретной области значений длин волн электромагнитного спектра. Данные также зависят от настроек захвата камеры, таких как выдержка и факторы сцены, такие как источник света.

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

  1. Импортируйте НЕОБРАБОТАННОЕ содержимое файла

  2. Линеаризуйте изображение CFA

  3. Масштабируйте данные о CFA к подходящей области значений

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

  5. Demosaic шаблон Байера

  6. Преобразуйте изображение demosaiced в sRGB цветовое пространство

Пример также показывает, как создать изображение RGB из НЕОБРАБОТАННОГО изображения, когда у вас нет НЕОБРАБОТАННЫХ метаданных файла.

Считайте НЕОБРАБОТАННОЕ содержимое файла

НЕОБРАБОТАННЫЕ файлы, созданные цифровым фотоаппаратом, содержат:

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

  • Метаданные, которые содержат всю информацию, должны были представить изображение RGB

Считайте изображение CFA шаблона Байера из НЕОБРАБОТАННОГО файла с помощью rawread функция.

fileName = "colorCheckerTestImage.NEF";
cfaImage = rawread(fileName);

Перечислите информацию о cfaImage переменная и отображение изображение.

whos cfaImage
  Name             Size                 Bytes  Class     Attributes

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

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

Считайте НЕОБРАБОТАННЫЕ метаданные файла с помощью rawinfo функция.

cfaInfo = rawinfo(fileName);

Метаданные содержат несколько полей с информацией, используемой, чтобы обработать НЕОБРАБОТАННОЕ изображение. Например, отобразите содержимое ImageSizeInfo поле . Метаданные указывают, что существует больше столбцов в массиве фотодатчика CFA, чем в видимом изображении. Различие обычно возникает, когда камера маскирует фрагмент фотодатчика, чтобы препятствовать тому, чтобы те разделы получили любой свет. Это включает точную меру уровня черного датчика.

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

НЕОБРАБОТАННЫЕ метаданные файла также включают информацию, которые включают линеаризацию, коррекцию в области черного, баланс белого, и другие операции по обработке должны были преобразовать Необработанные данные в RGB.

colorInfo = cfaInfo.ColorInfo
colorInfo = struct with fields:
           LinearizationTable: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... ]
                   BlackLevel: [0 0 0 0]
                   WhiteLevel: [3827 3827 3827 3827]
                  CameraToXYZ: [3x3 double]
                 CameraTosRGB: [3x3 double]
    CameraAsTakenWhiteBalance: [495 256 256 324]
              D65WhiteBalance: [2.1900 0.9286 0.9286 1.0595]
                   ICCProfile: []

Линеаризуйте изображение CFA

Много камер применяют нелинейное сжатие области значений к полученным сигналам прежде, чем сохранить их в НЕОБРАБОТАННЫХ файлах. Камеры обычно хранят это сжатие области значений как интерполяционную таблицу.

Постройте представительное подмножество значений в LinearizationTable поле метаданных изображения. Значения выше maxLinValue продолжите увеличиваться линейно.

maxLinValue = 10^4;
linTable = colorInfo.LinearizationTable;
plot(0:maxLinValue-1,linTable(1:maxLinValue)) 
title("Linearization Table")

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

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

Масштабируйте пиксельные значения к подходящей области значений

Выполните коррекцию в области черного

НЕОБРАБОТАННЫЕ изображения не имеют истинного черного значения. Даже с закрытым затвором, электричество, текущее через датчики, вызывает ненулевые количества фотона. Камеры используют значение пикселей маскированных, чтобы вычислить уровень черного изображения CFA. Чтобы масштабировать изображение, вычтите измеренный уровень черного из данных изображения CFA.

НЕОБРАБОТАННЫЕ форматы файлов могут сообщить об этом уровне черного в различных форматах. НЕОБРАБОТАННЫЕ метаданные файла для изображения в этом примере задают уровень черного как вектор с одним элементом на канал изображения CFA. Другие НЕОБРАБОТАННЫЕ форматы файлов, такие как DNG, задают уровень черного как повторную матрицу m на n, которая запускается в главном левом угле видимого фрагмента CFA.

Получите значение уровня черного Необработанных данных от BlackLevel поле метаданных.

blackLevel = colorInfo.BlackLevel;

Чтобы выполнить коррекцию в области черного, сначала преобразуйте вектор уровня черного в матрицу 2 на 2. Не используйте этот шаг для НЕОБРАБОТАННЫХ изображений, которые задают уровень черного как матрицу.

blackLevel = reshape(blackLevel,[1 1 numel(blackLevel)]);
blackLevel = planar2raw(blackLevel);

Реплицируйте матрицу уровня черного, чтобы быть размером видимого изображения.

repeatDims = cfaInfo.ImageSizeInfo.VisibleImageSize ./ size(blackLevel);
blackLevel = repmat(blackLevel,repeatDims);

Вычтите матрицу уровня черного из матрицы изображений CFA.

cfaImage = cfaImage - blackLevel;

Зафиксируйте отрицательные пиксельные значения

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

cfaImage = max(0,cfaImage);

Масштабируйте пиксельные значения

НЕОБРАБОТАННЫЕ метаданные файла часто представляют уровень белого, когда максимальное значение, позволенное по условию, вводит. Если это значение уровня белого намного выше, чем самое высокое значение интенсивности в изображении, то использование этого значения уровня белого для масштабирования результатов в изображении, которое более темно, чем он, должно быть. Чтобы избежать этого, масштабируйте изображение CFA с помощью максимального пиксельного значения, найденного в изображении.

cfaImage = double(cfaImage);
maxValue = max(cfaImage(:))
maxValue = 3366
cfaImage = cfaImage ./ maxValue;

Настройте баланс белого

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

Получите значения баланса белого от метаданных. Существует два типа доступных метаданных баланса белого. Этот шаг примера использует CameraAsTakenWhiteBalance поле масштабирует цветовые каналы, чтобы сбалансировать линейные пиксельные значения. Пример использует D65WhiteBalance поле позже в трубопроводе, чтобы настроить цвета к белой точке D65.

whiteBalance = colorInfo.CameraAsTakenWhiteBalance
whiteBalance = 1×4

   495   256   256   324

Масштабируйте множители так, чтобы значениями зеленых цветовых каналов был 1.

gLoc = strfind(cfaInfo.CFALayout,"G"); 
gLoc = gLoc(1);
whiteBalance = whiteBalance/whiteBalance(gLoc);

whiteBalance = reshape(whiteBalance,[1 1 numel(whiteBalance)]);
whiteBalance = planar2raw(whiteBalance);

Реплицируйте матрицу баланса белого, чтобы быть размером видимого изображения.

whiteBalance = repmat(whiteBalance,repeatDims);
cfaWB = cfaImage .* whiteBalance;

Преобразуйте изображение CFA в 16-битное изображение.

cfaWB = im2uint16(cfaWB);

Demosaic

Преобразуйте закодированное Байером изображение CFA в изображение истинного цвета demosaicing. Изображение истинного цвета находится в линейном пространстве камеры.

cfaLayout = cfaInfo.CFALayout;
imDebayered = demosaic(cfaWB,cfaLayout);
imshow(imDebayered)
title("Demosaiced RGB Image in Linear Camera Space")

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

Преобразуйте от цветового пространства камеры до цветового пространства RGB

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

Используйте преобразование пробела связи профиля

Получите матрицу преобразования между линейным пространством камеры и пробелом связи профиля XYZ от CameraToXYZ поле метаданных. Эта матрица налагает порядок RGB. Другими словами:

[X,Y,Z]' = CameraToXYZ.*[R,G,B]'

cam2xyzMat = colorInfo.CameraToXYZ
cam2xyzMat = 3×3

    1.5573    0.1527    0.0794
    0.6206    0.9012   -0.2690
    0.0747   -0.3117    1.4731

Нормируйте cam2xyzMat матрица согласно белой точке D65. Получите значения нормализации XYZ от D65WhiteBalance поле метаданных.

whiteBalanceD65 = colorInfo.D65WhiteBalance
whiteBalanceD65 = 1×4

    2.1900    0.9286    0.9286    1.0595

Множители баланса белого упорядочены согласно CFALayout поле метаданных. Переупорядочьте множители, чтобы совпадать с упорядоченным расположением строки cam2xyzMat матрица.

cfaLayout = cfaInfo.CFALayout;
wbIdx(1) = strfind(cfaLayout,"R");
gidx = strfind(cfaLayout,"G");
wbIdx(2) = gidx(1); 
wbIdx(3) = strfind(cfaLayout,"B");

wbCoeffs = whiteBalanceD65(wbIdx);
cam2xyzMat = cam2xyzMat ./ wbCoeffs;

Преобразуйте изображение от линейного пространства камеры до цветового пространства XYZ с помощью imapplymatrix функция. Затем преобразуйте изображение в sRGB цветовое пространство и примените гамма-коррекцию с помощью xyz2rgb функция.

imXYZ = imapplymatrix(cam2xyzMat,im2double(imDebayered));
srgbPCS = xyz2rgb(imXYZ,"OutputType","uint16");
imshow(srgbPCS)
title("sRGB Image Using PCS")

Figure contains an axes object. The axes object with title sRGB Image Using PCS contains an object of type image.

Используйте матрицу преобразования от НЕОБРАБОТАННЫХ метаданных файла

Преобразуйте изображение от линейного пространства камеры до линейного цветового пространства RGB с помощью матрицы преобразования в CameraTosRGB поле метаданных.

cam2srgbMat = colorInfo.CameraTosRGB;
imTransform = imapplymatrix(cam2srgbMat,imDebayered,"uint16");

Примените гамма-коррекцию, чтобы принести изображение от линейного sRGB цветового пространства до sRGB цветового пространства.

srgbTransform = lin2rgb(imTransform);
imshow(srgbTransform)
title("sRGB Image using Transformation Matrix")

Figure contains an axes object. The axes object with title sRGB Image using Transformation Matrix contains an object of type image.

Преобразуйте СЫРЫЕ ДАННЫЕ в RGB без метаданных

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

Преобразуйте данные изображения в НЕОБРАБОТАННОМ файле к sRGB цветовому пространству с помощью raw2rgb функция.

srgbAuto = raw2rgb(fileName);
imshow(srgbAuto)
title("sRGB Image using raw2rgb Function")

Figure contains an axes object. The axes object with title sRGB Image using raw2rgb Function contains an object of type image.

Сравните результат raw2rgb преобразование в то полученное использование полного конвейера обработки камеры с помощью PCS и матрицы преобразования.

montage({srgbPCS,srgbTransform,srgbAuto},"Size",[1 3]);
title(["RAW to sRGB Images: PCS (Left) vs.";"raw2rgb Function (Center) vs. Transformation (Right)"])

Figure contains an axes object. The axes object with title RAW to sRGB Images: PCS (Left) vs. raw2rgb Function (Center) vs. Transformation (Right) contains an object of type image.

Смотрите также

| | | |