first commit

This commit is contained in:
hero920103 committed 2026-10-27 17:58:28 +08:00
commit 3553790475
27 files changed
+3839

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
// Package vision 提供帧差指纹、图片编码与(可选的)本地检测接口。
package vision
import (
"image"
"golang.org/x/image/draw"
)
// Fingerprint 是用于判断"画面有没有变化"的感知哈希。
type Fingerprint struct {
AHash uint64 // 均值哈希
DHash uint64 // 差分哈希
Mean uint8 // 平均亮度
}
// grayGrid 把图像缩放到 w×h 的灰度图。
func grayGrid(src image.Image, w, h int) *image.Gray {
dst := image.NewGray(image.Rect(0, 0, w, h))
draw.ApproxBiLinear.Scale(dst, dst.Bounds(), src, src.Bounds(), draw.Src, nil)
return dst
}
// Of 计算图像指纹。
func Of(img image.Image) Fingerprint {
if img == nil {
return Fingerprint{}
}
small := grayGrid(img, 8, 8)
var sum, n int
for _, v := range small.Pix {
sum += int(v)
n++
}
avg := sum / max(n, 1)
mean := uint8(min(avg, 255))
var aHash uint64
for i, v := range small.Pix {
if int(v) > avg {
aHash |= 1 << uint(i)
}
}
wide := grayGrid(img, 9, 8)
var dHash uint64
for y := 0; y < 8; y++ {
for x := 0; x < 8; x++ {
l := wide.GrayAt(x, y).Y
r := wide.GrayAt(x+1, y).Y
if l > r {
dHash |= 1 << uint(y*8+x)
}
}
}
return Fingerprint{AHash: aHash, DHash: dHash, Mean: mean}
}
// Distance 返回两个指纹的汉明距离(取两种哈希的较大值,偏向灵敏)。
func (f Fingerprint) Distance(o Fingerprint) int {
return max(bitsSet(f.AHash^o.AHash), bitsSet(f.DHash^o.DHash))
}
// Changed 判断画面是否发生了足以触发提问的变化。
func (f Fingerprint) Changed(o Fingerprint, threshold int) bool {
if threshold <= 0 {
threshold = 5
}
return f.Distance(o) > threshold
}
func bitsSet(v uint64) int {
n := 0
for v != 0 {
v &= v - 1
n++
}
return n
}