first commit
This commit is contained in:
commit
3553790475
27 files changed
+3839
No files matched your search
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user