45 lines
924 B
Go
45 lines
924 B
Go
package vision
|
|
|
|
import (
|
|
"image"
|
|
"math/bits"
|
|
|
|
"github.com/disintegration/imaging"
|
|
)
|
|
|
|
// PHash 计算图像的感知哈希值 (Perceptual Hash)
|
|
// 返回 64 位整数。Hamming 距离越小,图片越相似。
|
|
func PHash(img image.Image) uint64 {
|
|
// 1. 缩小尺寸到 8x8
|
|
resized := imaging.Resize(img, 8, 8, imaging.Lanczos)
|
|
// 2. 转为灰度
|
|
gray := imaging.Grayscale(resized)
|
|
|
|
// 3. 计算像素平均值
|
|
var sum uint64
|
|
pixels := make([]uint8, 64)
|
|
for y := 0; y < 8; y++ {
|
|
for x := 0; x < 8; x++ {
|
|
r, _, _, _ := gray.At(x, y).RGBA()
|
|
v := uint8(r >> 8)
|
|
pixels[y*8+x] = v
|
|
sum += uint64(v)
|
|
}
|
|
}
|
|
avg := uint8(sum / 64)
|
|
|
|
// 4. 根据平均值生成哈希
|
|
var hash uint64
|
|
for i, v := range pixels {
|
|
if v >= avg {
|
|
hash |= (1 << uint(i))
|
|
}
|
|
}
|
|
return hash
|
|
}
|
|
|
|
// Distance 计算两个哈希值之间的 Hamming 距离
|
|
func Distance(h1, h2 uint64) int {
|
|
return bits.OnesCount64(h1 ^ h2)
|
|
}
|