Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Aproximación del operador de procesamiento de imágenes mediante el aprendizaje profundo

En este ejemplo se muestra cómo entrenar una red de agregación de contexto multiescala (CAN) que se utiliza para aproximar una operación de filtrado de imágenes.

En el ejemplo se muestra cómo entrenar una red CAN multiescala para aproximar un filtro bilateral y también proporciona una red preentrenada. Si opta por entrenar la red, se recomienda encarecidamente el uso de una GPU NVIDIA™ compatible con CUDA con capacidad de cómputo 3,0 o superior. El uso de una GPU requiere la caja de herramientas de computación paralela™.

Si no desea descargar el conjunto de datos de entrenamiento o entrenar la red, puede cargar el CAN preentrenado escribiendo en la línea de comandos.load('trainedOperatorLearning-Epoch-181.mat'); A continuación, vaya directamente a la sección de este ejemplo.Perform Bilateral Filtering Approximation Using Multiscale CAN

Introducción

La aproximación de operadores encuentra formas alternativas de procesar imágenes, de modo que el resultado se asemeja a la salida de una canalización o operación de procesamiento de imagen convencional. El objetivo de la aproximación del operador suele ser reducir el tiempo necesario para procesar una imagen.

Se han propuesto varias técnicas clásicas y de aprendizaje profundo para realizar la aproximación del operador. Algunas técnicas clásicas mejoran la eficiencia de un algoritmo único, pero no se pueden generalizar a otras operaciones. Otra técnica común se aproxima a una amplia gama de operaciones aplicando el operador a una copia de baja resolución de una imagen, pero la pérdida de contenido de alta frecuencia limita la precisión de la aproximación.

Las soluciones de aprendizaje profundo permiten la aproximación de operaciones más generales y complejas. Por ejemplo, la red de agregación de contexto multiescala (CAN) presentada por Q. Chen [1] puede aproximar la asignación de tonos multiescala, la transferencia de estilo fotográfico, la deshazing no local y el dibujo a lápiz. Multiescala CAN entrena en imágenes de resolución completa para una mayor precisión en el procesamiento de detalles de alta frecuencia. Después de entrenar la red, la red puede omitir la operación de procesamiento convencional y procesar las imágenes directamente.

En este ejemplo se explora cómo entrenar un CAN multiescala para aproximar una operación de filtrado bilateral de imágenes, lo que reduce el ruido de la imagen preservando la nitidez del borde. El ejemplo presenta el flujo de trabajo completo de aprendizaje e inferencia, que incluye el proceso de creación de un almacén de datos de entrenamiento, la selección de opciones de formación, la formación de la red y el uso de la red para procesar imágenes de prueba.

La red de aproximación de operadores

El CAN multiescala está entrenado para minimizar el

<math display="inline">
<mrow>
<msub>
<mrow>
<mi mathvariant="italic">l</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</math>
pérdida entre la salida convencional de una operación de procesamiento de imágenes y la respuesta de red después de procesar la imagen de entrada mediante la agregación de contexto multiescala. La agregación de contexto multiescala busca información sobre cada píxel de toda la imagen, en lugar de limitar la búsqueda a una pequeña vecindad que rodea el píxel.

Para ayudar a la red a aprender las propiedades globales de la imagen, la arquitectura CAN de múltiples escalas tiene un campo receptivo grande. La primera y la última capa tienen el mismo tamaño porque el operador no debe cambiar el tamaño de la imagen. Las capas intermedias sucesivas se dilatan exponencialmente aumentando los factores de escala (de ahí la naturaleza "multiescala" del CAN). La dilatación permite que la red busque entidades separadas espacialmente en varias frecuencias espaciales, sin reducir la resolución de la imagen. Después de cada capa de convolución, la red utiliza la normalización adaptable para equilibrar el impacto de la normalización de lotes y la asignación de identidad en el operador aproximado.

Descargar datos de entrenamiento y prueba

Descargue el benchmark IAPR TC-12, que consta de 20.000 imágenes fijas naturales [2]. El conjunto de datos incluye fotos de personas, animales, ciudades y más. Puede utilizar la función auxiliar, para descargar los datos.downloadIAPRTC12Data El tamaño del archivo de datos es ~ 1,8 GB.

