В этом примере показано, как реализовать конвейер обработки камеры, который представляет изображение RGB от НЕОБРАБОТАННОГО изображения массива цветового фильтра (CFA) шаблона Байера.
Камеры цифрового отражения одно линзы (DSLR) и много современных телефонных камер, могут сохранить данные, собранные от датчика камеры непосредственно к НЕОБРАБОТАННОМУ файлу. Каждый пиксель Необработанных данных является количеством света, полученным соответствующим фотодатчиком камеры. Данные зависят от фиксированных характеристик оборудования камеры, таких как чувствительность каждого фотодатчика к конкретной области значений длин волн электромагнитного спектра. Данные также зависят от настроек захвата камеры, таких как выдержка и факторы сцены, такие как источник света.
В зависимости от информации, доступной в метаданных для вашего изображения, может быть несколько способов реализовать трубопровод, который приводит к эстетически приятным результатам. Пример показывает одну последовательность операций в традиционном конвейере обработки камеры с помощью подмножества метаданных, сопоставленных с Необработанными данными.
Импортируйте НЕОБРАБОТАННОЕ содержимое файла
Линеаризуйте изображение CFA
Масштабируйте данные о CFA к подходящей области значений
Примените корректировку баланса белого
Demosaic шаблон Байера
Преобразуйте изображение 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")
Считайте НЕОБРАБОТАННЫЕ метаданные файла с помощью 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: []
Много камер применяют нелинейное сжатие области значений к полученным сигналам прежде, чем сохранить их в НЕОБРАБОТАННЫХ файлах. Камеры обычно хранят это сжатие области значений как интерполяционную таблицу.
Постройте представительное подмножество значений в LinearizationTable
поле метаданных изображения. Значения выше maxLinValue
продолжите увеличиваться линейно.
maxLinValue = 10^4;
linTable = colorInfo.LinearizationTable;
plot(0:maxLinValue-1,linTable(1:maxLinValue))
title("Linearization Table")
Операции по обработке по конвейеру обработки цифрового фотоаппарата обычно выполняются на линейных данных. Чтобы сгенерировать линейные данные, необходимо инвертировать нелинейное сжатие области значений. 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);
Преобразуйте закодированное Байером изображение CFA в изображение истинного цвета demosaicing. Изображение истинного цвета находится в линейном пространстве камеры.
cfaLayout = cfaInfo.CFALayout;
imDebayered = demosaic(cfaWB,cfaLayout);
imshow(imDebayered)
title("Demosaiced RGB Image in Linear Camera Space")
Метаданные включают две опции для преобразования изображения от линейного пространства камеры до откорректированного гаммой цветового пространства 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")
Преобразуйте изображение от линейного пространства камеры до линейного цветового пространства RGB с помощью матрицы преобразования в CameraTosRGB
поле метаданных.
cam2srgbMat = colorInfo.CameraTosRGB;
imTransform = imapplymatrix(cam2srgbMat,imDebayered,"uint16");
Примените гамма-коррекцию, чтобы принести изображение от линейного sRGB цветового пространства до sRGB цветового пространства.
srgbTransform = lin2rgb(imTransform);
imshow(srgbTransform)
title("sRGB Image using Transformation Matrix")
Можно преобразовать Необработанные данные непосредственно в изображение RGB с помощью raw2rgb
функция. raw2rgb
функция обеспечивает сопоставимые результаты как пользовательский конвейер обработки, адаптированный в соответствии с вашими данными и настройками захвата. Однако raw2rgb
функция не обеспечивает ту же подстроенную точность и гибкость как пользовательский трубопровод.
Преобразуйте данные изображения в НЕОБРАБОТАННОМ файле к sRGB цветовому пространству с помощью raw2rgb
функция.
srgbAuto = raw2rgb(fileName);
imshow(srgbAuto)
title("sRGB Image using raw2rgb Function")
Сравните результат raw2rgb
преобразование в то полученное использование полного конвейера обработки камеры с помощью PCS и матрицы преобразования.
montage({srgbPCS,srgbTransform,srgbAuto},"Size",[1 3]); title(["RAW to sRGB Images: PCS (Left) vs.";"raw2rgb Function (Center) vs. Transformation (Right)"])
raw2planar
| rawinfo
| planar2raw
| raw2rgb
| rawread