AverageHashExtend: Implement AverageHashExtend and fix bugs (#20)

This commit is contained in:
Dong-hee Na 2019-03-16 00:26:38 +09:00 committed by GitHub
parent c41a59a872
commit b535580cae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 33 deletions

View File

@ -91,9 +91,7 @@ func PerceptionHashExtend(img image.Image, hashSize int) (*ExtImageHash, error)
if img == nil {
return nil, errors.New("Image object can not be nil")
}
highFreqFactor := 8
imgSize := hashSize * highFreqFactor
imgSize := hashSize * hashSize
resized := resize.Resize(uint(imgSize), uint(imgSize), img, resize.Bilinear)
pixels := transforms.Rgb2Gray(resized)
dct := transforms.DCT2D(pixels, imgSize, imgSize)
@ -101,10 +99,9 @@ func PerceptionHashExtend(img image.Image, hashSize int) (*ExtImageHash, error)
median := etcs.MedianOfPixels(flattens)
lenOfUnit := 64
lenOfPhash := hashSize * hashSize
phash := make([]uint64, lenOfPhash/lenOfUnit)
phash := make([]uint64, imgSize/lenOfUnit)
for idx, p := range flattens {
indexOfArray := (lenOfPhash - 1 - idx) / lenOfUnit
indexOfArray := (imgSize - 1 - idx) / lenOfUnit
indexOfBit := idx % lenOfUnit
if p > median {
phash[indexOfArray] |= 1 << uint(indexOfBit)
@ -112,3 +109,29 @@ func PerceptionHashExtend(img image.Image, hashSize int) (*ExtImageHash, error)
}
return NewExtImageHash(phash, PHash), nil
}
// AverageHashExtend function returns ahash of which the size can be set larger than uint64
// Support 64bits ahash (hashSize=8) and 256bits ahash (hashSize=16)
func AverageHashExtend(img image.Image, hashSize int) (*ExtImageHash, error) {
if img == nil {
return nil, errors.New("Image object can not be nil")
}
imgSize := hashSize * hashSize
resized := resize.Resize(uint(hashSize), uint(hashSize), img, resize.Bilinear)
pixels := transforms.Rgb2Gray(resized)
flattens := transforms.FlattenPixels(pixels, hashSize, hashSize)
avg := etcs.MeanOfPixels(flattens)
lenOfUnit := 64
ahash := make([]uint64, imgSize/lenOfUnit)
for idx, p := range flattens {
indexOfArray := (imgSize - 1 - idx) / lenOfUnit
indexOfBit := idx % lenOfUnit
if p > avg {
ahash[indexOfArray] |= 1 << uint(indexOfBit)
}
}
return NewExtImageHash(ahash, AHash), nil
}

View File

@ -147,22 +147,36 @@ func TestExtImageHashCompute(t *testing.T) {
img1 string
img2 string
hashSize int
method func(img image.Image, hashSize int) (*ExtImageHash, error)
name string
distance int
}{
{"_examples/sample1.jpg", "_examples/sample1.jpg", 8, "PerceptionHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 8, "PerceptionHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 8, "PerceptionHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 8, "PerceptionHashExtend", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", 8, "PerceptionHashExtend", 32},
{"_examples/sample1.jpg", "_examples/sample3.jpg", 8, "PerceptionHashExtend", 2},
{"_examples/sample1.jpg", "_examples/sample4.jpg", 8, "PerceptionHashExtend", 30},
{"_examples/sample2.jpg", "_examples/sample3.jpg", 8, "PerceptionHashExtend", 34},
{"_examples/sample2.jpg", "_examples/sample4.jpg", 8, "PerceptionHashExtend", 20},
{"_examples/sample1.jpg", "_examples/sample1.jpg", 16, "PerceptionHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 16, "PerceptionHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 16, "PerceptionHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 16, "PerceptionHashExtend", 0},
{"_examples/sample1.jpg", "_examples/sample1.jpg", 8, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 8, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 8, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 8, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", 8, AverageHashExtend, "AverageHashExtend", 42},
{"_examples/sample1.jpg", "_examples/sample3.jpg", 8, AverageHashExtend, "AverageHashExtend", 4},
{"_examples/sample1.jpg", "_examples/sample4.jpg", 8, AverageHashExtend, "AverageHashExtend", 38},
{"_examples/sample2.jpg", "_examples/sample3.jpg", 8, AverageHashExtend, "AverageHashExtend", 40},
{"_examples/sample2.jpg", "_examples/sample4.jpg", 8, AverageHashExtend, "AverageHashExtend", 6},
{"_examples/sample1.jpg", "_examples/sample1.jpg", 16, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 16, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 16, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 16, AverageHashExtend, "AverageHashExtend", 0},
{"_examples/sample1.jpg", "_examples/sample1.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample1.jpg", "_examples/sample2.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 32},
{"_examples/sample1.jpg", "_examples/sample3.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 2},
{"_examples/sample1.jpg", "_examples/sample4.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 30},
{"_examples/sample2.jpg", "_examples/sample3.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 34},
{"_examples/sample2.jpg", "_examples/sample4.jpg", 8, PerceptionHashExtend, "PerceptionHashExtend", 20},
{"_examples/sample1.jpg", "_examples/sample1.jpg", 16, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample2.jpg", "_examples/sample2.jpg", 16, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample3.jpg", "_examples/sample3.jpg", 16, PerceptionHashExtend, "PerceptionHashExtend", 0},
{"_examples/sample4.jpg", "_examples/sample4.jpg", 16, PerceptionHashExtend, "PerceptionHashExtend", 0},
} {
file1, err := os.Open(tt.img1)
if err != nil {
@ -186,11 +200,11 @@ func TestExtImageHashCompute(t *testing.T) {
t.Errorf("%s", err)
}
hash1, err := PerceptionHashExtend(img1, tt.hashSize)
hash1, err := tt.method(img1, tt.hashSize)
if err != nil {
t.Errorf("%s", err)
}
hash2, err := PerceptionHashExtend(img2, tt.hashSize)
hash2, err := tt.method(img2, tt.hashSize)
if err != nil {
t.Errorf("%s", err)
}
@ -212,18 +226,6 @@ func TestExtImageHashCompute(t *testing.T) {
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)
}
if tt.hashSize == 8 {
hash0, err := PerceptionHash(img1)
if err != nil {
t.Errorf("%s", err)
}
hex0 := hash0.ToString()
hex1 := hash1.ToString()
if hex0 != hex1 {
t.Errorf("Hex is expected %v but got %v", hex0, hex1)
}
}
}
}