В этом примере показано, как оценить освещение и выполнить баланс белого сцены с помощью трех различных алгоритмов освещения. Пример сравнивает предполагаемый источник света с источником света основной истины, вычисленным с помощью графика X-Rite® ColorChecker®.
Глаза очень хороши в оценке, что является белым при различных условиях освещения. Цифровые фотоаппараты, однако, без некоторой корректировки, могут легко получить нереалистичные изображения с сильным цветовым оттенком. Алгоритмы автоматического баланса белого (AWB) пытаются откорректировать для рассеянного света минимальным входом от пользователя, так, чтобы получившееся изображение было похоже на то, что видели бы наши глаза.
Автоматическая балансировка белого сделана на двух шагах:
Шаг 1: Оцените источник света сцены.
Шаг 2: Откорректируйте цветовой баланс изображения.
Несколько различных алгоритмов существуют, чтобы оценить источник света сцены. Эффективность каждого алгоритма зависит от сцены, подсветки и условий обработки изображений. Этот пример судит качество трех алгоритмов для освещающей оценки для одного определенного изображения путем сравнения их с источником света сцены основной истины:
Белый Retinex [1] закрашенной фигуры
Серый мир [2]
Метод Анализа главных компонентов (PCA) Ченга [3]
После того, как рассеянный свет известен, затем исправление цветов в изображении (Шаг 2) является легким и фиксированным процессом.
Алгоритмы AWB обычно применяются на необработанные данные изображения после минимального объема предварительной обработки, прежде чем изображение будет сжато и сохранено в карту памяти.
Считайте 16-битное необработанное изображение в рабочую область. foosballraw.tiff
файл изображения, который содержит необработанные данные о датчике после исправления уровня черного и масштабирования интенсивности к 16 битам на пиксель. Это изображение свободно от балансировки белого, сделанной камерой, а также другими операциями предварительной обработки, такими как demosaicing, шумоподавление, компенсация хроматической аберрации, тональные корректировки и гамма-коррекция.
A = imread('foosballraw.tiff');
Цифровые фотоаппараты используют массив цветового фильтра, наложенный на датчик изображений, чтобы симулировать цветное видение, так, чтобы каждый пиксель был чувствителен или к красному, зеленому или к синему. Чтобы восстановить информацию об отсутствующем цвете на уровне каждого пикселя, интерполируйте использование demosaic
функция. Шаблон Байера, используемый камерой, с которой была получена фотография (Canon EOS 30D), является RGGB.
A = demosaic(A,'rggb');
Изображение A
содержит линейные значения RGB. Линейные значения RGB подходят для оценки источника света сцены и исправления цветового баланса изображения. Однако, при попытке отобразить линейное изображение RGB, это будет казаться очень тусклым из-за нелинейной характеристики дисплеев. Поэтому в целях отображения, правильных гаммой изображение к sRGB цветовому пространству с помощью lin2rgb
функция.
A_sRGB = lin2rgb(A);
Отобразите изображение demosiaced до и после гамма-коррекции.
montage({A,A_sRGB})
title('Original Image Before and After Gamma Correction')
Вычислите источник света основной истины использование X-обряда график ColorChecker, который включен в сцену. Этот график состоит из 24 нейтральных и цветовых полей с известными спектральными коэффициентами отражения.
Обнаружьте график в изображении со скорректированной гаммой при помощи colorChecker
функция. Линейное изображение RGB является слишком темным для colorChecker
обнаружить график автоматически.
chart_sRGB = colorChecker(A_sRGB);
Подтвердите, что график обнаруживается правильно.
displayChart(chart_sRGB)
Получите координаты регистрационных точек в четырех углах графика.
registrationPoints = chart_sRGB.RegistrationPoints;
Создайте новый colorChecker
объект из линейных данных о RGB. Задайте местоположение графика с помощью координат регистрационных точек.
chart = colorChecker(A,"RegistrationPoints",registrationPoints);
Измерьте значения RGB всех цветовых полей с помощью measureColor
функция.
colors = measureColor(chart)
colors=24×9 table
ROI Color Measured_R Measured_G Measured_B Reference_L Reference_a Reference_b Delta_E
___ ________________ __________ __________ __________ ___________ ___________ ___________ _______
1 {'DarkSkin' } 1773 2284 1106 37.54 14.37 14.92 40.763
2 {'LightSkin' } 5691 7627 4245 64.66 19.27 17.5 61.046
3 {'BlueSky' } 1919 5214 4677 49.32 -3.82 -22.54 49.222
4 {'Foliage' } 1576 3376 1216 43.46 -12.74 22.72 46.172
5 {'BlueFlower' } 2997 6253 5997 54.94 9.61 -24.79 55.312
6 {'BluishGreen' } 3676 12020 7388 70.48 -32.26 -0.37 56.895
7 {'Orange' } 6250 5276 1213 62.73 35.83 56.5 82.432
8 {'PurplishBlue'} 1226 3779 5302 39.43 10.75 -45.17 55.714
9 {'ModerateRed' } 4581 3277 2074 50.57 48.64 16.67 67.971
10 {'Purple' } 1233 1767 1889 30.1 22.54 -20.87 41.882
11 {'YellowGreen' } 4939 10555 2657 71.77 -24.13 58.19 72.055
12 {'OrangeYellow'} 7410 8522 1608 71.51 18.24 67.37 83.134
13 {'Blue' } 567 2300 3888 28.37 15.42 -49.8 55.878
14 {'Green' } 2087 6486 2278 54.38 -39.72 32.27 61.962
15 {'Red' } 3702 1986 968 42.43 51.05 28.62 68.861
16 {'Yellow' } 8906 12782 2422 81.8 2.67 80.41 87.375
⋮
Измерять освещающую основную истину, только использовать 6 нейтральных закрашенных фигур в нижнем ряду графика. Извлеките значения RGB шести нейтральных (ахроматических) закрашенных фигур в нижнем ряду.
grayPatchRGB = colors{19:end,{'Measured_R','Measured_G','Measured_B'}}; grayPatchRGB = im2double(grayPatchRGB);
Источник света основной истины является средним цветом нейтральных закрашенных фигур.
illuminant_groundtruth = mean(grayPatchRGB)
illuminant_groundtruth = 1×3
0.0693 0.1423 0.0943
При тестировании алгоритмов AWB предотвратите алгоритмы от несправедливого использования в своих интересах графика путем каширования графика.
Создайте ROI многоугольника по графику при помощи drawpolygon
функция. Задайте вершины многоугольника, когда регистрация указывает.
chartROI = drawpolygon("Position",registrationPoints);
Преобразуйте ROI многоугольника в бинарную маску при помощи createMask
функция.
mask_chart = createMask(chartROI);
Инвертируйте маску. Пиксели в рамках графика исключены из маски, и пиксели остальной части сцены включены в маску.
mask_scene = ~mask_chart;
Чтобы подтвердить точность маски, отобразите маску по изображению. Пиксели, включенные в маску, имеют синий оттенок.
imshow(labeloverlay(A_sRGB,mask_scene));
Можно рассмотреть источник света как вектор в 3-D цветовом пространстве RGB. Величина предполагаемого источника света не имеет значения так же как его направление, потому что направление источника света - то, что используется к балансу белого изображение.
Чтобы оценить качество предполагаемого источника света, вычислите угловую погрешность между предполагаемым источником света и основной истиной. Угловая погрешность является углом (в градусах) сформированным этими двумя векторами. Чем меньший угловая погрешность, тем лучше оценка.
Чтобы лучше изучить концепцию угловой погрешности, рассмотрите следующую визуализацию произвольного источника света, и основная истина измерила использование графика ColorChecker. plotColorAngle
графики функций помощника единичный вектор источника света в 3-D цветовом пространстве RGB, и заданы в конце примера.
sample_illuminant = [0.066 0.1262 0.0691]; p = plot3([0 1],[0 1],[0,1],'LineStyle',':','Color','k'); ax = p.Parent; hold on plotColorAngle(illuminant_groundtruth,ax) plotColorAngle(sample_illuminant,ax) title('Illuminants in RGB space') view(28,36) legend('Achromatic Line','Ground Truth Illuminant','Sample Illuminant') grid on axis equal
Белый алгоритм Retinex Закрашенной фигуры для освещающей оценки принимает, что сцена содержит яркую ахроматическую закрашенную фигуру. Эта закрашенная фигура отражает максимальный свет, возможный для каждой цветной полосы, которая является цветом источника света сцены. Используйте illumwhite
функционируйте, чтобы оценить освещение с помощью Белой Закрашенной фигуры алгоритм Retinex.
Оцените источник света с помощью всех пикселей в сцене. Исключите график ColorChecker из сцены при помощи 'Mask'
аргумент пары "имя-значение".
percentileToExclude = 0;
illuminant_wp1 = illumwhite(A,percentileToExclude,'Mask',mask_scene);
Вычислите угловую погрешность для источника света, оцененного с Белой Закрашенной фигурой Retinex.
err_wp1 = colorangle(illuminant_wp1, illuminant_groundtruth);
disp(['Angular error for White Patch with percentile=0: ' num2str(err_wp1)])
Angular error for White Patch with percentile=0: 16.5377
Баланс белого изображение с помощью chromadapt
функция. Задайте предполагаемый источник света и укажите, что значения цвета находятся в линейном цветовом пространстве RGB.
B_wp1 = chromadapt(A,illuminant_wp1,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение.
B_wp1_sRGB = lin2rgb(B_wp1);
figure
imshow(B_wp1_sRGB)
title('White-Balanced Image using White Patch Retinex with percentile=0')
Белый алгоритм Retinex Закрашенной фигуры не выполняет хорошо, когда пиксели переэкспонированы. Чтобы улучшать производительность алгоритма, исключите лучший 1% самых ярких пикселей.
percentileToExclude = 1;
illuminant_wp2 = illumwhite(A,percentileToExclude,'Mask',mask_scene);
Вычислите угловую погрешность для предполагаемого источника света. Ошибка меньше, оценивая источник света с помощью всех пикселей.
err_wp2 = colorangle(illuminant_wp2,illuminant_groundtruth);
disp(['Angular error for White Patch with percentile=1: ' num2str(err_wp2)])
Angular error for White Patch with percentile=1: 5.032
Баланс белого изображение в линейном цветовом пространстве RGB с помощью предполагаемого источника света.
B_wp2 = chromadapt(A,illuminant_wp2,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение с новым источником света.
B_wp2_sRGB = lin2rgb(B_wp2);
imshow(B_wp2_sRGB)
title('White-Balanced Image using White Patch Retinex with percentile=1')
Серый Мировой алгоритм для освещающей оценки принимает, что средний цвет мира является серым, или ахроматическим. Поэтому это вычисляет источник света сцены как среднее значение RGB в изображении. Используйте illumgray
функционируйте, чтобы оценить освещение с помощью Серого Мирового алгоритма.
Во-первых, оцените источник света сцены, использующий все пиксели изображения, исключая тех, которые соответствуют графику ColorChecker. illumgray
функция обеспечивает параметр, чтобы задать процентили нижней части и главных значений (упорядоченный яркостью), чтобы исключить. Здесь, задайте процентили как 0.
percentileToExclude = 0;
illuminant_gw1 = illumgray(A,percentileToExclude,'Mask',mask_scene);
Вычислите угловую погрешность между предполагаемым источником света и источником света основной истины.
err_gw1 = colorangle(illuminant_gw1,illuminant_groundtruth);
disp(['Angular error for Gray World with percentiles=[0 0]: ' num2str(err_gw1)])
Angular error for Gray World with percentiles=[0 0]: 5.0414
Баланс белого изображение в линейном цветовом пространстве RGB с помощью предполагаемого источника света.
B_gw1 = chromadapt(A,illuminant_gw1,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение.
B_gw1_sRGB = lin2rgb(B_gw1);
imshow(B_gw1_sRGB)
title('White-Balanced Image using Gray World with percentiles=[0 0]')
Серый Мировой алгоритм не выполняет хорошо, когда пиксели недоэкспонируются или переэкспонированы. Чтобы улучшать производительность алгоритма, исключите лучший 1% самых темных и самых ярких пикселей.
percentileToExclude = 1;
illuminant_gw2 = illumgray(A,percentileToExclude,'Mask',mask_scene);
Вычислите угловую погрешность для предполагаемого источника света. Ошибка меньше, оценивая источник света с помощью всех пикселей.
err_gw2 = colorangle(illuminant_gw2, illuminant_groundtruth);
disp(['Angular error for Gray World with percentiles=[1 1]: ' num2str(err_gw2)])
Angular error for Gray World with percentiles=[1 1]: 5.1092
Баланс белого изображение в линейном цветовом пространстве RGB с помощью предполагаемого источника света.
B_gw2 = chromadapt(A,illuminant_gw2,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение с новым источником света.
B_gw2_sRGB = lin2rgb(B_gw2);
imshow(B_gw2_sRGB)
title('White-Balanced Image using Gray World with percentiles=[1 1]')
Освещающий метод оценки Ченга черпает вдохновение в пространственных доменных методах, таких как Серое Ребро [4], который принимает, что градиенты изображения являются ахроматическими. Они показывают, что Серое Ребро может быть улучшено путем искусственного представления сильных градиентов путем перестановки блоков изображений, и приходить к заключению, что самые сильные градиенты следуют за направлением источника света. Их метод состоит в упорядоченном расположении пикселей согласно норме их проекции вдоль направления среднего цвета изображения и сохранения нижней части и главной процентили. Эти две группы соответствуют сильным градиентам в изображении. Наконец, они выполняют анализ главных компонентов (PCA) сохраненных пикселей и возвращают первый компонент как предполагаемый источник света. Используйте illumpca
функционируйте, чтобы оценить освещение с помощью алгоритма Ченга PCA.
Во-первых, оцените источник света с помощью значения процента по умолчанию метода Ченга PCA, исключая тех, которые соответствуют графику ColorChecker.
illuminant_ch2 = illumpca(A,'Mask',mask_scene);
Вычислите угловую погрешность между предполагаемым источником света и источником света основной истины.
err_ch2 = colorangle(illuminant_ch2,illuminant_groundtruth);
disp(['Angular error for Cheng with percentage=3.5: ' num2str(err_ch2)])
Angular error for Cheng with percentage=3.5: 5.0159
Баланс белого изображение в линейном цветовом пространстве RGB с помощью предполагаемого источника света.
B_ch2 = chromadapt(A,illuminant_ch2,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение.
B_ch2_sRGB = lin2rgb(B_ch2);
imshow(B_ch2_sRGB)
title('White-Balanced Image using Cheng with percentile=3.5')
Теперь оцените источник света сцены использование нижней части и лучших 5% пикселей вдоль направления среднего цвета. Второй аргумент illumpca
функция задает процентили нижней части и главных значений (упорядоченный яркостью), чтобы исключить.
illuminant_ch1 = illumpca(A,5,'Mask',mask_scene);
Вычислите угловую погрешность между предполагаемым источником света и источником света основной истины. Ошибка меньше, оценивая источник света с помощью процента по умолчанию.
err_ch1 = colorangle(illuminant_ch1, illuminant_groundtruth);
disp(['Angular error for Cheng with percentage=5: ' num2str(err_ch1)])
Angular error for Cheng with percentage=5: 4.7452
Баланс белого изображение в линейном цветовом пространстве RGB с помощью предполагаемого источника света.
B_ch1 = chromadapt(A,illuminant_ch1,'ColorSpace','linear-rgb');
Отобразите откорректированное гаммой белым сбалансированное изображение.
B_ch1_sRGB = lin2rgb(B_ch1);
imshow(B_ch1_sRGB)
title('White-Balanced Image using Cheng with percentage=5')
Чтобы найти, что лучший параметр использует для каждого алгоритма, можно развернуться через область значений и вычислить угловую погрешность для каждого из них. Параметры этих трех алгоритмов имеют различные значения, но подобные области значений этих параметров дают возможность программно искать лучший для каждого алгоритма.
param_range = 0:0.25:5; err = zeros(numel(param_range),3); for k = 1:numel(param_range) % White Patch illuminant_wp = illumwhite(A,param_range(k),'Mask',mask_scene); err(k,1) = colorangle(illuminant_wp,illuminant_groundtruth); % Gray World illuminant_gw = illumgray(A,param_range(k),'Mask',mask_scene); err(k,2) = colorangle(illuminant_gw,illuminant_groundtruth); % Cheng if (param_range(k) ~= 0) illuminant_ch = illumpca(A,param_range(k),'Mask',mask_scene); err(k,3) = colorangle(illuminant_ch,illuminant_groundtruth); else % Cheng's algorithm is undefined for percentage=0. err(k,3) = NaN; end end
Отобразите тепловую карту угловой погрешности с помощью heatmap
функция. Темно-синие цвета указывают на низкую угловую погрешность, в то время как желтые цвета указывают на высокую угловую погрешность. Оптимальный параметр имеет самую маленькую угловую погрешность.
heatmap(err,'Title','Angular Error','Colormap',parula(length(param_range)), ... 'XData',["White Patch" "Gray World" "Cheng's PCA"], ... 'YLabel','Parameter Value','YData',string(param_range));
Найдите лучший параметр для каждого алгоритма.
[~,idx_best] = min(err); best_param_wp = param_range(idx_best(1)); best_param_gw = param_range(idx_best(2)); best_param_ch = param_range(idx_best(3)); fprintf('The best parameter for White Patch is %1.2f with angular error %1.2f degrees\n', ... best_param_wp,err(idx_best(1),1));
The best parameter for White Patch is 0.25 with angular error 3.35 degrees
fprintf('The best parameter for Gray World is %1.2f with angular error %1.2f degrees\n', ... best_param_gw,err(idx_best(2),2));
The best parameter for Gray World is 0.00 with angular error 5.04 degrees
fprintf('The best parameter for Cheng is %1.2f with angular error %1.2f degrees\n', ... best_param_ch,err(idx_best(3),3));
The best parameter for Cheng is 0.50 with angular error 1.74 degrees
Вычислите предполагаемый источник света для каждого алгоритма с помощью лучшего параметра.
best_illum_wp = illumwhite(A,best_param_wp,'Mask',mask_scene); best_illum_gw = illumgray(A,best_param_gw,'Mask',mask_scene); best_illum_ch = illumpca(A,best_param_ch,'Mask',mask_scene);
Отобразите угловую погрешность каждого лучшего источника света в цветовом пространстве RGB.
p = plot3([0 1],[0 1],[0,1],'LineStyle',':','Color','k'); ax = p.Parent; hold on plotColorAngle(illuminant_groundtruth,ax) plotColorAngle(best_illum_wp,ax) plotColorAngle(best_illum_gw,ax) plotColorAngle(best_illum_ch,ax) title('Best Illuminants in RGB space') view(28,36) legend('Achromatic Line','Ground Truth','White Patch','Gray World','Cheng') grid on axis equal
Вычислите оптимальные белым сбалансированные изображения для каждого алгоритма с помощью лучшего источника света.
B_wp_best = chromadapt(A,best_illum_wp,'ColorSpace','linear-rgb'); B_wp_best_sRGB = lin2rgb(B_wp_best); B_gw_best = chromadapt(A,best_illum_gw,'ColorSpace','linear-rgb'); B_gw_best_sRGB = lin2rgb(B_gw_best); B_ch_best = chromadapt(A,best_illum_ch,'ColorSpace','linear-rgb'); B_ch_best_sRGB = lin2rgb(B_ch_best);
Отобразите оптимальные белым сбалансированные изображения для каждого алгоритма в монтаже.
figure montage({B_wp_best_sRGB,B_gw_best_sRGB,B_ch_best_sRGB},'Size',[1 3]) title('Montage of Best White-Balanced Images: White Point, Gray World, Cheng')
Эта быстрая перестрелка между двумя классическими освещающими алгоритмами оценки и более свежим показывает, что метод Ченга, с помощью верхних и нижних самых темных и самых ярких пикселей на 0,75%, побеждает для того конкретного изображения. Однако этот результат должен быть взят с мелкой частицей соли.
Во-первых, источник света основной истины был измерен с помощью графика ColorChecker и чувствителен к шуму датчика и выстрелу. Источник света основной истины сцены может быть лучше оценен с помощью спектрофотометра.
Во-вторых, источник света основной истины оценивается как средний цвет нейтральных закрашенных фигур. Распространено использовать медиану вместо среднего значения, которое могло переключить основную истину существенным количеством. Например, для изображения в этом исследовании, с помощью тех же пикселей, средний цвет и средний цвет нейтральных закрашенных фигур являются 0,5 градусами независимо, которые в некоторых случаях могут быть больше, чем угловая погрешность источников света, оцененных различными алгоритмами.
В-третьих, полное сравнение освещающих алгоритмов оценки должно использовать множество изображений, взятых при различных условиях. Один алгоритм может работать лучше, чем другие для конкретного изображения, но может выполнить плохо по целому набору данных.
plotColorAngle
графики функций единичный вектор источника света в 3-D цветовом пространстве RGB. Входной параметр illum
задает источник света как цвет RGB и входной параметр ax
задает оси, на которых можно построить единичный вектор.
function plotColorAngle(illum,ax) R = illum(1); G = illum(2); B = illum(3); magRGB = norm(illum); plot3([0 R/magRGB],[0 G/magRGB],[0 B/magRGB], ... 'Marker','.','MarkerSize',10,'Parent',ax) xlabel('R') ylabel('G') zlabel('B') xlim([0 1]) ylim([0 1]) zlim([0 1]) end
[1] Ebner, Марк. Белая закрашенная фигура Retinex, цветное постоянство. John Wiley & Sons, 2007. ISBN 978-0-470-05829-9.
[2] Ebner, Марк. Серое мировое предположение, цветное постоянство. John Wiley & Sons, 2007. ISBN 978-0-470-05829-9.
[3] Ченг, Дунлян, Дилип К. Прасад и Майкл С. Браун. "Освещающая оценка для цветного постоянства: почему пространственно-доменные методы работают и роль цветного распределения". JOSA 31.5 (2014): 1049-1058.
[4] Ван де Вейджер, Joost, Тео Джеверс и Арджэн Джиджсений. "Основанное на ребре цветное постоянство". Транзакции IEEE на обработке изображений 16.9 (2007): 2207-2214.
chromadapt
| colorangle
| colorChecker
| illumgray
| illumpca
| illumwhite
| lin2rgb
| measureColor
| rgb2lin