更新代码

This commit is contained in:
hero920103 committed 2026-10-28 17:39:33 +08:00
1 parent eda7e8bc96
commit 6ff632e0b0
19 files changed
+2033 -197

No files matched your search

+45 -6
View File
@@ -7,11 +7,17 @@ import (
"golang.org/x/image/draw"
)
// detailSize 是细节网格的边长。相比 8×8 的感知哈希,这份高分辨率灰度
// 网格专门用来捕捉"布局没变、只是文字/局部内容变了"这类细粒度变化——
// 题目换了但背景一样时,粗哈希几乎不动,细节网格的平均差却会明显跳变。
const detailSize = 64
// Fingerprint 是用于判断"画面有没有变化"的感知哈希。
type Fingerprint struct {
AHash uint64 // 均值哈希
DHash uint64 // 差分哈希
Mean uint8 // 平均亮度
AHash uint64 // 均值哈希(8×8,抗噪、粗筛)
DHash uint64 // 差分哈希(8×8,抗噪、粗筛)
Mean uint8 // 平均亮度
Detail []byte // 细节灰度网格(detailSize×detailSize),用于细粒度内容差
}
// grayGrid 把图像缩放到 w×h 的灰度图。
@@ -55,7 +61,13 @@ func Of(img image.Image) Fingerprint {
}
}
return Fingerprint{AHash: aHash, DHash: dHash, Mean: mean}
// 细节网格:把画面缩到 detailSize×detailSize 的灰度图,
// 用于和上一帧做逐像素的归一化平均差(MAD),比感知哈希灵敏得多。
detailGrid := grayGrid(img, detailSize, detailSize)
detail := make([]byte, len(detailGrid.Pix))
copy(detail, detailGrid.Pix)
return Fingerprint{AHash: aHash, DHash: dHash, Mean: mean, Detail: detail}
}
// Distance 返回两个指纹的汉明距离(取两种哈希的较大值,偏向灵敏)。
@@ -63,12 +75,39 @@ func (f Fingerprint) Distance(o Fingerprint) int {
return max(bitsSet(f.AHash^o.AHash), bitsSet(f.DHash^o.DHash))
}
// DetailDiff 返回两份细节网格的归一化平均绝对差(0~1)。
// 它衡量"逐像素平均变了多少",对文字替换、局部内容更新这类变化远比对
// 比哈希敏感,是提升画面更新识别灵敏度的主力信号。
func (f Fingerprint) DetailDiff(o Fingerprint) float64 {
a, b := f.Detail, o.Detail
if len(a) == 0 || len(b) == 0 || len(a) != len(b) {
return 0
}
var sum int
for i := range a {
d := int(a[i]) - int(b[i])
if d < 0 {
d = -d
}
sum += d
}
return float64(sum) / (float64(len(a)) * 255.0)
}
// Changed 判断画面是否发生了足以触发提问的变化。
func (f Fingerprint) Changed(o Fingerprint, threshold int) bool {
// 任一信号超过阈值即判定为变化:感知哈希(抗噪粗筛)命中,或细节网格的
// 归一化平均差超过 sensitivity(细粒度内容变化)。
func (f Fingerprint) Changed(o Fingerprint, threshold int, sensitivity float64) bool {
if threshold <= 0 {
threshold = 5
}
return f.Distance(o) > threshold
if sensitivity <= 0 {
sensitivity = 0.01
}
if f.Distance(o) > threshold {
return true
}
return f.DetailDiff(o) > sensitivity
}
func bitsSet(v uint64) int {