imagesDir = tempdir; url_1 = 'http://www-i6.informatik.rwth-aachen.de/imageclef/resources/iaprtc12.tgz'; downloadIAPRTC12Data(url_1,imagesDir);

En este ejemplo se entrenará la red con un pequeño subconjunto de los datos de Benchmark IAPRTC-12.

trainImagesDir = fullfile(imagesDir,'iaprtc12','images','39'); exts = {'.jpg','.bmp','.png'}; inputImages = imageDatastore(trainImagesDir,'FileExtensions',exts);

Enumere el número de imágenes de entrenamiento.

numel(inputImages.Files)
ans = 916 

Definir almacén de datos de extracción de parches aleatorios para formación

Utilice un almacén de datos de extracción de parches al azar para alimentar a la red. Este almacén de datos extrae los parches correspondientes aleatorios de dos almacenes de datos de imagen que contienen las entradas de red y las respuestas de red deseadas.

En este ejemplo, las entradas de red son las imágenes de entrenamiento sin procesar. Las respuestas de red deseadas son las imágenes procesadas después del filtrado bilateral. Cree un almacén de datos de imagen que contenga las imágenes de entrenamiento sin procesar y especifique una función de lectura personalizada que aplique el filtrado bilateral cuando las imágenes se lean desde el almacén de datos. La función de lectura personalizada, se adjunta como un archivo auxiliar a este ejemplo.readAndBilateralFilterImage

bilatFilteredImages = imageDatastore(trainImagesDir,'FileExtensions',exts); bilatFilteredImages.ReadFcn = @readAndBilateralFilterImage;

Cree los de los dos almacenes de datos de imagen.randomPatchExtractionDatastore Especifique un tamaño de parche de 256-by-256 píxeles. Especifique ' ' para extraer un parche posicionado aleatoriamente de cada par de imágenes durante el entrenamiento.PatchesPerImage Especifique un tamaño de mini lote de uno.

miniBatchSize = 1; patchSize = [256 256]; patchds = randomPatchExtractionDatastore(inputImages,bilatFilteredImages,patchSize, ....     'PatchesPerImage',1); patchds.MiniBatchSize = miniBatchSize;

El proporciona mini-lotes de datos a la red en cada iteración de la época.randomPatchExtractionDatastore Realice una operación de lectura en el almacén de datos para explorarlos.

inputBatch = read(patchds); summary(inputBatch)
Variables:      InputImage: 1×1 cell      ResponseImage: 1×1 cell 

Configurar capas CAN de escala múltiple

En este ejemplo se define el CAN multiescala utilizando capas de Deep Learning Toolbox™, incluidos:

Se agregan dos capas de escala personalizadas para implementar una capa de normalización de lotes adaptable. Estas capas se adjuntan como archivos auxiliares a este ejemplo.

  • -Capa de escala que ajusta las fortalezas de la rama de normalización por lotesadaptiveNormalizationMu

  • -Capa de escala que ajusta las fortalezas de la rama de identidadadaptiveNormalizationLambda

La primera capa, opera en parches de imagen.imageInputLayer El tamaño del parche se basa en el campo receptivo de red, que es la región de la imagen espacial que afecta a la respuesta de la capa superior de la red. Idealmente, el campo receptivo de la red es lo mismo que el tamaño de la imagen de modo que pueda ver todas las características de alto nivel en la imagen. Para un filtro bilateral, el tamaño de parche de la imagen de aproximación se fija a 256-by-256.

networkDepth = 10; numberOfFilters = 32; firstLayer = imageInputLayer([256 256 3],'Name','InputLayer','Normalization','none');

La capa de entrada de imagen va seguida de una capa de convolución 2-D que contiene 32 filtros de tamaño 3x3. Cero-Pad las entradas a cada capa de convolución para que los mapas de entidades permanezcan del mismo tamaño que la entrada después de cada convolución. Inicialice los pesos en la matriz de identidades.

convolutionLayer = convolution2dLayer(3,numberOfFilters,'Padding',1,'Name','Conv1'); Wgts = zeros(3,3,3,numberOfFilters);  for ii = 1:3     Wgts(2,2,ii,ii) = 1; end convolutionLayer.Weights = Wgts;

