Mixrelax 发表于 2018-12-26 22:05:02

感知哈希算法 松散比较图片 是否相似

本帖最后由 Mixrelax 于 2019-2-18 17:48 编辑

#include <File.au3>
#include <GDIPlus.au3>
#include <WinAPIShPath.au3>
HotKeySet("{F1}", "compare")
Global $Filter = "*.jpg;*.bmp;*.png", $size = 8, $Pixel[$size + 1][$size + 1]

While 1
      Sleep(100)
WEnd

Func compare()
      $aArray = _FileListToArrayRec(@ScriptDir, $Filter, 1 + 4 + 8, 0, 0, 2)
      If @error = 0 Then
                For $m = 1 To $aArray
                        Global $imageFile = $aArray[$m]
                        $PublicDir = _WinAPI_PathRemoveFileSpec($imageFile) & "\"
                        $fileFullname = StringRegExp($imageFile, '.+\\(.+)\.([^\.]+)', 3)
                        Global $filename = StringRegExpReplace($fileFullname, "[\s+]", "")
                        Global $Extention = $fileFullname
                        calc_hash()
                Next
                compare_different()
                FileDelete(@ScriptDir & "\hash.txt")
                Run(@ComSpec & " /c " & 'del /f ' & @ScriptDir & "\*." & $Extention, "", @SW_HIDE)
      EndIf
EndFunc   ;==>compare

Func calc_hash()
      Global $grayValue="", $temp = "", $hex = ""
      $hWnd = _WinAPI_GetDesktopWindow()
      $hDC = _WinAPI_GetDC($hWnd)
      $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $size, $size)
      _WinAPI_ReleaseDC($hWnd, $hDC)
      _GDIPlus_Startup()
      $hOut = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
      $hGraphics = _GDIPlus_ImageGetGraphicsContext($hOut)
      Global $hIn = _GDIPlus_BitmapCreateFromFile($imageFile)
      _GDIPlus_GraphicsDrawImageRect($hGraphics, $hIn, 0, 0, $size, $size)
      For $iY = 0 To $size - 1
                For $iX = 0 To $size - 1
                        $iColor = _GDIPlus_BitmapGetPixel($hOut, $iX, $iY)
                        $ib = BitAND(0xFF, BitShift($iColor, 16))
                        $ir = BitAND(0xFF, $iColor)
                        If $ib = $ir Then
                              $Pixel[$iX][$iY] = $ir
                        Else
                              $ig = BitAND(0xFF, BitShift($iColor, 8))
                              $Pixel[$iX][$iY] = BitShift(($ir * 38 + $ig * 75 + $ib * 15), 7)
                        EndIf
                Next
      Next
      For $i = 0 To $size - 1
                For $j = 0 To $size - 1
                        $grayValue += $Pixel[$i][$j]
                Next
      Next
      $GrayValue_AVG = $grayValue / 64 ;灰度平均值
      
      For $i = 0 To $size - 1
                For $j = 0 To $size - 1
                        $grayValue = $Pixel[$i][$j]
                        If $grayValue >= $GrayValue_AVG Then
                              $temp &= 1
                        Else
                              $temp &= 0
                        EndIf
                Next
      Next
      $matchArray = StringRegExp($temp, '.{4}', 3)
      For $i = 0 To UBound($matchArray) - 1
                $hex &= BinaryToHex($matchArray[$i]);计算哈希
      Next
      FileWriteLine(@ScriptDir & "\hash.txt", $hex)
      _WinAPI_DeleteObject($hBMP)
      _GDIPlus_GraphicsDispose($hGraphics)
      _GDIPlus_BitmapDispose($hOut)
      _GDIPlus_BitmapDispose($hIn)
      _GDIPlus_Shutdown()
EndFunc   ;==>calc_hash

Func compare_different()
      $strA = FileReadLine(@ScriptDir & "\hash.txt", 1)
      $strB = FileReadLine(@ScriptDir & "\hash.txt", 2)
      Local $ArrayA = StringSplit($strA, "", 0)
      Local $ArrayB = StringSplit($strB, "", 0)
      $count = 0
      For $n = 1 To $ArrayA
                If $ArrayA[$n] <> $ArrayB[$n] Then
                        $count += 1
                EndIf;compare hamming distance
      Next
      If $count < 10 Then
                MsgBox(0, "信息", "图片相似 " & $count, 1)
      Else
                MsgBox(0, "信息", "图片不相似 " & $count, 1)
      EndIf
EndFunc   ;==>compare_different

Func BinaryToHex($BinaryInput)
      Switch $BinaryInput
                Case "0000"
                        $var = "0"
                Case "0001"
                        $var = "1"
                Case "0010"
                        $var = "2"
                Case "0011"
                        $var = "3"
                Case "0100"
                        $var = "4"
                Case "0101"
                        $var = "5"
                Case "0110"
                        $var = "6"
                Case "0111"
                        $var = "7"
                Case "1000"
                        $var = "8"
                Case "1001"
                        $var = "9"
                Case "1010"
                        $var = "A"
                Case "1011"
                        $var = "B"
                Case "1100"
                        $var = "C"
                Case "1101"
                        $var = "D"
                Case "1110"
                        $var = "E"
                Case "1111"
                        $var = "F"
      EndSwitch
      Return $var
EndFunc   ;==>BinaryToHex

Mixrelax 发表于 2018-12-26 22:07:57

本帖最后由 Mixrelax 于 2019-1-20 14:54 编辑

@@ Debug(64) : $dif = 0.0104599153416684
>Error code: 0
@@ Debug(66) : $count = 4
汉明距离4 小于10 接近5 较相似,有点不同。耗时 0.01045秒。机器有点老
其他 Phash (离散余弦变化)自己研究吧。改编自 https://www.jianshu.com/p/193f0089b7a2






qq362817567 发表于 2018-12-27 00:21:52

先赞后看,毕竟现在肯踏实做学问的人不多了,记得前不久刚有人问过类似的问题,这么快就有作品出来了。

zch11230 发表于 2018-12-27 09:41:49

这个就很有意思了

ban_r 发表于 2018-12-28 14:56:26

记号, 感觉很有用

kc098829 发表于 2019-1-15 10:46:39

這個不錯用{:face (303):}

ncxj 发表于 2019-1-15 12:16:26

这个厉害,上次看还是用的imagemagick,现在改成纯au3了

guoguo188 发表于 2019-4-25 15:52:12

感谢感谢,收藏学习一下

heavenm 发表于 2019-7-23 08:32:27

这个貌似有点意思,在特殊情况下可以使用!

xwei21 发表于 2020-7-15 15:05:55

不错,感谢提供

sunsunshine2009 发表于 2021-1-5 00:18:23

非常感谢你的工作!
页: [1]
查看完整版本: 感知哈希算法 松散比较图片 是否相似