Delphi圖像Hash算法,關於圖像相似度問題

圖像Hash算法,有PHash,DHash,AHash,以下記錄平均值哈希AHash的Delphi算法代碼

var
  bmp: TBitmap = nil;
  //gb: TBitmap;
//算法原理:將圖像縮放成8x8的灰度圖,統計出像素平均值
//再遍歷每個像素,值大於平均值記爲二進制的1,否則記爲0,最終得到一個64位的整數
function GetAHash(SrcBmp: TBitmap): Int64;
var
  I, J: Integer;
  P24, P8: PByte;
  AG, SG: Integer;
  AVG: Single;
  CT: array[0..7, 0..7] of Byte;
begin
  Result := 0;
  if bmp = nil then
  begin
    bmp := TBitmap.Create;
    bmp.Width := 8;
    bmp.Height := 8;
    bmp.PixelFormat := TPixelFormat.pf24bit;
  end;
//  if gb = nil then
//  begin
//    gb := TBitmap.Create;
//    gb.Width := 8;
//    gb.Height := 8;
//    gb.PixelFormat := TPixelFormat.pf24bit;
//  end;
  //TODO 可以高斯模糊一下,能去除雜點的影響
  SetStretchBltMode(bmp.Canvas.Handle, COLORONCOLOR); //設置指位圖拉伸模式
  StretchBlt(bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, SrcBmp.Canvas.Handle, 0, 0, SrcBmp.Width, SrcBmp.Height, SRCCOPY); //從源矩形中複製一個位圖到目標

  AG := 0;
  for I := 0 to 7 do
  begin
    P24 := bmp.ScanLine[I];
//    P8 := gb.ScanLine[I];
    for J := 0 to 7 do
    begin
      SG := Round(P24[0] * 0.11 + P24[1] * 0.59 + P24[2] * 0.3);
      CT[I, J] := SG;
//      P8[0] := CT[I, J];
//      P8[1] := CT[I, J];
//      P8[2] := CT[I, J];
      Inc(P8, 3);
      AG := AG + SG;
      Inc(P24, 3);
    end;
  end;

//  bmp.SaveToFile('D:\_rgb.bmp');
//  gb.SaveToFile('D:\_gray.bmp');

  AVG := AG / 64;
  Result := 0;
  for I := 0 to 7 do
    for J := 0 to 7 do
      Result := Result shl 1 or Ord(CT[I, J] > AVG);
end;

兩個Hash值比較相似度,比較兩個數有多少個不同的二進制位,即:海明距離

function Hamming(Hash1, Hash2: Int64): Integer;
var
  I: Integer;
  A: Int64;
begin
  Result := 0;
  //使用一個神奇的表達式 n&=(n-1)
  //參考:https://blog.csdn.net/u013243347/article/details/52220551
  A := Hash1 xor Hash2;
  while A <> 0 do
  begin
    A := A and (A -1);
    Inc(Result);
  end;
end;

最後,平均Hash僅適用於背景不變,前景部分變化的場景比較。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章