Cada capa de convolución va seguida de una capa de normalización por lotes y una capa de escala de normalización adaptable que ajusta las fortalezas de la rama de normalización por lotes. Más adelante, este ejemplo creará la capa de escala de normalización adaptable correspondiente que ajusta la intensidad de la rama de identidad. Por ahora, sigue la capa con una capa de adición.adaptiveNormalizationMu Por último, especifique una capa de ReLU con fugas con un multiplicador escalar de 0,2 para las entradas negativas.

batchNorm = batchNormalizationLayer('Name','BN1'); adaptiveMu = adaptiveNormalizationMu(numberOfFilters,'Mu1'); addLayer = additionLayer(2,'Name','add1'); leakyrelLayer = leakyReluLayer(0.2,'Name','Leaky1');

Especifique las capas intermedias de la red siguiendo el mismo patrón. Las sucesivas capas de convolución tienen un factor de dilatación que se escala exponencialmente con la profundidad de la red.

middleLayers = [convolutionLayer batchNorm adaptiveMu addLayer leakyrelLayer];      Wgts = zeros(3,3,numberOfFilters,numberOfFilters); for ii = 1:numberOfFilters     Wgts(2,2,ii,ii) = 1; end      for layerNumber = 2:networkDepth-2     dilationFactor = 2^(layerNumber-1);     padding = dilationFactor;     conv2dLayer = convolution2dLayer(3,numberOfFilters, ...         'Padding',padding, ...         'Name',['Conv' num2str(layerNumber)]);     conv2dLayer.DilationFactor = dilationFactor;     conv2dLayer.Weights = Wgts;     batchNorm = batchNormalizationLayer('Name',['BN' num2str(layerNumber)]);     adaptiveMu = adaptiveNormalizationMu(numberOfFilters,['Mu' num2str(layerNumber)]);     addLayer = additionLayer(2,'Name',['add' num2str(layerNumber)]);     leakyrelLayer = leakyReluLayer(0.2, 'Name', ['Leaky' num2str(layerNumber)]);     middleLayers = [middleLayers conv2dLayer batchNorm adaptiveMu addLayer leakyrelLayer];     end

No aplique un factor de dilatación a la capa de convolución de la segunda a la última.

conv2dLayer = convolution2dLayer(3,numberOfFilters, ...     'Padding', 1,'Name','Conv9');  conv2dLayer.Weights = Wgts; batchNorm = batchNormalizationLayer('Name','AN9'); adaptiveMu = adaptiveNormalizationMu(numberOfFilters,'Mu9'); addLayer = additionLayer(2,'Name','add9'); leakyrelLayer = leakyReluLayer(0.2,'Name', 'Leaky9'); middleLayers = [middleLayers conv2dLayer batchNorm adaptiveMu addLayer leakyrelLayer];

La última capa de convolución tiene un único filtro de tamaño 1x1x32x3 que reconstruye la imagen.

conv2dLayer = convolution2dLayer(1,3, ...     'NumChannels',numberOfFilters, ...     'Name','Conv10'); conv2dLayer.Weights = sqrt(2/(9*numberOfFilters))*randn(1,1,numberOfFilters,3);

La última capa es una capa de regresión en lugar de una capa de ReLU que goteras. La capa de regresión calcula el error medio cuadrado entre la imagen filtrada bilateral y la predicción de red.

finalLayers = [conv2dLayer      regressionLayer('Name','FinalRegressionLayer') ];

Concatenar todas las capas.

