goimagehash/hashcompute_test.go
2024-08-04 18:24:04 -07:00

395 lines
15 KiB
Go

// Copyright 2017 The goimagehash Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goimagehash
import (
"image"
"image/jpeg"
"os"
"testing"
)
func TestHashCompute(t *testing.T) {
for _, tt := range []struct {
img1 string
img2 string
method func(img image.Image) (*ImageHash, error)
name string
distance int
}{
{"_examples/sample1.jpg", "_examples/sample1.jpg", AverageHash, "AverageHash", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", AverageHash, "AverageHash", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", AverageHash, "AverageHash", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", AverageHash, "AverageHash", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", AverageHash, "AverageHash", 40},
{"_examples/sample1.jpg", "_examples/sample3.jpg", AverageHash, "AverageHash", 0},
{"_examples/sample1.jpg", "_examples/sample4.jpg", AverageHash, "AverageHash", 34},
{"_examples/sample2.jpg", "_examples/sample3.jpg", AverageHash, "AverageHash", 40},
{"_examples/sample2.jpg", "_examples/sample4.jpg", AverageHash, "AverageHash", 6},
{"_examples/sample1.jpg", "_examples/sample1.jpg", DifferenceHash, "DifferenceHash", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", DifferenceHash, "DifferenceHash", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", DifferenceHash, "DifferenceHash", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", DifferenceHash, "DifferenceHash", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", DifferenceHash, "DifferenceHash", 40},
{"_examples/sample1.jpg", "_examples/sample3.jpg", DifferenceHash, "DifferenceHash", 2},
{"_examples/sample1.jpg", "_examples/sample4.jpg", DifferenceHash, "DifferenceHash", 38},
{"_examples/sample2.jpg", "_examples/sample3.jpg", DifferenceHash, "DifferenceHash", 42},
{"_examples/sample2.jpg", "_examples/sample4.jpg", DifferenceHash, "DifferenceHash", 20},
{"_examples/sample1.jpg", "_examples/sample1.jpg", PerceptionHash, "PerceptionHash", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", PerceptionHash, "PerceptionHash", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", PerceptionHash, "PerceptionHash", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", PerceptionHash, "PerceptionHash", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", PerceptionHash, "PerceptionHash", 34},
{"_examples/sample1.jpg", "_examples/sample3.jpg", PerceptionHash, "PerceptionHash", 0},
{"_examples/sample1.jpg", "_examples/sample4.jpg", PerceptionHash, "PerceptionHash", 30},
{"_examples/sample2.jpg", "_examples/sample3.jpg", PerceptionHash, "PerceptionHash", 34},
{"_examples/sample2.jpg", "_examples/sample4.jpg", PerceptionHash, "PerceptionHash", 20},
} {
file1, err := os.Open(tt.img1)
if err != nil {
}
defer file1.Close()
file2, err := os.Open(tt.img2)
if err != nil {
t.Errorf("%s", err)
}
defer file2.Close()
img1, err := jpeg.Decode(file1)
if err != nil {
t.Errorf("%s", err)
}
img2, err := jpeg.Decode(file2)
if err != nil {
t.Errorf("%s", err)
}
hash1, err := tt.method(img1)
if err != nil {
t.Errorf("%s", err)
}
hash2, err := tt.method(img2)
if err != nil {
t.Errorf("%s", err)
}
dis1, err := hash1.Distance(hash2)
if err != nil {
t.Errorf("%s", err)
}
dis2, err := hash2.Distance(hash1)
if err != nil {
t.Errorf("%s", err)
}
if dis1 != dis2 {
t.Errorf("Distance should be identical %v vs %v", dis1, dis2)
}
if dis1 != tt.distance {
t.Errorf("%s: Distance between %v and %v is expected %v but got %v", tt.name, tt.img1, tt.img2, tt.distance, dis1)
}
}
}
func TestNilHashCompute(t *testing.T) {
hash, err := AverageHash(nil)
if err == nil {
t.Errorf("Error should be got.")
}
if hash != nil {
t.Errorf("Nil hash should be got. but got %v", hash)
}
hash, err = DifferenceHash(nil)
if err == nil {
t.Errorf("Error should be got.")
}
if hash != nil {
t.Errorf("Nil hash should be got. but got %v", hash)
}
hash, err = PerceptionHash(nil)
if err == nil {
t.Errorf("Error should be got.")
}
if hash != nil {
t.Errorf("Nil hash should be got. but got %v", hash)
}
}
func TestExtendHashCompute(t *testing.T) {
file, err := os.Open("_examples/sample1.jpg")
if err != nil {
t.Errorf("%s", err)
}
defer file.Close()
img, err := jpeg.Decode(file)
if err != nil {
t.Errorf("%s", err)
}
hash, err := ExtPerceptionHash(img, 0, 8)
if err == nil {
t.Errorf("Error should be got.")
}
if hash != nil {
t.Errorf("Nil hash should be got. but got %v", hash)
}
hash, err = ExtPerceptionHash(img, 16, 2)
if err != nil {
t.Errorf("%s", err)
}
if hash == nil {
t.Errorf("Hash should be got.")
}
}
// func TestNilExtendHashCompute(t *testing.T) {
// hash, err := ExtAverageHash(nil, 8, 8)
// if err == nil {
// t.Errorf("Error should be got.")
// }
// if hash != nil {
// t.Errorf("Nil hash should be got. but got %v", hash)
// }
// hash, err = ExtDifferenceHash(nil, 8, 8)
// if err == nil {
// t.Errorf("Error should be got.")
// }
// if hash != nil {
// t.Errorf("Nil hash should be got. but got %v", hash)
// }
// hash, err = ExtPerceptionHash(nil, 8, 8)
// if err == nil {
// t.Errorf("Error should be got.")
// }
// if hash != nil {
// t.Errorf("Nil hash should be got. but got %v", hash)
// }
// hash, err = ExtPerceptionHash(nil, 8, 9)
// if err == nil {
// t.Errorf("Error should be got.")
// }
// if hash != nil {
// t.Errorf("Nil hash should be got. but got %v", hash)
// }
// }
func BenchmarkDistanceIdentical(b *testing.B) {
h1 := &ImageHash{hash: 0xe48ae53c05e502f7}
h2 := &ImageHash{hash: 0xe48ae53c05e502f7}
for i := 0; i < b.N; i++ {
h1.Distance(h2)
}
}
func BenchmarkDistanceDifferent(b *testing.B) {
h1 := &ImageHash{hash: 0xe48ae53c05e502f7}
h2 := &ImageHash{hash: 0x678be53815e510f7} // 8 bits flipped
for i := 0; i < b.N; i++ {
h1.Distance(h2)
}
}
// func TestExtImageHashCompute(t *testing.T) {
// for _, tt := range []struct {
// img1 string
// img2 string
// width int
// height int
// method func(img image.Image, width, height int) (*ExtImageHash, error)
// name string
// distance int
// }{
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 40},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 34},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 40},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 8, 8, ExtAverageHash, "ExtAverageHash", 6},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 143},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 3},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 148},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 146},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 16, 16, ExtAverageHash, "ExtAverageHash", 31},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 17, 17, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 17, 17, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 17, 17, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 17, 17, ExtAverageHash, "ExtAverageHash", 0},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 32},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 2},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 30},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 34},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 8, 4, ExtPerceptionHash, "ExtPerceptionHash", 20},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 124},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 14},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 122},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 120},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 16, 4, ExtPerceptionHash, "ExtPerceptionHash", 102},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 40},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 2},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 38},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 42},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 8, 8, ExtDifferenceHash, "ExtDifferenceHash", 20},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample1.jpg", "_examples/sample2.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 137},
// {"_examples/sample1.jpg", "_examples/sample3.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 13},
// {"_examples/sample1.jpg", "_examples/sample4.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 124},
// {"_examples/sample2.jpg", "_examples/sample3.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 140},
// {"_examples/sample2.jpg", "_examples/sample4.jpg", 16, 16, ExtDifferenceHash, "ExtDifferenceHash", 109},
// {"_examples/sample1.jpg", "_examples/sample1.jpg", 17, 17, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample2.jpg", "_examples/sample2.jpg", 17, 17, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample3.jpg", "_examples/sample3.jpg", 17, 17, ExtDifferenceHash, "ExtDifferenceHash", 0},
// {"_examples/sample4.jpg", "_examples/sample4.jpg", 17, 17, ExtDifferenceHash, "ExtDifferenceHash", 0},
// } {
// file1, err := os.Open(tt.img1)
// if err != nil {
// t.Errorf("%s", err)
// }
// defer file1.Close()
// file2, err := os.Open(tt.img2)
// if err != nil {
// t.Errorf("%s", err)
// }
// defer file2.Close()
// img1, err := jpeg.Decode(file1)
// if err != nil {
// t.Errorf("%s", err)
// }
// img2, err := jpeg.Decode(file2)
// if err != nil {
// t.Errorf("%s", err)
// }
// hash1, err := tt.method(img1, tt.width, tt.height)
// if err != nil {
// t.Errorf("%s", err)
// }
// hash2, err := tt.method(img2, tt.width, tt.height)
// if err != nil {
// t.Errorf("%s", err)
// }
// dis1, err := hash1.Distance(hash2)
// if err != nil {
// t.Errorf("%s", err)
// }
// dis2, err := hash2.Distance(hash1)
// if err != nil {
// t.Errorf("%s", err)
// }
// if dis1 != dis2 {
// t.Errorf("Distance should be identical %v vs %v", dis1, dis2)
// }
// if dis1 != tt.distance {
// t.Errorf("%s: Distance between %v and %v is expected %v but got %v: %v %v", tt.name, tt.img1, tt.img2, tt.distance, dis1, hash1, hash2)
// }
// }
// }
func BenchmarkExtImageHashDistanceDifferent(b *testing.B) {
h1 := &ExtImageHash{hash: []uint64{0xe48ae53c05e502f7}}
h2 := &ExtImageHash{hash: []uint64{0x678be53815e510f7}} // 8 bits flipped
for i := 0; i < b.N; i++ {
_, err := h1.Distance(h2)
if err != nil {
b.Errorf("%s", err)
}
}
}
func BenchmarkPerceptionHash(b *testing.B) {
file1, err := os.Open("_examples/sample3.jpg")
if err != nil {
b.Errorf("%s", err)
}
defer file1.Close()
img1, err := jpeg.Decode(file1)
if err != nil {
b.Errorf("%s", err)
}
for i := 0; i < b.N; i++ {
_, err := ExtPerceptionHash(img1, 8, 8)
if err != nil {
b.Errorf("%s", err)
}
}
}
// func BenchmarkAverageHash(b *testing.B) {
// file1, err := os.Open("_examples/sample3.jpg")
// if err != nil {
// b.Errorf("%s", err)
// }
// defer file1.Close()
// img1, err := jpeg.Decode(file1)
// if err != nil {
// b.Errorf("%s", err)
// }
// for i := 0; i < b.N; i++ {
// _, err := ExtAverageHash(img1, 8, 8)
// if err != nil {
// b.Errorf("%s", err)
// }
// }
// }
// func BenchmarkDifferenceHash(b *testing.B) {
// file1, err := os.Open("_examples/sample3.jpg")
// if err != nil {
// b.Errorf("%s", err)
// }
// defer file1.Close()
// img1, err := jpeg.Decode(file1)
// if err != nil {
// b.Errorf("%s", err)
// }
// for i := 0; i < b.N; i++ {
// _, err := ExtDifferenceHash(img1, 8, 8)
// if err != nil {
// b.Errorf("%s", err)
// }
// }
// }