Memoria PIV II (2015)

Trabajo Español
Universidad Universidad Politécnica de Cataluña (UPC)
Grado Ingeniería de Sistemas Audiovisuales - 3º curso
Asignatura (PIV) Procesado de Imagen y Video
Año del apunte 2015
Páginas 21
Fecha de subida 13/03/2016
Descargas 13

Vista previa del texto

         COMPARACIÓN DE IMÁGENES USANDO  DESCRIPTORES DE COLORES DEL ESTÁNDAR  MPEG­7                                           Oriol Bernal  Eduard Torres Romero    1.     ​ Introducción  En  el  presente  trabajo  se  realizará  la  comparación  de  imágenes  mediante  el  uso  de  los  descriptores  de  colores  descritos  en  el  estándar  MPEG­7  y  una  base  de  datos  compuesta  por  2000 imágenes.  Se estudiarán 4 descriptores concretos:  ­          DCD: Dominant Color Descriptor  ­          SCD: Scalable Color Descriptor  ­          CLD: Color Layout Descriptor  ­          CSD: Color Structure Descriptor    2.     ​ Comparación previa.  En  el  pasado  trabajo  se   realizó  la  misma  comparación  con  la   base  de  datos  usando  histogramas  de  las  imágenes  en  color  de  gris.  Los  resultados  obtenidos  fueron  buenos  muy  satisfactorios  para  encontrar  imágenes  idénticas,  pero  el  método  resultó  ser  poco  fiable  para  las imágenes que no eran completamente idénticas.    Como  se  puede  observar,  las   curvas  de  precisión&recall,  que  nos  permitían  evaluar  nuestro  sistema,  pasaban  por  el  punto  0.5­0­5.   Gracias  a  los  descriptores  de  colores  de  MPEG­7  conseguiremos mejorar dichos resultados.     3.     ​ Descriptores de color.  Hay  muchos  descriptores  actualmente,  no  solo  de  color,  sino  también  de  textura,  forma,  etc.  En la realización de este trabajo nos centramos en descriptores de color.  Antes  de  empezar  a  evaluar  los  diferentes  descriptores  del  MPEG­7,  hicimos  una  comparación previa de las imágenes usando histogramas en RGB.  A  diferencia,   del  trabajo  anterior,  donde  solo  usábamos  un  histograma  de  la  escala  de  grises  por  imagen,  en  este  caso  usamos  tres  histogramas  por  imagen,  uno  por  cada  componente   de  color definida por el espacio RGB.  El  método  para  comparar  es  análogo  al  método  de  gris,  usando  un  algoritmo  MAD  (mean  additive difference) para valorar el parecido entre histogramas.  Los  resultados  fueron  los  esperados,  ya  que  mejoramos  las  curvas  anteriores  y  los  cálculos  fueron sencillos, es decir, no introdujimos un exceso de coste computacional.    Sin  embargo,  los  resultados obtenidos no eran suficientes así que nos dispusimos a empezar a  trabajar con los diferentes descriptores.    3.1. ​ DCD  Este  descriptor  proporciona  una  información  compacta  de  los  colores  representativos  de  una  imagen.  De  esta  forma,  cada  imagen  queda  representada  por  un  número  N  de  colores  principales (​ ci​ ​ )  Cada  color  principal  o  dominante  tiene  una  probabilidad  de  aparición  en la  imagen (​ pi​ ​ ). Este  valor está normalizado (al ser una probabilidad) dentro del rango de [0,1].  De  forma  aditiva,  se  pueden añadir más características al descriptor como la varianza de cada  color  c​ v​ )  y  la   homogeneidad  espacial  (​ s​ ) de los colores dominantes, aunque en este trabajo  i   (​ i​ no se tendrán en cuenta.    Para  extraer  los   colores  dominantes  de  una  imagen  se  aplica  el  algoritmo  de  Lloyd  en  el  histograma  de  la  imagen,  donde  se  recomienda  que  esta  esté  definida  en  el  espacio  de  color  CIE LUV.       El  código  usado  para  obtener  los  colores  dominantes  y  sus  respectivas  probabilidades  de  aparición en una imagen es el siguiente:     function​ [ci,  pi]  =  Cluster_ci_pi(I,  num_ci);  ​ %num_si  es  el  número  de  colores  dominantes  (N).  [X,  map]  =  rgb2ind(I,  num_ci,​ 'nodither'​ );  ​ %Nos  devuelve  X  que es la imagen con los  ci.  cihist= imhist(X); ​ %Histograma de la imagen solo con los colores dominantes.  cihist = cihist(1:num_ci);  [cihist, IX] = sort(cihist, ​ 'descend'​ );  pi = cihist/sum(cihist); ​ %pi­> probabilidad de cada color  ci=map(IX, :).*255; ​ %Colores RGB que mas aparecen  ci = rgb2luv(ci);  end     Una  vez  obtenidos  los  parámetros  que  nos  permiten  describir  la  imagen  podemos  compararlas.  Dadas dos imágenes  y obtenemos:        Donde  podemos  obtener  una   medida  paramétrica  de  la  distancia  entre  ellas,  siendo  la  distancia euclídea entre dos colores, como:                    es  un  factor  que  indica  cuando  dos  colores se parecen, se recomienda que su valor esté entre  [10,20]  y  es  multiplicado  por  un  escalar  α  cuyo  valor  se  recomienda  que  esté  en  el  rango  [1.0, 1.5].     function​   D = CompararDCD(c1, c2, p1, p2);  %Compara los colores dominantes y su probabilidad.  Td=10;  alpha=1;  dmax = alpha*Td;  for​  k=1:length(c1(:,1))    for​  l=1:length(c2(:,1))              d(k,l)=sqrt(sum((c1(k,:)­c2(l,:)).^2));    if​  d(k,l)<=Td    a(k,l)=(1­(d(k,l)/dmax));    else    a(k,l)=0;    end    end  end  D = sum(p1.^2) + sum(p2.^2) ­ (sum(sum(2*a*(p1*p2'))));  end     Una  vez  llegados  a  este  punto,  podemos  comparar  todas  las  imágenes  de  la  BD  entre ellas y  realizar una evaluación con las curvas de precision&recall.  Usamos 8 colores dominantes para definir cada imagen,  = 10, y α =  1.         3.2. ​ SCD  El  Scalable  Color  Descriptor  es  un  descriptor  que  se  basa  en  la  transformación  de  Haar  del  histograma  de  una  imagen  en  el  espacio  de  colores  HSV.  De  esta  forma  los  valores  del  histograma  sufren  una  transformación  no  lineal  con  el  fin  de  darles  más  importancia  a  los  valores  pequeños.  La   transformación  de  Haar  que  se  aplica  a  este  histograma  normalizado  está  basada  en   una  serie  de  operaciones  que  consiste,  básicamente,  en  una  cadena  de  operaciones suma y resta sobre los niveles del histograma.  El  análisis  de  wavelets  consiste  en  la  descomposición  de  una  señal  arbitraria  f  en  versiones  escaladas y trasladadas de la wavelet original.  La  ​ wavelet  de  Haar  es  un  sistema  ortonormal  contable  para  el  espacio  de  las  funciones  de  cuadrado  integrable  en  la  recta  real.  La  transformada  de  Haar  puede  ser  pensada  como  un  proceso  de  muestreo   cuyas  filas  de  la  matriz  de  transformación  actúan  como  muestras  de  resolución cada vez más precisas.     El  espacio  de  color  HSV  se   basa  en  un  cilindro  tridimensional  donde  las  dimensiones  corresponden a HUE (h), SATURATION (s) y VALUE (v). Estos valores están normalizados  entre [0,1] y [0,2ᴨ].              function​  [a] = ScalableDescProtocol(I,hBins,sBins,vBins)  [f, c] = size(I);  HISTOhsv = zeros(hBins, sBins, vBins);  pos = zeros(f*c, 3);  Ihsv = rgb2hsv(I);​ %RGB to HSV color space  Ih = Ihsv(:, :, 1); ​ %hue values  Is = Ihsv(:, :, 2); ​ %saturation values  Iv = Ihsv(:, :, 3); ​ %value values  maxH = max(Ih(:));  maxS = max(Is(:));  maxV = max(Iv(:));     k = 1;  for​  i = 1:size(Ih, 1)  for​  j = 1 : size(Ih, 2)    H1(i, j) = round(hBins * Ih(i, j)/maxH);    S1(i, j) = round(sBins * Is(i, j)/maxS);    V1(i, j) = round(vBins * Iv(i, j)/maxV);    pos(k, 1) = H1(i, j);          pos(k, 2) = S1(i, j);    pos(k, 3) = V1(i, j);    k = k+1;  end  end     for​  i = 1:size(pos, 1)  aux=true;  if​  ((pos(i,1)*pos(i,2)*pos(i,3)) == 0)    aux = false;  end  if​  aux  HISTOhsv(pos(i,  1),  pos(i,  2),  pos(i,  3))  =  HISTOhsv(pos(i,  1),  pos(i,  2),  pos(i, 3)) +  1;  end  end     a=WaveletHaar(HISTOhsv);  end      function​  [a4] = WaveletHaar(HISTOhsv)  a1=zeros(8,4,4);  a2=zeros(8,2,4);  a3=zeros(8,2,2);  a4=zeros(4,2,2);  cont=1;  size_hist=size(HISTOhsv);  for​  Ih=1:2:(size_hist(1)­1)    ​ for​  Is=1:size_hist(2)  for​  Iv=1:size_hist(3)        a1(cont,Is,Iv)=HISTOhsv(Ih,Is,Iv)+HISTOhsv(Ih+1,Is,Iv);  end    ​ end    cont=cont+1;  end  cont=1;  for​  Is=1:2:(size_hist(2)­1)    ​ for​  Ih=1:size_hist(2)  for​  Iv=1:size_hist(3)        a2(Ih,cont,Iv)=HISTOhsv(Ih,Is,Iv)+HISTOhsv(Ih,Is+1,Iv);  end    ​ end    cont=cont+1;  end  cont=1;  for​  Iv=1:2:(size_hist(3)­1)    ​ for​  Ih=1:size_hist(1)  for​  Is=1:size_hist(2)        a3(Ih,Is,cont)=HISTOhsv(Ih,Is,Iv)+HISTOhsv(Ih,Is,Iv+1);  end    ​ end    cont=cont+1;  end  cont=1;  for​  Ih=1:2:(size_hist(1)­1)    ​ for​  Is=1:size_hist(2)  for​  Iv=1:size_hist(3)        a4(cont,Is,Iv)=HISTOhsv(Ih,Is,Iv)+HISTOhsv(Ih+1,Is,Iv);  end    ​ end    cont=cont+1;  end       Cada  histograma  queda  representado  por  un  vector  de  8x4x4,  dándole  más  importancia  al  tinte  (hue)  ya  que es donde reside la mayor parte de la información del color de las imágenes.  Para  comparar  las  imágenes  una  vez  se  ha  indexado  la  BD  se   usa  una  matriz  de  4  dimensiones 8x4x4x200 (un vector de 2000 posiciones que guarda matrices de 8x4x4).     function​  [ imagenes ] = Algo2SCD(a, num_imagenes)  load (​ 'SCD.mat'​ );  difsTotal=[];     ​ for​  i =1:length(SCD(1,:,:,:))    dif_cuadrado= (a­ SCD(:,:,:,i));        res=sum(sum(sum(abs(dif_cuadrado))));     ​ end     ordenados=sort(difsTotal);     ​ for​  i=1:num_imagenes         imag(i)=find(difsTotal==ordenados(i),1)­1;     ​ end     imagenes=imag;  end       3.2. ​ CLD  El  Color  Layout  Descriptor   se  basa  en  la  partición  inicial  de  la  imagen   en  bloques  más  pequeños,  después  se  selecciona  el  color  más representativo, se aplica a  cada bloque de color  la  transformada  DCT  y  mediante  una  exploración  en  zig­zag  se  obtienen  los  coeficientes  CLD. Este descriptor trabaja con imágenes en formato HSV.         El código para obtener dichos coeficientes es el siguiente:    function [ CLD_Y, CLD_Cr, CLD_Cb ] = CLD_BD( directorio )  %Función que calcula las matrices CLD de una imagen.  %Usamos 80 bloques de 6x8.  scale=8;  coef=40;  CLD_Y=[];  CLD_Cr=[];  CLD_Cb=[];   lee_archivos = dir(strcat(directorio,'*.jpg'));   fun = @(block_struct) mean2(block_struct.data);    disp('Analizando base de datos:');  for k = 1:length(lee_archivos) %Recorre número de archivos guardados en el directorio      disp(k);      rgb_image=imread(strcat(directorio,lee_archivos(k).name));      mean_rgb(:,:,1)=blockproc(rgb_image(:,:,1),[480/8 640/8],fun);      mean_rgb(:,:,2)=blockproc(rgb_image(:,:,2),[480/8 640/8],fun);      mean_rgb(:,:,3)=blockproc(rgb_image(:,:,3),[480/8 640/8],fun);      %hsv_image = rgb2hsv(mean_rgb);      hsv_image = rgb2ycbcr(mean_rgb);      D=dctmtx(size(hsv_image,1));      DH=toZigzag(D*hsv_image(:,:,1)*D',coef);      DS=toZigzag(D*hsv_image(:,:,2)*D',coef);      DV=toZigzag(D*hsv_image(:,:,3)*D',coef);      CLD_Y=[CLD_Y,DH'];      CLD_Cr=[CLD_Cr,DS'];      CLD_Cb=[CLD_Cb,DV'];   end    function out=toZigzag(x,coef)  % transform a matrix to the zigzag format  [row col]=size(x);  if row~=col  disp('Matrix must be square.');  return;  end;  y=zeros(row*col,1);  count=1;  for s=1:row  if mod(s,2)==0  for m=s:­1:1  y(count)=x(m,s+1­m);  count=count+1;  end;  else  for m=1:s  y(count)=x(m,s+1­m);  count=count+1;  end;  end;  end;  if mod(row,2)==0  flip=1;  else  flip=0;  end;  for s=row+1:2*row­1  if mod(flip,2)==0  for m=row:­1:s+1­row  y(count)=x(m,s+1­m);  count=count+1;  end;  else  for m=row:­1:s+1­row  y(count)=x(s+1­m,m);  count=count+1;  end;  end;  flip=flip+1;  for i=1:coef  out(i)=y(i);  end  end;    Una  vez  hemos  obtenido  los  coeficientes  debemos  poder  compararlos,  para  ello  se  usa  la  siguiente fórmula:          La implementación de la fórmula se hizo de la siguiente manera:    function [ dif ] = dif_CLD(hY1,hCr1,hCb1,hY2,hCr2,hCb2,alpha,alphaY, alphaCr, alphaCb)  %Calcula la diferencia CLD  %Ponderaciones alphaH, alphaS, alphaV    dif=(alphaY*(sum(alpha'.*(hY1­hY2).^2))^0.5)+(alphaCr*(sum(alpha'.*(hCr1­hCr2).^2))^0.
5)+(alphaCb*(sum(alpha'.*(hCb1­hCb2).^2))^0.5);    end    Nota:  Al  código  anterior  es  necesario  pasar  como  parámetros  las  ponderaciones  de  cada  valor  del  vector  que  forman  cada  histograma  así  como  los  pesos  de  cada  uno  de  los  componentes.      3.2. ​ CSD     El  Color  Structure  Descriptor  es,  quizás,  el  descriptor  más  complejo  de  los  tratados  en  este  proyecto.  En  la  realización  del  código  cometimos  ciertos  errores  que  no  hemos  sabido  solucionar pero aún así presentaremos el proceso de obtención de los coeficientes.    El primer problema que se nos presenta es convertir la imagen a HMMD.    Para ello usamos el siguiente código adquirido de un trabajo universitario:      function [hsd,hmmd] = rgb2hmmd(inputI)  % RGB2HMMD converts an RGB image to a HMMD space  % Manjunath et al: MPEG 7   % input : inputI ­ input RGB image  % output: hsd ­ output HMMD image with hue, sum and diff as the  % planes in increasing order  % hmmd ­ output with 4 planes (Hue, Max, Min and diff)  % Preethi Vaidyanathan  % 8­2­11  if size(inputI,3)~= 3      error('Image not RGB')  end  % convert to   I = rgb2hsv(inputI);  hue = I(:,:,1);% first plane of HMMD  Max = max(inputI,[],3);  Min = min(inputI,[],3);  summ = (Max+Min)/2;%second plane  diff = Max­Min;% third plane  hmmd(:,:,1) = hue;  hmmd(:,:,2) = Max;  hmmd(:,:,3) = Min;  hmmd(:,:,4) = diff;  hsd (:,:,1) = hue;  hsd (:,:,2) = summ;  hsd (:,:,3) = diff;    Una  vez  tenemos  la  imagen  en  HMMD  es  necesario  realizar  un  complejo  sistema  de  cuantización  para  obtener  en  cada  píxel  un  valor  dentro   del  rango  [1,  256].  Para  ello  es  necesario seguir la siguiente tabla y un orden predeterminado:                          El código que nosotros generamos era excesivamente costoso y el tiempo de computación en  el laboratorio alcanzó la hora y media.    function [ quantified ] = hmmd_quantification( imagen, num_cells )  %Esta funcion cuantifica una imagen hmmd.  %num_cells sirve para determinar la cuantificación deseada.  %En esta implementación solo se permiten  256 celdas.    hue=imagen(:,:,1);  sum=imagen(:,:,2);  diff=imagen(:,:,3);  maxhue=max(max(hue));  minhue=min(min(hue));  maxsum=max(max(sum));  minsum=min(min(sum));  hueminsub0=maxhue;  huemaxsub0=minhue;  hueminsub1=maxhue;  huemaxsub1=minhue;  hueminsub2=maxhue;  huemaxsub2=minhue;  hueminsub3=maxhue;  huemaxsub3=minhue;  hueminsub4=maxhue;  huemaxsub4=minhue;  summinsub0=maxsum;  summaxsub0=minsum;  summinsub1=maxsum;  summaxsub1=minsum;  summinsub2=maxsum;  summaxsub2=minsum;  summinsub1and2=maxsum;  summaxsub1and2=minsum;  hueminsub1and2=maxhue;  huemaxsub1and2=minhue;  summinsub3=maxsum;  summaxsub3=minsum;  summinsub4=maxsum;  summaxsub4=minsum;  quantified=zeros(length(hue(:,1)),length(hue(1,:)));  %Debemos crear los subespacios de diff  subdiff=diff;  subdiff(0<=diff & diff<6) = 0;  subdiff(6<=diff & diff<20) = 1;  subdiff(20<=diff & diff<60) = 2;  subdiff(60<=diff & diff<110) = 3;  subdiff(110<=diff & diff<=255) = 4;  switch num_cells      case 256              for i=1:length(diff(:,1))              for j=1:length(diff(1,:))                  if subdiff(i,j)==0                      if hueminsub0>hue(i,j)                          hueminsub0=hue(i,j);                      end                      if huemaxsub0<hue(i,j)                          huemaxsub0=hue(i,j);                      end                       if summinsub0>sum(i,j)                          summinsub0=sum(i,j);                      end                      if summaxsub0<sum(i,j)                          summaxsub0=sum(i,j);                      end                  elseif subdiff(i,j)==1                        if hueminsub1>hue(i,j)                          hueminsub1=hue(i,j);                      end                      if huemaxsub1<hue(i,j)                          huemaxsub1=hue(i,j);                      end                      if summinsub1>sum(i,j)                          summinsub1=sum(i,j);                      end                      if summaxsub1<sum(i,j)                          summaxsub1=sum(i,j);                      end                   elseif subdiff(i,j)==2                      if summinsub2>sum(i,j)                          summinsub2=sum(i,j);                      end                      if summaxsub2<sum(i,j)                          summaxsub2=sum(i,j);                      end                      if hueminsub2>hue(i,j)                          hueminsub2=hue(i,j);                      end                      if huemaxsub2<hue(i,j)                          huemaxsub2=hue(i,j);                      end                  elseif subdiff(i,j)==3                       if summinsub3>sum(i,j)                          summinsub3=sum(i,j);                      end                      if summaxsub3<sum(i,j)                          summaxsub3=sum(i,j);                      end                      if hueminsub3>hue(i,j)                          hueminsub3=hue(i,j);                      end                      if huemaxsub3<hue(i,j)                          huemaxsub3=hue(i,j);                      end                  else                      if summinsub4>sum(i,j)                          summinsub4=sum(i,j);                      end                      if summaxsub4<sum(i,j)                          summaxsub4=sum(i,j);                        end                      if hueminsub4>hue(i,j)                          hueminsub4=hue(i,j);                      end                      if huemaxsub4<hue(i,j)                          huemaxsub4=hue(i,j);                      end                      end              end          end          rangesum0=(summaxsub0­summinsub0)/32;          rangehue0=(huemaxsub0­hueminsub0);          rangehue1=(huemaxsub1­hueminsub1)/4;          rangesum1=(summaxsub1­summinsub1)/8;          rangehue2=(huemaxsub1­hueminsub1)/16;          rangesum2=(summaxsub1­summinsub1)/4;          rangehue3=(huemaxsub3­hueminsub3)/16;          rangesum3=(summaxsub3­summinsub3)/4;          rangehue4=(huemaxsub4­hueminsub4)/16;          rangesum4=(summaxsub4­summinsub4)/4;               for i=1:length(diff(:,1))              for j=1:length((diff(1,:)))                  if subdiff(i,j)==0                      numlevelstart=1;                        numlevelshue=1;                      numlevelssum=32;                      count=0;                      for ii=1:numlevelshue+1                      if  ((rangehue0*(ii­1)+hueminsub0)<=hue(i,j))&&(hue(i,j)<(rangehue0*ii+hueminsub0))                         for jj=1:numlevelssum+1                          if  ((rangesum0*(jj­1)+summinsub0)<=sum(i,j))&&(sum(i,j)<(rangesum0*jj+summinsub0))                             quantified(i,j)=numlevelstart+count;                             break;                            end                          count=count+1;                         end                      end                      end                  elseif subdiff(i,j)==1                       numlevelstart=33;                        numlevelshue=4;                      numlevelssum=8;                      count=0;                      for ii=1:numlevelshue+1                      if  ((rangehue1*(ii­1)+hueminsub1)<=hue(i,j))&&(hue(i,j)<(rangehue1*ii+hueminsub1))                         for jj=1:numlevelssum+1                          if  ((rangesum1*(jj­1)+summinsub1)<=sum(i,j))&&(sum(i,j)<(rangesum1*jj+summinsub1))                             quantified(i,j)=numlevelstart+count;                             break;                            end                          count=count+1;                         end                      end                      end                       elseif subdiff(i,j)==2                       numlevelstart=65;                        numlevelshue=16;                      numlevelssum=4;                      count=0;                      for ii=1:numlevelshue+1                      if  ((rangehue2*(ii­1)+hueminsub2)<=hue(i,j))&&(hue(i,j)<(rangehue2*ii+hueminsub2))                         for jj=1:numlevelssum+1                          if  ((rangesum2*(jj­1)+summinsub2)<=sum(i,j))&&(sum(i,j)<(rangesum2*jj+summinsub2))                             quantified(i,j)=numlevelstart+count;                             break;                            end                          count=count+1;                         end                      end                      end                  elseif subdiff(i,j)==3                      numlevelstart=129;                      numlevelshue=16;                      numlevelssum=4;                      count=0;                      for ii=1:numlevelshue+1                      if  ((rangehue3*(ii­1)+hueminsub3)<=hue(i,j))&&(hue(i,j)<(rangehue3*ii+hueminsub3))                         for jj=1:numlevelssum+1                          if  ((rangesum3*(jj­1)+summinsub3)<=sum(i,j))&&(sum(i,j)<(rangesum3*jj+summinsub3))                             quantified(i,j)=numlevelstart+count;                             break;                            end                          count=count+1;                         end                      end                      end                  else                     numlevelstart=192;                      numlevelshue=16;                      numlevelssum=4;                      count=0;                      for ii=1:numlevelshue+1                      if  ((rangehue4*(ii­1)+hueminsub4)<=hue(i,j))&&(hue(i,j)<(rangehue4*ii+hueminsub4))                         for jj=1:numlevelssum+1                          if  ((rangesum4*(jj­1)+summinsub4)<=sum(i,j))&&(sum(i,j)<(rangesum4*jj+summinsub4))                             quantified(i,j)=numlevelstart+count;                             break;                            end                           count=count+1;                          end                      end                      end                  end              end           end       otherwise disp('Número de celdas no permitido.')  end  end    Una vez cuantificada la imagen es necesario crear un histograma con los valores pero para  crearlo es necesario recorrer la imagen usando un enventanado mediante bloques.  Nosotros decidimos implementar un enventanado de 8x8 con un bloque de espaciado entre  cada elemento. Para intentar reducir el tiempo de procesado decidimos recorrer la imagen en  bloques de 16x16.        function [ histo_norm ] = hmmd_histos( hmmd_quantified )  histograma=zeros(256,1);  for i=1:16:length(hmmd_quantified(:,1))­16      for j=1:16:length(hmmd_quantified(1,:))­16          histo_aux=imhist(hmmd_quantified(i:2:(i+14),j:2:(j+14)),256);          histo_aux(histo_aux>0)=1;          histograma=histograma+histo_aux;          end  end  histo_norm=histograma./max(histograma,1);  end    Una vez obtenido dicho histograma debemos calcular la diferencia entre imágenes. Para ello  podemos usar el método que utilizamos con los histogramas en escala de grises, el MAD.    function [ res ] = dif_Histos( hist1, hist2, cuadrado )  %Esta función realiza la resta de dos histogramas y suma el valor absoluto  %de dichos valores para calcular la diferencia entre las imágenes.   switch cuadrado              case 1                  dif_cuadrado= ((hist1­hist2).^2)/length(hist1);                  otherwise                 dif_cuadrado= (hist1­hist2)/length(hist1);          end    res=sum(abs(dif_cuadrado));    end    4.     ​ Análisis de los resultados  Del CSD no pudimos obtener resultados puesto que los histogramas de la base de datos  que obtuvimos eran ceros y no supimos encontrar el error.  En el caso del DCD y el CLD obtuvimos resultados buenos pero muy mejorables, pero no  tuvimos suficiente tiempo para mejorar su implementación.  El  SCD  fue  el  más  problemático,  aunque  al  final  conseguimos  encontrar  los  errores  y  utilizarlo  para  comparar  con  la  BD,  los  resultados  no  fueron  los  esperados,  porque  probablemente tenga algún fallo de código.  Los  volúmenes  de  la  BD  indexada  y  el  tiempo  total  de  ejecución  (del  algoritmo  comparador) fue:     CSD: No results.  DCD: ​ 1475.386802 seconds y 391 KB  SCD:​  1962.551064 seconds y 255 KB  CLD:1537.242467 seconds y 1821 KB         5.     ​ Conclusiones y mejoras  Para realizar el presente trabajo decidimos implementar el máximo de descriptores posible  en  vez  de  centrarnos  en  uno  específico  hasta  conseguir  unos  resultados  buenos.  Pese  a  que  los  resultados  obtenidos,  en  general, no hayan sido espectacularmente buenos, hemos  tenido  la  oportunidad  de  manejar  diferentes  espacios  de  colores  y  muchos  descriptores  aprendiendo conceptos nuevos para cada descriptor.   Hemos  acabado  satisfechos  con  el  trabajo  realizado,  pues  hemos  cumplido  nuestras  expectativas,  que  eran  mejorar  las  curvas  P&R  del  sistema  anterior  y  hemos  disfrutado  aprendiendo y jugando con los diferentes parámetros que nos ofrecían los descriptores.  Para  mejorar  los  resultados  se  podría  intentar  mejorar  cada  descriptor  por  separado  y  luego realizar un algoritmo de forma que:  El  descriptor  que  presente  un  tiempo  de  cálculo  pequeño  pero  que  a  su  vez  sea  relativamente  fiable  se  usaría  para  comparar  las  2000 imágenes, devolviendo  las  50­100  imágenes  más  parecidas.  Finalmente  usar  el  descriptor  más fiable para ordenar estas 50 o  100  imágenes,  devolviendo  las  10  más  parecidas.  De  esta  forma  evitaríamos  un  gran  tiempo de cálculo.  En  este  trabajo  se  trabaja  solo  con  descriptores  de  color,  pero,  ¿Son  suficientes  para  establecer el parecido entre imágenes?  Puede  que  el  uso  de  algún  otro  tipo  de  descriptor,  como  un  descriptor  de  formas  o  de  texturas, mejorase mucho los resultados.    ...