Esta página es para la versión anterior. La página correspondiente en inglés se eliminó en la versión actual.

Comparación de algoritmos de balance de blancos automáticos

Nuestros ojos son muy buenos a juzgar lo que es blanco bajo diferentes condiciones de iluminación. Las cámaras digitales, sin embargo, sin algún tipo de ajuste, pueden capturar fácilmente imágenes irreales con un molde de color fuerte. Los algoritmos de balance de blancos automáticos (AWB) intentan corregir la luz ambiental con una entrada mínima del usuario, de modo que la imagen resultante se parezca a lo que verían nuestros ojos. Pero, ¿cuál es el mejor algoritmo de AWB para utilizar? En este ejemplo, explicamos el proceso detrás del balance de blancos automático y mostramos cómo comparar y seleccionar el mejor algoritmo.

El balanceo blanco automático se hace en dos pasos:

  • Paso 1: Estime la iluminación de la escena.

  • Paso 2: Corrija el balance de color de la imagen.

El paso más difícil, y el que se centrará en la optimización, es el paso 1-la estimación de la luz ambiental. Una vez que se conoce la luz ambiental, entonces corregir los colores de la imagen (paso 2) es un proceso fácil y fijo.

En el siguiente, juzgamos la calidad de tres algoritmos para la estimación del iluminador comparando ellos a la iluminación de la escena de la verdad del suelo:

  • Parche blanco Retinex [1]

  • Mundo gris [2]

  • Método de análisis de componentes principales de Cheng (PCA) [3]

Leer la imagen de 16 bits de los valores RGB lineales

Los algoritmos de balance de blancos automáticos se aplican generalmente en los datos de imagen RAW, antes de comprimir la imagen y guardarla en la tarjeta de memoria. foosballraw.tiff es un archivo de imagen que contiene datos de sensores crudos después de corregir el nivel de negro y escalar las intensidades a 16 bits por píxel. Esta imagen está libre del balanceo blanco hecho por la cámara, así como demosaicking, eliminación, Compensación cromática de la aberración, ajustes del tono, corrección gamma y el otro proceso hecho antes de que la imagen se guarde a la tarjeta de memoria.

A = imread('foosballraw.tiff');

La imagen A contiene valores RGB lineales. La mayoría de los algoritmos de estimación de bombillas asumen una relación lineal entre la respuesta del sensor de imagen y las intensidades de píxeles. Sin embargo, debido a la naturaleza no lineal de los dispositivos de visualización, los archivos de imagen destinados a ser mostrados como archivos JPEG incorporan una corrección de gamma. Sin las imágenes de corrección gamma se vería muy tenue en una pantalla de ordenador. Si está trabajando con imágenes corregidas por gamma, asegúrese de alinearlas con la función rgb2lin. Este no es el caso con foosballraw.tiff, así que omitir este paso.

Interpolación para recuperar información de color que falta

Las cámaras digitales utilizan una matriz de filtro de color superpuesta en el sensor de imagen para simular la visión de color, de modo que cada píxel sea sensible a rojo, verde o azul. Para recuperar la información de color que falta en cada píxel, debe interpolar. El patrón de Bayer utilizado por la cámara con la que se capturó la foto (Canon EOS 30D) es RGGB.

A = demosaic(A,'rggb');

Gamma-corrija la imagen para la exhibición

Si intenta mostrar la imagen lineal tal cual, parecerá muy tenue, debido a la característica no lineal de los dispositivos de visualización. Por lo tanto, para los propósitos de la exhibición, gamma-corrija la imagen para utilizar el espacio de color de sRGB.

A_sRGB = lin2rgb(A);

Mostrar la imagen original, mínimamente procesada antes y después de la corrección de gamma

warning('off','images:initSize:adjustingMag') montage({A,A_sRGB}) title('Original, minimally processed image before and after gamma correction')

Localice el gráfico de ColorChecker

Se ha incluido un gráfico de ColorChecker en la escena. Esta tabla está formada por 24 parches neutros y de color con reflectancias espectrales conocidas. Utilizaremos los 6 remiendos neutrales (acromático) en la fila inferior para estimar la iluminación de la verdad del suelo en la escena, contra la cual los algoritmos serán comparados. Sin embargo, al probar los algoritmos, el gráfico debe ser excluido para evitar que los algoritmos se aprovechen injustamente de él – no hay un gráfico ColorChecker en situaciones de la vida real.

