Algoritmos de hash de similitud para imágenes

Los algoritmos de hash de imágenes inclyuen tres variantes principales: hash promedio (aHash), hash perceptual (pHash) y hash diferencial (dHash). A continuación, se detalla la implementación del algoritmo de hash promedio (aHash), que es el más sencillo.

Algoritmo de hash promedio (aHash)

Este algoritmo genera un valor de hash único para una imagen mediante los siguientes pasos: redimensionar la imagen, convertirla a escala de grises, calcular el promedio de los píxeles y derivar una huella digital binaria basada en ese proemdio.

Pasos del algoritmo

  1. Redimensionar la imagen: La imagen de entrada se escala a un tamaño estándar de 8x8 píxeles, obteniendo una matriz de 64 valores de píxeles.
  2. Convertir a escala de grises: Las imágenes de entrada pueden ser en diferentes formatos (escala de grises, RGB, RGBA). Para estandarizar, todas se convierten a escala de grises usando el método promedio: Gray = (R + G + B) / 3.
  3. Clacular el promedio de píxeles: Con la matriz de 8x8 en escala de grises, se calcula el valor promedio de todos los elementos, denominado avg.
  4. Generar la huella digital: Se itera sobre cada píxel de la matriz. Si el valor de un píxel es mayor o igual al promedio avg, se agrega un '1' a la cadena hash; de lo contrario, se agrega un '0'. Esto produce una cadena binaria de 64 bits.

Después de obtener el hash de dos imágenes, se calcula la distancia de Hamming entre ellos. Generalmente, se considera que imágenes similares tienen una distancia de Hamming menor a 10.

Implementación en código

La siguiente función en Pascal calcula el hash promedio para una imagen dada:

function CalcHash(sourceBitmap: TBitmap; algorithmType: Integer): Int64;
var
  pixelData: PByteArray;
  scaledBmp: TBitmap;
  col, row: Integer;
  grayValue, totalSum: Integer;
  grayMatrix: array[0..7, 0..7] of Byte;
  meanValue: Single;
  hashResult: Int64;
begin
  hashResult := 0;
  case algorithmType of
    0: // aHash
    begin
      scaledBmp := TBitmap.Create;
      try
        scaledBmp.Assign(sourceBitmap);
        scaledBmp.Width := 8;
        scaledBmp.Height := 8;
        scaledBmp.PixelFormat := pf24bit;
        totalSum := 0;
        for row := 0 to 7 do
        begin
          pixelData := scaledBmp.ScanLine[row];
          for col := 0 to 7 do
          begin
            // Conversión a escala de grises mediante promedio
            grayValue := (pixelData[3 * col + 2] + pixelData[3 * col + 1] + pixelData[3 * col]) div 3;
            grayMatrix[row, col] := grayValue;
            totalSum := totalSum + grayValue;
          end;
        end;
        meanValue := totalSum / 64;
        for row := 0 to 7 do
          for col := 0 to 7 do
            hashResult := hashResult shl 1 or Ord(grayMatrix[row, col] > meanValue);
      finally
        scaledBmp.Free;
      end;
    end;
    // Otros algoritmos (pHash, dHash) pueden implementarse aquí
  end;
  Result := hashResult;
end;

Para comparar dos hashes, se utiliza la función de distancia de Hamming:

function HammingDistance(hash1, hash2: Int64): Integer;
var
  diff: Int64;
begin
  Result := 0;
  diff := hash1 xor hash2;
  while diff <> 0 do
  begin
    diff := diff and (diff - 1);
    Inc(Result);
  end;
end;

Esta implementación proporciona una forma eficiente de evaluar la similitud entre imágenes basada en características de bajo nivel como el color promedio.

Etiquetas: imagen hashing aHash similitud Pascal

Publicado el 6-12 03:27