Наши глаза очень хороши в оценке, что является белым при различных условиях освещения. Цифровые фотоаппараты, однако, без некоторой корректировки, могут легко получить нереалистичные изображения с сильным цветовым оттенком. Алгоритмы автоматического баланса белого (AWB) пытаются откорректировать для рассеянного света минимальным входом от пользователя, так, чтобы получившееся изображение было похоже на то, что видели бы наши глаза. Но который должен использовать лучший алгоритм AWB? В этом примере мы объясняем процесс позади автоматического баланса белого и показываем, как сравнить и выбрать лучший алгоритм.
Автоматическая балансировка белого сделана на двух шагах:
Шаг 1: Оцените освещение сцены.
Шаг 2: Откорректируйте цветовой баланс изображения.
Самым твердым шагом и тем, который мы будем фокусировать на оптимизации, является Шаг 1 - оценка рассеянного света. Если рассеянный свет известен, затем исправление цветов в изображении (Шаг 2) является легким и фиксированным процессом.
В следующем мы судим качество трех алгоритмов для освещающей оценки путем сравнения их с освещением сцены основной истины:
Белый Retinex [1] закрашенной фигуры
Серый мир [2]
Метод Анализа главных компонентов (PCA) Ченга [3]
Автоматические алгоритмы баланса белого обычно применяются на необработанные данные изображения, прежде чем изображение будет сжато и сохранено в карту памяти. foosballraw.tiff
файл изображения, который содержит такие необработанные данные о датчике после исправления уровня черного и масштабирования интенсивности к 16 битам на пиксель. Это изображение свободно от балансировки белого, сделанной камерой, а также demosaicking, шумоподавлением, компенсацией хроматической аберрации, тональными корректировками, гамма-коррекцией и другой обработкой, сделанной, прежде чем изображение будет сохранено в карту памяти.
A = imread('foosballraw.tiff');
Изображение A
содержит линейные значения RGB. Большинство освещающих алгоритмов оценки принимает линейное соотношение между ответом датчика изображений и интенсивностями пикселей. Однако из-за нелинейной природы дисплеев, файлы изображений, предназначенные, чтобы быть отображенными, такие как файлы JPEG, включают гамма-коррекцию. Без гамма-коррекции изображения выглядели бы очень тусклыми на мониторе. Если вы работаете с изображениями со скорректированной гаммой, убедитесь, что линеаризовали их с rgb2lin
функция. Дело обстоит не так с foosballraw.tiff
, так пропустите этот шаг.
Цифровые фотоаппараты используют массив цветового фильтра, наложенный на датчик изображений, чтобы симулировать цветное видение, так, чтобы каждый пиксель был чувствителен или к красному, зеленому или к синему. Чтобы восстановить информацию об отсутствующем цвете на уровне каждого пикселя, необходимо интерполировать. Шаблон Байера, используемый камерой, с которой была получена фотография (Canon EOS 30D), является RGGB.
A = demosaic(A,'rggb');
При попытке отобразить линейное изображение как есть, это будет казаться очень тусклым из-за нелинейной характеристики дисплеев. Поэтому в целях отображения, правильных гаммой изображение, чтобы использовать sRGB цветовое пространство.
A_sRGB = lin2rgb(A);
Отобразите исходное, минимально обработанное изображение до и после гамма-коррекции
warning('off','images:initSize:adjustingMag') montage({A,A_sRGB}) title('Original, minimally processed image before and after gamma correction')
График ColorChecker был включен в сцену. Этот график сделан из 24 нейтральных и цветовых полей с известными спектральными коэффициентами отражения. Мы будем использовать 6 нейтральных (ахроматических) закрашенных фигур в нижнем ряду, чтобы оценить освещение основной истины в сцене, с которой будут сравнены алгоритмы. Однако при тестировании алгоритмов, график должен быть исключен, чтобы предотвратить алгоритмы, чтобы незаконно использовать в своих интересах его – в реальных ситуациях нет никакого Графика ColorChecker.
Задайте местоположение Графика ColorChecker. По умолчанию пример обеспечивает cooridinates четырехугольника ограничения. Если вы хотите выбрать координаты многоугольника в интерактивном режиме, изменить значение select_polygon
к true
.
select_polygon = false; if select_polygon % Use roipoly to create a mask from a polygon drawn manually. % Click to add vertices, then right-click and select "Create Mask" to return. imshow(A_sRGB) title('Draw a polygon around the chart') mask_chart = roipoly; else % Use the provided coordinates of the bounding rectangle. c = [930 1280 1316 953]; r = [1877 1890 1382 1370]; mask_chart = roipoly(A_sRGB,r,c); end
Расширьте маску немного, чтобы гарантировать, что мы не включаем пикселей, принадлежащих графику.
mask_chart = imdilate(mask_chart,ones(7));
В целях баланса белого мы будем только использовать 6 нейтральных закрашенных фигур в нижнем ряду графика. Эти нейтральные закрашенные фигуры отражают свет одинаково через видимый спектр. Они отражают освещение сцены. Источник света основной истины вычисляется как средний цвет нейтральных закрашенных фигур, исключая под - и переэкспонированные пиксели.
Задайте центр каждой нейтральной закрашенной фигуры. По умолчанию пример обеспечивает оценку центральной координаты каждой закрашенной фигуры. Если вы хотите выбрать центры ROI в интерактивном режиме, изменить значение estimate_roi_centers
к true
.
estimate_roi_centers = false; if estimate_roi_centers % Zoom in and click the center of each of the 6 neutral patches. xlim([1350 1930]) ylim([900 1350]) title('Click the center of each of the 6 neutral patches') [x,y] = ginput(6); else % Use the provided estimate of ROI center coordinates. x = [1424 1514 1598 1676 1757 1835]; y = [1268 1250 1247 1250 1235 1229]; end
Мы выводим область квадрата из координат центра каждой закрашенной фигуры, полагая, что сторона квадрата 80% расстояния, разделяющего центры двух последовательных закрашенных фигур.
x = round(x); y = round(y); r = mean(diff(x)) / 2 * 0.80; r = floor(r);
Создайте бинарную маску, покрывающую нейтральные закрашенные фигуры.
mask = false(size(A,1), size(A,2)); for k = 1:6 mask(y(k)-r:y(k)+r,x(k)-r:x(k)+r) = true; end
Разрушьте маску, чтобы избежать включая пиксели за пределами закрашенных фигур или на границе, которые подвержены хроматической аберрации, цвета которой могут скосить измерение основной истины.
mask_eroded = imerode(mask, strel('disk',5));
Идентифицируйте насыщаемые значения RGB во входном изображении. Эти значения должны быть исключены из расчета основной истины, когда они скосят измерение также.
mask_clipped = (A == intmax(class(A))) | (A == intmin(class(A))); mask_clipped = mask_clipped(:,:,1) | mask_clipped(:,:,2) | mask_clipped(:,:,3);
Исключите эти отсеченные пиксели из маски, соответствующей нейтральным закрашенным фигурам.
mask_patches = mask_eroded & ~mask_clipped;
Визуализируйте выбранные пиксели. Подсвеченные пиксели должны все быть в нейтральных закрашенных фигурах. В противном случае попытайтесь кликнуть по центрам закрашенных фигур снова и повторите шаги выше.
A_patches = imoverlay(A_sRGB,mask_patches);
imshow(A_patches)
title('The selected pixels are highlighted in yellow')
Получите красные, зеленые и красные значения для нейтральных закрашенных фигур.
patches_R = A(:,:,1); patches_G = A(:,:,2); patches_B = A(:,:,3); patches_R = patches_R(mask_patches); patches_G = patches_G(mask_patches); patches_B = patches_B(mask_patches);
Для простоты и потому что большинство освещающих алгоритмов оценки работает в плавающей точке, мы преобразуем значения RGB закрашенных фигур, чтобы удвоить и масштабировать значения, чтобы быть в [0 1] прежде, чем вычислить среднее значение.
patches_R = im2double(patches_R); patches_G = im2double(patches_G); patches_B = im2double(patches_B);
Вычислите источник света RGB основной истины как среднее значение RGB через нейтральные закрашенные фигуры.
illuminant_groundtruth = [mean(patches_R) mean(patches_G) mean(patches_B)];
Чтобы сравнить предполагаемый источник света с основной истиной, вычислите угловую погрешность между двумя цветами. Чтобы лучше изучить концепцию угловой погрешности, рассмотрите следующую визуализацию произвольного источника света и основной истины, которую мы только измерили. Каждый источник света представляет вектор на пробеле RGB.
illuminant = [0.066 0.1262 0.0691]; plot3([0 1],[0 1],[0,1],'LineStyle',':','Color','k') hold on plot3(... [0 illuminant_groundtruth(1)/norm(illuminant_groundtruth)], ... % Red [0 illuminant_groundtruth(2)/norm(illuminant_groundtruth)], ... % Green [0 illuminant_groundtruth(3)/norm(illuminant_groundtruth)], ... % Blue 'Marker','.', 'MarkerSize',10) hold on plot3( ... [0 illuminant(1)/norm(illuminant)], ... % Red [0 illuminant(2)/norm(illuminant)], ... % Green [0 illuminant(3)/norm(illuminant)], ... % Blue 'Marker','.', 'MarkerSize',10) xlabel('R') ylabel('G') zlabel('B') title('Illuminants in RGB space') xlim([0 1]) ylim([0 1]) zlim([0 1]) view(28, 36) legend('achromatic line', 'ground truth illuminant', 'estimated illuminant') grid on axis equal
Точное значение предполагаемого источника света не имеет значения так же как его направление, поскольку направление источника света - то, что используется к балансу белого изображение. Идеально, предполагаемый источник света должен быть выровнен с источником света основной истины. Угловая погрешность между предполагаемым источником света и основной истиной является углом (в градусах) сформированным этими двумя векторами. Чем меньший угловая погрешность, тем лучше оценка. Мы оценим качество оценки согласно угловой погрешности против основной истины.
Белый метод Retinex Закрашенной фигуры [1] для освещающей оценки принимает, что сцена содержит яркую закрашенную фигуру. Эта закрашенная фигура отражает максимальный свет, возможный для каждой цветной полосы, которая является цветом освещения сцены.
illumwhite
функционируйте реализует Белую Закрашенную фигуру метод Retinex, также обеспечивая способность исключить часть самых ярких пикселей от расчета, во избежание принятия переэкспонированных пикселей во внимание.
Во-первых, оцените освещение сцены с помощью всех пикселей в изображении минус График ColorChecker. Это сделано путем определения главной процентили, чтобы исключить, чтобы быть 0. 'Mask'
пара "имя-значение" используется, чтобы задать, какие пиксели использовать в расчете, которые в нашем случае являются пикселями, не принадлежащими Графику ColorChecker.
illuminant_wp1 = illumwhite(A, 0, 'Mask', ~mask_chart);
Вычислите угловую погрешность для источника света, оцененного с Белой Закрашенной фигурой 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.5163
К балансу белого изображение (Шаг 2 AWB) использующий этот предполагаемый источник света, используйте 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')
Во-вторых, начиная с выбора максимального значения RGB чувствительно к сверх - отсоединенные пиксели, Белая Закрашенная фигура, алгоритм Retinex может быть сделан более устойчивым исключением определенного процента самых ярких пикселей от расчета. Это достигается через параметр процентили функции illumwhite. Выберите значение процентили 1. (Значение по умолчанию равняется 1.)
illuminant_wp2 = illumwhite(A, 1, 'Mask', ~mask_chart);
Вычислите угловую погрешность для источника света, оцененного с более устойчивой версией Белой Закрашенной фигуры Retinex.
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.0323
Отобразите откорректированное гаммой белое сбалансированное изображение с новым источником света
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')
Серый Мир [2] является несомненно самым известным освещающим методом оценки. Это принимает, что средний цвет мира является серым, т.е. ахроматическим. Поэтому это вычисляет источник света сцены как среднее значение RGB в изображении.
illumgray
функционируйте реализует Серый Мировой алгоритм с одним сложением: Это обеспечивает способность исключить самые темные и самые яркие пиксели из расчета, который может скосить оценку источника света, делая алгоритм более устойчивым.
Во-первых, оцените освещение сцены с помощью всех пикселей изображения, исключая тех, которые соответствуют Графику ColorChecker. illumgray
функция обеспечивает параметр, чтобы задать процентили нижней части и главных значений (упорядоченный яркостью), чтобы исключить. Здесь, мы задаем процентили как [0 0].
illuminant_gw1 = illumgray(A, 0, 'Mask', ~mask_chart);
Сравните предполагаемый источник света с основной истиной путем вычисления угловой погрешности между этими двумя, так же к тому, что мы сделали для Белой Закрашенной фигуры Retinex.
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.063
Примените цветную адаптацию к балансу белого изображение с предполагаемым источником света.
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]')
Во-вторых, с тех пор под - и переэкспонированные пиксели может негативно влиять на оценку источника света как среднее значение RGB в изображении, давайте исключим нижнюю часть и лучший 1 пиксель %. (Значение по умолчанию для percentiles
[1 1].)
illuminant_gw2 = illumgray(A, 1, 'Mask', ~mask_chart);
Вычислите угловую погрешность для второго источника света, оцененного с Серым Миром.
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.1314
Отобразите откорректированное гаммой белое сбалансированное изображение с новым источником света.
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]')
Освещающий метод оценки Ченга [3] черпает вдохновение в пространственных доменных методах, таких как Серое Ребро [4], который принимает, что градиенты изображения являются ахроматическими. Они показывают, что Серое Ребро может быть улучшено путем искусственного представления сильных градиентов путем перестановки блоков изображений, и приходить к заключению, что самые сильные градиенты следуют за направлением источника света. Их метод состоит в упорядоченном расположении пикселей согласно норме их проекции вдоль направления среднего цвета изображения и сохранения нижней части и верхней части p %. Эти две группы соответствуют сильным градиентам в изображении. Наконец, они выполняют анализ главных компонентов (PCA) сохраненных пикселей и возвращают первый компонент как предполагаемое освещение.
Метод Ченга реализован illumpca
функция. Мы используем метод Ченга, чтобы оценить источник света в сцене с помощью нижней части и лучших 5% пикселей вдоль направления среднего цвета. (Значение по умолчанию 3.5.)
illuminant_ch1 = illumpca(A, 5, 'Mask', ~mask_chart);
Сравните эту оценку основной истиной.
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.7595
Отобразите откорректированное гаммой белое сбалансированное изображение
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')
Давайте теперь использовать значение процента по умолчанию и видеть, как оно выдерживает сравнение.
illuminant_ch2 = illumpca(A, 'Mask', ~mask_chart); 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.0283
Отобразите откорректированное изображение в sRGB.
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')
Чтобы найти, что лучший параметр использует в каждом методе, мы можем развернуться через область значений и вычислить угловую погрешность для каждого из них. Параметры этих трех алгоритмов имеют различные значения, но подобные области значений этих параметров дают возможность программно искать лучший для каждого алгоритма.
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_chart); err(k,1) = colorangle(illuminant_wp, illuminant_groundtruth); % Gray World illuminant_gw = illumgray(A, param_range(k), 'Mask', ~mask_chart); err(k,2) = colorangle(illuminant_gw, illuminant_groundtruth); % Cheng if (param_range(k) ~= 0) illuminant_ch = illumpca(A, param_range(k), 'Mask', ~mask_chart); err(k,3) = colorangle(illuminant_ch, illuminant_groundtruth); else % Cheng's algorithm is undefined for percentage=0. err(k,3) = NaN; end end
Создайте визуализацию угловой погрешности как карта тепла.
err_normalized = mat2gray(log(err)); block_size_x = 120; block_size_y = 50; err_image = ones(size(err,1) * block_size_y, size(err,2) * block_size_x); for i = 0:size(err,1)-1 for j = 0:size(err,2)-1 err_image(block_size_y*i+1:block_size_y*(i+1), block_size_x*j+1:block_size_x*(j+1)) = err_normalized(i+1,j+1); end end
Отобразите карту тепла угловой погрешности. Голубые цвета указывают на низкую (хорошую) угловую погрешность, в то время как красные цвета указывают на высокую угловую погрешность (плохо).
old_pref = iptgetpref('ImshowAxesVisible'); iptsetpref('ImshowAxesVisible','on') imshow(err_image, 'Colormap', cool) iptsetpref('ImshowAxesVisible',old_pref) for i = 0:size(err,1)-1 for j = 0:size(err,2)-1 y = block_size_y*i + 1 + block_size_y/2; x = block_size_x*j + 1 + block_size_x/3; text(x,y,sprintf('%1.2f',err(i+1,j+1))) end end box off title('Angular Error') ylabel('Parameter') yticks(linspace(block_size_y/2, size(err_image,1) - block_size_y/2, numel(param_range))) yticklabels(arrayfun(@(x) {num2str(x)}, param_range)) xticks(block_size_x/2 + [0 block_size_x 2*block_size_x]) xticklabels({'White Patch','Gray World','Cheng'})
Найдите лучший параметр для каждого алгоритма.
[~,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.33 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.06 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.72 degrees
Вычислите и отобразите лучший предполагаемый источник света для каждого алгоритма на пробеле RGB.
best_illum_wp = illumwhite(A, best_param_wp, 'Mask', ~mask_chart); best_illum_gw = illumgray(A, best_param_gw, 'Mask', ~mask_chart); best_illum_ch = illumpca(A, best_param_ch, 'Mask', ~mask_chart); plot3([0 1],[0 1],[0,1],'LineStyle',':','Color','k') hold on plot3(... [0 illuminant_groundtruth(1)/norm(illuminant_groundtruth)], ... % Red [0 illuminant_groundtruth(2)/norm(illuminant_groundtruth)], ... % Green [0 illuminant_groundtruth(3)/norm(illuminant_groundtruth)], ... % Blue 'Marker','.', 'MarkerSize',10) plot3( ... [0 best_illum_wp(1)/norm(best_illum_wp)], ... % Red [0 best_illum_wp(2)/norm(best_illum_wp)], ... % Green [0 best_illum_wp(3)/norm(best_illum_wp)], ... % Blue 'Marker','.', 'MarkerSize',10) plot3( ... [0 best_illum_gw(1)/norm(best_illum_gw)], ... % Red [0 best_illum_gw(2)/norm(best_illum_gw)], ... % Green [0 best_illum_gw(3)/norm(best_illum_gw)], ... % Blue 'Marker','.', 'MarkerSize',10) plot3( ... [0 best_illum_ch(1)/norm(best_illum_ch)], ... % Red [0 best_illum_ch(2)/norm(best_illum_ch)], ... % Green [0 best_illum_ch(3)/norm(best_illum_ch)], ... % Blue 'Marker','.', 'MarkerSize',10) xlabel('R') ylabel('G') zlabel('B') title('Best illuminants in RGB space') xlim([0 1]) ylim([0 1]) zlim([0 1]) 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); M = zeros(size(A,1), 3*size(A,2), size(A,3), 'like', A); M(:,1:size(A,2),:) = B_wp_best_sRGB; M(:,size(A,2)+1:2*size(A,2),:) = B_gw_best_sRGB; M(:,2*size(A,2)+1:end,:) = B_ch_best_sRGB; figure imshow(M) title('Montage of the best white balanced images: White Point, Gray World, Cheng')
Эта быстрая перестрелка между двумя классическими освещающими методами оценки и более свежим показывает, что метод Ченга, с помощью верхних и нижних самых темных и самых ярких пикселей на 0,75%, побеждает для того конкретного изображения. Однако этот результат должен быть взят с мелкой частицей соли.
Во-первых, источник света основной истины был измерен с помощью Графика ColorChecker и чувствителен к шуму датчика и выстрелу. Источник света основной истины сцены может быть лучше оценен с помощью спектрофотометра.
Во-вторых, мы оценили источник света основной истины как средний цвет нейтральных закрашенных фигур. Также распространено использовать медиану вместо среднего значения. Выполнение так могло переключить основную истину существенным количеством. Например, для изображения в этом исследовании, с помощью тех же пикселей, средний цвет и средний цвет нейтральных закрашенных фигур являются 0,5 градусами независимо, которые в некоторых случаях могут быть больше, чем угловая погрешность источников света, оцененных различными методами.
В-третьих, полное сравнение освещающих методов оценки должно использовать множество изображений, взятых при различных условиях. Один метод может работать лучше, чем другие для конкретного изображения, но может выполнить плохо по целому набору данных.
[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
| illumgray
| illumpca
| illumwhite
| imdilate
| imerode
| imoverlay
| lin2rgb
| rgb2lin