Especifique la ubicación del gráfico ColorChecker. De forma predeterminada, el ejemplo proporciona la cooridinates de un cuadrilátero limitador. Si desea seleccionar las coordenadas del polígono interactivamente, cambie el valor de select_polygon a 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

Dilate ligeramente la mascarilla para asegurarse de que no incluimos ningún píxel perteneciente al gráfico.

mask_chart = imdilate(mask_chart,ones(7));

Mida la iluminación de la verdad del suelo usando el gráfico ColorChecker

Para el propósito del balance de blancos, sólo usaremos los 6 parches neutros en la fila inferior de la tabla. Estos parches neutros reflejan la luz equitativamente a través del espectro visible. Reflejan la iluminación de la escena. El iluminador de la verdad de tierra se computa como el color medio de los remiendos neutrales, excepto los pixeles under-y over-Exposed.

Especifique el centro de cada parche neutro. De forma predeterminada, el ejemplo proporciona una estimación de la coordenada central de cada parche. Si desea seleccionar los centros de ROI de forma interactiva, cambie el valor de estimate_roi_centers a 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

Obtenemos un área cuadrada de las coordenadas del centro de cada parche considerando el lado de un cuadrado para ser 80% de la distancia que separa los centros de dos parches consecutivos.

x = round(x); y = round(y); r = mean(diff(x)) / 2 * 0.80; r = floor(r);

Cree una máscara binaria que cubra los parches neutros.

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

Erosionar la máscara para evitar incluir píxeles fuera de los parches o en el borde, que son propensos a la aberración cromática, cuyos colores pueden sesgar la medida de la verdad del suelo.

mask_eroded = imerode(mask, strel('disk',5));

Identifique los valores RGB saturados en la imagen de entrada. Estos valores se deben excluir del cómputo de la verdad del suelo pues sesgarán la medida también.

mask_clipped = (A == intmax(class(A))) | (A == intmin(class(A))); mask_clipped = mask_clipped(:,:,1) | mask_clipped(:,:,2) | mask_clipped(:,:,3);

Excluya estos píxeles recortados de la máscara correspondiente a los parches neutros.

mask_patches = mask_eroded & ~mask_clipped;

Visualice los píxeles seleccionados. Los píxeles resaltados deben estar dentro de los parches neutros. Si no, intente hacer clic de nuevo en los centros de los parches y repita los pasos anteriores.

A_patches = imoverlay(A_sRGB,mask_patches);  imshow(A_patches) title('The selected pixels are highlighted in yellow')

Obtenga los valores rojo, verde y rojo para los parches neutros.

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);

Para simplificar y porque la mayoría de los algoritmos de estimación de bombillas funcionan en punto flotante, convertimos los valores RGB de los parches en duplicar y escalar los valores para estar en [0 1] antes de calcular la media.

patches_R = im2double(patches_R); patches_G = im2double(patches_G); patches_B = im2double(patches_B);

Calcule el elemento de iluminación RGB de la verdad de tierra como el valor RGB medio en los parches neutros.

illuminant_groundtruth = [mean(patches_R) mean(patches_G) mean(patches_B)];

Error angular

Para comparar un iluminador Estimado contra la verdad de tierra, calcule el error angular entre los dos colores. Para entender mejor el concepto de error angular, considere la siguiente visualización de un elemento luminoso arbitrario y la verdad de tierra que acabamos de medir. Cada elemento luminoso representa un vector en el espacio 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

El valor exacto de la bombilla estimada no importa tanto como su dirección, ya que la dirección de la bombilla es lo que se utiliza para equilibrar el blanco de una imagen. Idealmente, el iluminante Estimado debe estar alineado con el iluminador de la verdad de tierra. El error angular entre el iluminante Estimado y la verdad del suelo es el ángulo (en grados) formado por los dos vectores. Cuanto más pequeño es el error angular, mejor es la estimación. Evaluaremos la calidad de una estimación según el error angular contra la verdad de tierra.

Parche blanco Retinex

El método Retinex de parche blanco [1] para la estimación de iluminaciones supone que la escena contiene un parche brillante. Este parche refleja la luz máxima posible para cada banda de color, que es el color de la iluminación de la escena.