layers = [firstLayer middleLayers finalLayers']; lgraph = layerGraph(layers);

Crear conexiones de omisión, que actúan como la rama de identidad para la ecuación de normalización adaptable. Conecte las conexiones de omisión a las capas de adición.

skipConv1 = adaptiveNormalizationLambda(numberOfFilters,'Lambda1'); skipConv2 = adaptiveNormalizationLambda(numberOfFilters,'Lambda2'); skipConv3 = adaptiveNormalizationLambda(numberOfFilters,'Lambda3'); skipConv4 = adaptiveNormalizationLambda(numberOfFilters,'Lambda4'); skipConv5 = adaptiveNormalizationLambda(numberOfFilters,'Lambda5'); skipConv6 = adaptiveNormalizationLambda(numberOfFilters,'Lambda6'); skipConv7 = adaptiveNormalizationLambda(numberOfFilters,'Lambda7'); skipConv8 = adaptiveNormalizationLambda(numberOfFilters,'Lambda8'); skipConv9 = adaptiveNormalizationLambda(numberOfFilters,'Lambda9');  lgraph = addLayers(lgraph,skipConv1); lgraph = connectLayers(lgraph,'Conv1','Lambda1'); lgraph = connectLayers(lgraph,'Lambda1','add1/in2');  lgraph = addLayers(lgraph,skipConv2); lgraph = connectLayers(lgraph,'Conv2','Lambda2'); lgraph = connectLayers(lgraph,'Lambda2','add2/in2');  lgraph = addLayers(lgraph,skipConv3); lgraph = connectLayers(lgraph,'Conv3','Lambda3'); lgraph = connectLayers(lgraph,'Lambda3','add3/in2');  lgraph = addLayers(lgraph,skipConv4); lgraph = connectLayers(lgraph,'Conv4','Lambda4'); lgraph = connectLayers(lgraph,'Lambda4','add4/in2');  lgraph = addLayers(lgraph,skipConv5); lgraph = connectLayers(lgraph,'Conv5','Lambda5'); lgraph = connectLayers(lgraph,'Lambda5','add5/in2');  lgraph = addLayers(lgraph,skipConv6); lgraph = connectLayers(lgraph,'Conv6','Lambda6'); lgraph = connectLayers(lgraph,'Lambda6','add6/in2');  lgraph = addLayers(lgraph,skipConv7); lgraph = connectLayers(lgraph,'Conv7','Lambda7'); lgraph = connectLayers(lgraph,'Lambda7','add7/in2');  lgraph = addLayers(lgraph,skipConv8); lgraph = connectLayers(lgraph,'Conv8','Lambda8'); lgraph = connectLayers(lgraph,'Lambda8','add8/in2');  lgraph = addLayers(lgraph,skipConv9); lgraph = connectLayers(lgraph,'Conv9','Lambda9'); lgraph = connectLayers(lgraph,'Lambda9','add9/in2');

Como alternativa, puede utilizar esta función auxiliar para crear las capas CAN multiescala.

layers = operatorApproximationLayers();

Trace el gráfico de capas.

plot(lgraph)

Especifique opciones de formación

Entrena la red usando el optimizador Adam. Especifique la configuración del hiperparámetro mediante la función.trainingOptions Utilice los valores predeterminados de 0,9 para ' ' y 0,0001 para ' ' (deterioro de peso).MomentumL2Regularization Especifique una tasa de aprendizaje constante de 0,0001. Tren para 181 epochs.

maxEpochs = 181; initLearningRate = 0.0001; miniBatchSize = 1;  options = trainingOptions('adam', ...     'InitialLearnRate',initLearningRate, ...     'MaxEpochs',maxEpochs, ...     'MiniBatchSize',miniBatchSize);

Entrena la red

Ahora que se configuran la fuente de datos y las opciones de entrenamiento, entrena el CAN multiescala usando el.trainNetworkfunction Para entrenar la red, establezca el parámetro en el siguiente código.doTrainingtrue Una GPU NVIDIA™ compatible con CUDA con capacidad de cómputo 3,0 o superior es muy recomendable para el entrenamiento.

Si mantiene el parámetro en el código siguiente como, a continuación, el ejemplo devuelve un preentrenado multiescala CAN que se ha entrenado para aproximar un filtro bilateral.doTrainingfalse

Note: Training usually takes about 15 hours on an NVIDIA™ Titan X and can take even longer depending on your GPU hardware.

doTraining = false; if doTraining     modelDateTime = datestr(now,'dd-mmm-yyyy-HH-MM-SS');     net = trainNetwork(patchds,layers,options);     save(['trainedOperatorLearning-' modelDateTime '-Epoch-' num2str(maxEpochs) '.mat'],'net'); else     load('trainedOperatorLearning-Epoch-181.mat'); end

Realizar aproximación de filtrado bilateral mediante el uso de multiescala CAN

Para procesar una imagen utilizando una red de CAN multiescala entrenada que se aproxima a un filtro bilateral, siga los pasos restantes de este ejemplo. El resto del ejemplo muestra cómo:

  • Cree una imagen de entrada ruidosa de muestra a partir de una imagen de referencia.

  • Realice el filtrado bilateral convencional de la imagen ruidosa utilizando la función.imbilatfilt

  • Realice una aproximación al filtrado bilateral en la imagen ruidosa utilizando el CAN.

  • Compare visualmente las imágenes denozadas de la aproximación del operador y el filtrado bilateral convencional.

  • Evalúe la calidad de las imágenes denozadas cuantificando la similitud de las imágenes con la imagen de referencia prístina.

Crear muestra de imagen ruidosa

Cree una imagen ruidosa de muestra que se utilizará para comparar los resultados de la aproximación del operador al filtrado bilateral convencional. El conjunto de datos de prueba, contiene 21 imágenes prístinas enviadas en Image Processing Toolbox™.testImages Cargue las imágenes en un.imageDatastore

exts = {'.jpg','.png'}; fileNames = {'sherlock.jpg','car2.jpg','fabric.png','greens.jpg','hands1.jpg','kobi.png',...     'lighthouse.png','micromarket.jpg','office_4.jpg','onion.png','pears.png','yellowlily.jpg',...     'indiancorn.jpg','flamingos.jpg','sevilla.jpg','llama.jpg','parkavenue.jpg',...     'peacock.jpg','car1.jpg','strawberries.jpg','wagon.jpg'}; filePath = [fullfile(matlabroot,'toolbox','images','imdata') filesep]; filePathNames = strcat(filePath,fileNames); testImages = imageDatastore(filePathNames,'FileExtensions',exts);

Visualice las imágenes de prueba como un montaje.

montage(testImages)

Seleccione una de las imágenes que se utilizarán como imagen de referencia para el filtrado bilateral. Convierta la imagen al tipo de datos.uint8

indx = 3; % Index of image to read from the test image datastore Ireference = readimage(testImages,indx); Ireference = im2uint8(Ireference);

Opcionalmente, puede utilizar su propia imagen como imagen de referencia. Tenga en cuenta que el tamaño de la imagen de prueba debe ser de al menos 256x256. Si la imagen de prueba es más pequeña que 256x256, aumente el tamaño de la imagen utilizando la función.imresize La red también requiere una imagen de prueba RGB. Si la imagen de prueba es de escala de grises, convierta la imagen a RGB utilizando la función para concatenar tres copias de la imagen original a lo largo de la tercera dimensión.cat

Visualice la imagen de referencia.

imshow(Ireference) title('Pristine Reference Image')

Utilice la función para añadir ruido blanco Gaussiano de media cero con una varianza de 0,00001 a la imagen de referencia.imnoise

Inoisy = imnoise(Ireference,'gaussian',0.00001); imshow(Inoisy) title('Noisy Image')

Filtrar imagen mediante filtrado bilateral

El filtrado bilateral convencional es una forma estándar de reducir el ruido de la imagen preservando la nitidez del borde. Utilice la función para aplicar un filtro bilateral a la imagen ruidosa.imbilatfilt Especifique un grado de suavizado igual a la varianza de los valores de píxel.

degreeOfSmoothing = var(double(Inoisy(:))); Ibilat = imbilatfilt(Inoisy,degreeOfSmoothing); imshow(Ibilat) title('Denoised Image Obtained Using Bilateral Filtering')

Procesar imagen mediante red entrenada

Pase la imagen de entrada normalizada a través de la red entrenada y observe la capa final (una capa de regresión).activations La salida de la red es la imagen denozada deseada.

Iapprox = activations(net,Inoisy,'FinalRegressionLayer');

Image Processing Toolbox™ requiere que las imágenes de punto flotante tengan valores de píxel en el intervalo [0, 1]. Utilice la función para escalar los valores de píxel a este rango y, a continuación, convierta la imagen en.rescaleuint8

Iapprox = rescale(Iapprox); Iapprox = im2uint8(Iapprox); imshow(Iapprox) title('Denoised Image Obtained Using Multiscale CAN')

Comparación visual y cuantitativa

Para obtener una mejor comprensión visual de las imágenes denozadas, examine una pequeña región dentro de cada imagen. Especifique una región de interés (ROI) utilizando vector en el formato [].roixywidthheight Los elementos definen la coordenada x e y de la esquina superior izquierda, y la anchura y la altura del ROI.

roi = [300 30 50 50];

Recortar las imágenes a este ROI, y mostrar el resultado como un montaje.

montage({imcrop(Ireference,roi),imcrop(Inoisy,roi), ...     imcrop(Ibilat,roi),imcrop(Iapprox,roi)}, ...     'Size',[1 4]); title('Reference Image | Noisy Image | Bilateral-Filtered Image | CAN Prediction');

El CAN eliminó más ruido que el filtrado bilateral convencional. Ambas técnicas conservan la nitidez del borde.

Utilice las métricas de calidad de imagen para comparar cuantitativamente la imagen de entrada ruidosa, la imagen filtrada de forma bilateral y la imagen aproximada del operador. La imagen de referencia es la imagen de referencia original, antes de añadir ruido.Ireference

Mida la relación señal-ruido (PSNR) máxima de cada imagen en la imagen de referencia. Los valores PNSR más grandes generalmente indican una mejor calidad de imagen. Consulte para obtener más información acerca de esta métrica.psnr

noisyPSNR = psnr(Inoisy,Ireference); bilatPSNR = psnr(Ibilat,Ireference); approxPSNR = psnr(Iapprox,Ireference); disp(['PSNR of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = ', ...     num2str([noisyPSNR bilatPSNR approxPSNR])])
PSNR of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = 20.2857      25.7978      26.2011 

Mida el índice de similitud estructural (SSIM) de cada imagen. SSIM evalúa el impacto visual de tres características de una imagen: luminancia, contraste y estructura, contra una imagen de referencia. Cuanto más cercano sea el valor de SSIM a 1, mejor será la imagen de prueba de acuerdo con la imagen de referencia. Consulte para obtener más información acerca de esta métrica.ssim

noisySSIM = ssim(Inoisy,Ireference); bilatSSIM = ssim(Ibilat,Ireference); approxSSIM = ssim(Iapprox,Ireference); disp(['SSIM of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = ', ...     num2str([noisySSIM bilatSSIM approxSSIM])])
SSIM of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = 0.76251     0.91576     0.92663 

Mida la calidad de imagen perceptual utilizando el evaluador de calidad de imagen naturalness (NIQE). Las puntuaciones NIQE más pequeñas indican una mejor calidad perceptual. Consulte para obtener más información acerca de esta métrica.niqe

noisyNIQE = niqe(Inoisy); bilatNIQE = niqe(Ibilat); approxNIQE = niqe(Iapprox); disp(['NIQE score of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = ', ...     num2str([noisyNIQE bilatNIQE approxNIQE])])
NIQE score of: Noisy Image / Bilateral-Filtered Image / Operator Approximated Image = 12.1865      7.22606      6.18119 

En comparación con el filtrado bilateral convencional, la aproximación del operador produce mejores puntuaciones métricas.

Resumen

Este ejemplo muestra cómo crear y entrenar una CAN multiescala para aproximar un filtro bilateral. Estos son los pasos para entrenar la red:

  • Descargue los datos de entrenamiento.

  • Cree una que alimente los datos de entrenamiento a la red.randomPatchExtractionDatastore

  • Defina las capas del CAN multiescala.

  • Especifique las opciones de formación.

  • Entrenar la red utilizando la función.trainNetwork

Después de entrenar la CAN multiescala o cargar una red preentrenada, el ejemplo se aproxima a una operación de filtrado bilateral en una imagen ruidosa. El ejemplo compara el resultado con un filtro bilateral convencional que no utiliza el aprendizaje profundo. La aproximación del operador supera el filtrado bilateral con respecto a la calidad de imagen perceptual y las mediciones cuantitativas de calidad.

Referencias

[1] Chen, Q. J. Xu y V. Koltun. "Procesamiento rápido de imágenes con redes completamente convolucionales." En.Proceedings of the 2017 IEEE Conference on Computer Vision Venecia, Italia, 2017 de octubre, págs. 2516-2525.

[2] Grubinger, M., P. Clough, H. Müller y T. Deselaers. "El IAPR TC-12 Benchmark: Un nuevo recurso de evaluación para sistemas de información visual. ".Proceedings of the OntoImage 2006 Language Resources For Content-Based Image Retrieval Génova, Italia. Vol. 5, mayo 2006, p. 10.

Consulte también

| | | | |

Temas relacionados