本文整理自网络,侵删。
图像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仅适用于背景不变,前景部分变化的场景比较。
相关阅读 >>
Delphi 格式化输出函数(2): formatdatetime
Delphi 从paintbox拷贝一部分内容到tbitmap
更多相关阅读请进入《Delphi》频道 >>