La función illumwhite implementa el método Retinex de parche blanco al mismo tiempo que proporciona la capacidad de excluir parte de los píxeles más brillantes del cálculo, con el fin de evitar tomar en cuenta los píxeles sobreexpuestos.

En primer lugar, calcule la iluminación de la escena utilizando todos los píxeles de la imagen, menos el gráfico ColorChecker. Esto se hace especificando el percentil superior a excluir para ser 0. El par nombre-valor 'Mask' se utiliza para especificar los píxeles que se van a utilizar para el cálculo, que en nuestro caso son píxeles que no pertenecen al gráfico ColorChecker.

illuminant_wp1 = illumwhite(A, 0, 'Mask', ~mask_chart);

Calcular el error angular de la bombilla estimada con parche blanco 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 

Para balancear el blanco la imagen (paso 2 de AWB) usando esta bombilla estimada, use la función chromadapt, que por defecto escala los colores en el modelo de respuesta del cono de Bradford. Asegúrese de especificar que estamos trabajando con valores de color RGB lineales.

B_wp1 = chromadapt(A, illuminant_wp1, 'ColorSpace', 'linear-rgb');

Mostrar la imagen balanceada de color blanco corregida por gamma

B_wp1_sRGB = lin2rgb(B_wp1);  figure imshow(B_wp1_sRGB) title('White balanced image using White Patch Retinex with percentile=0')

En segundo lugar, puesto que la selección del valor RGB máximo es sensible a los pixeles sobre-expuestos, el algoritmo Retinex del remiendo blanco se puede hacer más robusto excluyendo un cierto porcentaje de los pixeles más brillantes del cómputo. Esto se consigue a través del parámetro percentil de la función illumwhite. Elija un valor de percentil de 1. (el valor por defecto es 1.)

illuminant_wp2 = illumwhite(A, 1, 'Mask', ~mask_chart);

Calcule el error angular de la bombilla estimada con la versión más robusta de White patch 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 

Mostrar la imagen equilibrada de color blanco corregida por gamma con la nueva bombilla

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')

Mundo gris

El mundo gris [2] es sin duda el método más conocido de estimación de iluminantes. Asume que el color medio del mundo es gris, es decir, acromático. Por lo tanto, calcula el iluminador de escena como el valor RGB promedio de la imagen.

La función illumgray implementa el algoritmo del mundo gris con una adición: Proporciona la capacidad de excluir los píxeles más oscuros y brillantes del cálculo, lo que puede sesgar la estimación del elemento luminoso, haciendo que el algoritmo sea más robusto.

En primer lugar, estime la iluminación de la escena utilizando todos los píxeles de la imagen, excluyendo las correspondientes al gráfico ColorChecker. La función illumgray proporciona un parámetro para especificar los percentiles de los valores inferior y superior (ordenados por Brightness) para excluir. Aquí, especificamos los percentiles como [0 0].

illuminant_gw1 = illumgray(A, 0, 'Mask', ~mask_chart);

Compare el iluminante Estimado a la verdad del suelo componiendo el error angular entre los dos, semejantemente a lo que hicimos para el remiendo blanco 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 

Aplicar la adaptación cromática al balance de blancos de la imagen con la bombilla estimada.

B_gw1 = chromadapt(A, illuminant_gw1, 'ColorSpace', 'linear-rgb');

Mostrar la imagen balanceada de color blanco corregida por gamma

B_gw1_sRGB = lin2rgb(B_gw1);  imshow(B_gw1_sRGB) title('White balanced image using Gray World with percentiles=[0 0]')

En segundo lugar, puesto que los píxeles inferiores y sobreexpuestos pueden influir negativamente en la estimación del elemento luminoso como valor medio RGB en la imagen, excluyamos los píxeles inferior y superior al 1%. (el valor predeterminado para percentiles es [1 1].)

illuminant_gw2 = illumgray(A, 1, 'Mask', ~mask_chart);

Calcular el error angular de la segunda bombilla estimada con Gray World.

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 

Visualice la imagen balanceada de color blanco con la nueva bombilla.

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]')

Método de análisis de componentes principales de Cheng (PCA)

