找回密码
 加入
搜索
查看: 4960|回复: 10

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

[复制链接]
发表于 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[0]
                        Global $imageFile = $aArray[$m]
                        $PublicDir = _WinAPI_PathRemoveFileSpec($imageFile) & ""
                        $fileFullname = StringRegExp($imageFile, '.+\\(.+)\.([^\.]+)', 3)
                        Global $filename = StringRegExpReplace($fileFullname[0], "[\s+]", "")
                        Global $Extention = $fileFullname[1]
                        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[0]
                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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 4威望 +3 金钱 +560 贡献 +19 收起 理由
zldfsz + 100 + 1 很给力!
haijie1223 + 1 + 200 + 2 很给力!
lpxx + 60 + 14 赞一个!
afan + 2 + 200 + 2 认真的人怎么会缺钱……

查看全部评分

 楼主| 发表于 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






发表于 2018-12-27 00:21:52 | 显示全部楼层
先赞后看,毕竟现在肯踏实做学问的人不多了,记得前不久刚有人问过类似的问题,这么快就有作品出来了。
发表于 2018-12-27 09:41:49 | 显示全部楼层
这个就很有意思了
发表于 2018-12-28 14:56:26 | 显示全部楼层
记号, 感觉很有用
发表于 2019-1-15 10:46:39 | 显示全部楼层
這個不錯用
发表于 2019-1-15 12:16:26 | 显示全部楼层
这个厉害,上次看还是用的imagemagick,现在改成纯au3了
发表于 2019-4-25 15:52:12 | 显示全部楼层
感谢感谢,收藏学习一下
发表于 2019-7-23 08:32:27 | 显示全部楼层
这个貌似有点意思,在特殊情况下可以使用!
发表于 2020-7-15 15:05:55 | 显示全部楼层
不错,感谢提供
发表于 2021-1-5 00:18:23 | 显示全部楼层
非常感谢你的工作!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-22 00:41 , Processed in 0.080681 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表