El método de estimación de bombillas de Cheng [3] se inspira en los métodos de dominio espacial, como el borde gris [4], que asume que los gradientes de una imagen son acromático. Muestran que el borde gris puede mejorarse introduciendo artificialmente los gradientes fuertes al barajar bloques de imágenes y concluir que los gradientes más fuertes siguen la dirección de la bombilla. Su método consiste en ordenar píxeles según la norma de su proyección a lo largo de la dirección del color de la imagen media, y retener la parte inferior y superior p%. Estos dos grupos corresponden a fuertes gradientes en la imagen. Finalmente, realizan un análisis de componentes principales (PCA) en los píxeles retenidos y devuelven el primer componente como la iluminación estimada.

El método de Cheng es implementado por la función illumpca. Utilizamos el método de Cheng para estimar el elemento luminoso en la escena usando la parte inferior y la parte superior del 5% de los píxeles a lo largo de la dirección del color medio. (el valor por defecto es 3,5.)

illuminant_ch1 = illumpca(A, 5, 'Mask', ~mask_chart);

Compare esta estimación con la verdad de tierra.

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 

Mostrar la imagen balanceada de color blanco corregida por gamma

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')

Ahora vamos a utilizar el valor de porcentaje predeterminado y ver cómo se compara.

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 

Visualice la imagen corregida en 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')

Barrido de parámetros

Para encontrar el mejor parámetro a utilizar para cada método podemos barrer a través de un rango y calcular el error angular para cada uno de ellos. Los parámetros de los tres algoritmos tienen diferentes significados, pero las gamas similares de estos parámetros hacen que sea fácil buscar mediante programación la mejor para cada algoritmo.

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

Crear una visualización del error angular como mapa de calor.

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

Mostrar el mapa de calor del error angular. Los colores azules claros indican un error angular bajo (bueno), mientras que los colores rojos indican un alto error angular (malo).

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'})

Encuentra el mejor parámetro para cada algoritmo.

[~,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 

Calcule y muestre el iluminador mejor estimado para cada algoritmo en espacio 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

Muestre las imágenes balanceadas blancas para cada método usando el mejor iluminador lado a lado.

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')

Conclusión

Este rápido tiroteo entre dos métodos clásicos de estimación de iluminantes y uno más reciente muestra que el método de Cheng, utilizando los píxeles superior e inferior 0,75% más oscuros y brillantes, gana para esa imagen en particular. Sin embargo, este resultado debe tomarse con un grano de sal.

Primero, el iluminador de la verdad del suelo fue medido usando una carta ColorChecker y es sensible al ruido del tiro y del sensor. El iluminador de la verdad de la tierra de una escena se puede estimar mejor usando un espectrofotómetro.

En segundo lugar, estimamos el iluminador de la verdad del suelo como el color medio de los remiendos neutrales. También es común utilizar la mediana en lugar de la media. Hacerlo podría cambiar la verdad de tierra por una cantidad significativa. Por ejemplo, para la imagen de este estudio, utilizando los mismos píxeles, el color mediano y el color medio de los parches neutros son 0,5 grados aparte, que en algunos casos pueden ser más que el error angular de las bombillas estimadas por diferentes métodos.

En tercer lugar, una comparación completa de los métodos de estimación de los iluminadores debe utilizar una variedad de imágenes tomadas bajo diferentes condiciones. Un método podría funcionar mejor que los demás para una imagen en particular, pero podría desempeñarse de forma deficiente en todo el conjunto de datos.

Referencias

[1] Ebner, Marc. Parche blanco Retinex, constancia de color. Juan Wiley y hijos, 2007. ISBN 978-0-470-05829-9.

[2] Ebner, Marc. La asunción del mundo gris, la constancia del color. Juan Wiley y hijos, 2007. ISBN 978-0-470-05829-9.

[3] Cheng, Dongliang, Dilip K. Prasad, y Michael S. Brown. "estimación de la iluminación de la constancia de color: por qué los métodos de dominio espacial funcionan y el papel de la distribución del color." Josa A 31,5 (2014): 1049-1058.

[4] van de weijer, Joost, Theo Gevers, y Arjan Gijsenij. "constancia de color basada en el borde." Transacciones IEEE en el procesamiento de imágenes 16,9 (2007): 2207-2214.