imagehash: Create a new API Bits() (#25)
This commit is contained in:
parent
84eb1859d0
commit
47321c08d3
13
README.md
13
README.md
@ -39,6 +39,19 @@ func main() {
|
||||
hash2, _ = goimagehash.DifferenceHash(img2)
|
||||
distance, _ = hash1.Distance(hash2)
|
||||
fmt.Printf("Distance between images: %v\n", distance)
|
||||
hash3, _ = goimagehash.AverageHashExtend(img1, 16)
|
||||
hash4, _ = goimagehash.AverageHashExtend(img2, 16)
|
||||
distance, _ = hash3.Distance(hash4)
|
||||
fmt.Printf("Distance between images: %v\n", distance)
|
||||
fmt.Printf("hash3 bit size: %v\n", hash3.Bits())
|
||||
fmt.Printf("hash4 bit size: %v\n", hash4.Bits())
|
||||
|
||||
var b bytes.Buffer
|
||||
foo := bufio.NewWriter(&b)
|
||||
_ = hash4.Dump(foo)
|
||||
foo.Flush()
|
||||
bar := bufio.NewReader(&b)
|
||||
hash5, _ := goimagehash.LoadImageHashExtend(bar)
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -29,4 +29,6 @@ func main() {
|
||||
hash2, _ = goimagehash.PerceptionHash(img2)
|
||||
distance, _ = hash1.Distance(hash2)
|
||||
fmt.Printf("Distance between images: %v\n", distance)
|
||||
fmt.Println(hash1.Bits())
|
||||
fmt.Println(hash2.Bits())
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/corona10/goimagehash"
|
||||
"image/jpeg"
|
||||
"os"
|
||||
|
||||
"github.com/corona10/goimagehash"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -20,9 +21,9 @@ func main() {
|
||||
img2, _ := jpeg.Decode(file2)
|
||||
hash1, _ := goimagehash.AverageHashExtend(img1, 15)
|
||||
hash2, _ := goimagehash.AverageHashExtend(img2, 15)
|
||||
hash1024, _ := goimagehash.AverageHashExtend(img2, 32)
|
||||
distance, _ := hash1.Distance(hash2)
|
||||
fmt.Printf("Distance between images: %v\n", distance)
|
||||
|
||||
err := hash1.Dump(foo)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@ -33,6 +34,8 @@ func main() {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
distance, err = hash1.Distance(hash1024)
|
||||
fmt.Println(err)
|
||||
distance, _ = hash1.Distance(hash3)
|
||||
fmt.Printf("Distance between hash1 and hash3: %v\n", distance)
|
||||
distance, _ = hash2.Distance(hash3)
|
||||
@ -40,4 +43,7 @@ func main() {
|
||||
fmt.Println(hash1.ToString())
|
||||
fmt.Println(hash2.ToString())
|
||||
fmt.Println(hash3.ToString())
|
||||
fmt.Println(hash1.Bits())
|
||||
fmt.Println(hash2.Bits())
|
||||
fmt.Println(hash3.Bits())
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ func PerceptionHashExtend(img image.Image, hashSize int) (*ExtImageHash, error)
|
||||
phash[indexOfArray] |= 1 << uint(indexOfBit)
|
||||
}
|
||||
}
|
||||
return NewExtImageHash(phash, PHash), nil
|
||||
return NewExtImageHash(phash, PHash, imgSize), nil
|
||||
}
|
||||
|
||||
// AverageHashExtend function returns ahash of which the size can be set larger than uint64
|
||||
@ -142,7 +142,7 @@ func AverageHashExtend(img image.Image, hashSize int) (*ExtImageHash, error) {
|
||||
ahash[indexOfArray] |= 1 << uint(indexOfBit)
|
||||
}
|
||||
}
|
||||
return NewExtImageHash(ahash, AHash), nil
|
||||
return NewExtImageHash(ahash, AHash, imgSize), nil
|
||||
}
|
||||
|
||||
// DifferenceHashExtend function returns dhash of which the size can be set larger than uint64
|
||||
@ -175,5 +175,5 @@ func DifferenceHashExtend(img image.Image, hashSize int) (*ExtImageHash, error)
|
||||
idx++
|
||||
}
|
||||
}
|
||||
return NewExtImageHash(dhash, DHash), nil
|
||||
return NewExtImageHash(dhash, DHash, imgSize), nil
|
||||
}
|
||||
|
30
imagehash.go
30
imagehash.go
@ -26,6 +26,7 @@ type ImageHash struct {
|
||||
type ExtImageHash struct {
|
||||
hash []uint64
|
||||
kind Kind
|
||||
bits int
|
||||
}
|
||||
|
||||
const (
|
||||
@ -46,6 +47,11 @@ func NewImageHash(hash uint64, kind Kind) *ImageHash {
|
||||
return &ImageHash{hash: hash, kind: kind}
|
||||
}
|
||||
|
||||
// Bits method returns an actual hash bit size
|
||||
func (h *ImageHash) Bits() int {
|
||||
return 64
|
||||
}
|
||||
|
||||
// Distance method returns a distance between two hashes.
|
||||
func (h *ImageHash) Distance(other *ImageHash) (int, error) {
|
||||
if h.GetKind() != other.GetKind() {
|
||||
@ -146,8 +152,13 @@ func (h *ImageHash) ToString() string {
|
||||
}
|
||||
|
||||
// NewExtImageHash function creates a new big hash
|
||||
func NewExtImageHash(hash []uint64, kind Kind) *ExtImageHash {
|
||||
return &ExtImageHash{hash: hash, kind: kind}
|
||||
func NewExtImageHash(hash []uint64, kind Kind, bits int) *ExtImageHash {
|
||||
return &ExtImageHash{hash: hash, kind: kind, bits: bits}
|
||||
}
|
||||
|
||||
// Bits method returns an actual hash bit size
|
||||
func (h *ExtImageHash) Bits() int {
|
||||
return h.bits
|
||||
}
|
||||
|
||||
// Distance method returns a distance between two big hashes
|
||||
@ -156,13 +167,18 @@ func (h *ExtImageHash) Distance(other *ExtImageHash) (int, error) {
|
||||
return -1, errors.New("Extended Image hashes's kind should be identical")
|
||||
}
|
||||
|
||||
if h.Bits() != other.Bits() {
|
||||
msg := fmt.Sprintf("Extended image hash should has an identical bit size but got %v vs %v", h.Bits(), other.Bits())
|
||||
return -1, errors.New(msg)
|
||||
}
|
||||
|
||||
lHash := h.GetHash()
|
||||
rHash := other.GetHash()
|
||||
if len(lHash) != len(rHash) {
|
||||
return -1, errors.New("Extended Image hashes's size should be identical")
|
||||
}
|
||||
|
||||
var distance int
|
||||
distance := 0
|
||||
for idx, lh := range lHash {
|
||||
rh := rHash[idx]
|
||||
hamming := lh ^ rh
|
||||
@ -186,9 +202,10 @@ func (h *ExtImageHash) Dump(w io.Writer) error {
|
||||
type D struct {
|
||||
Hash []uint64
|
||||
Kind Kind
|
||||
Bits int
|
||||
}
|
||||
enc := gob.NewEncoder(w)
|
||||
err := enc.Encode(D{Hash: h.hash, Kind: h.kind})
|
||||
err := enc.Encode(D{Hash: h.hash, Kind: h.kind, Bits: h.bits})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -200,6 +217,7 @@ func LoadImageHashExtend(b io.Reader) (*ExtImageHash, error) {
|
||||
type E struct {
|
||||
Hash []uint64
|
||||
Kind Kind
|
||||
Bits int
|
||||
}
|
||||
var e E
|
||||
dec := gob.NewDecoder(b)
|
||||
@ -207,7 +225,7 @@ func LoadImageHashExtend(b io.Reader) (*ExtImageHash, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ExtImageHash{hash: e.Hash, kind: e.Kind}, nil
|
||||
return &ExtImageHash{hash: e.Hash, kind: e.Kind, bits: e.Bits}, nil
|
||||
}
|
||||
|
||||
const extStrFmt = "%1s:%s"
|
||||
@ -248,7 +266,7 @@ func ExtImageHashFromString(s string) (*ExtImageHash, error) {
|
||||
case "w":
|
||||
kind = WHash
|
||||
}
|
||||
return NewExtImageHash(hash, kind), nil
|
||||
return NewExtImageHash(hash, kind, len(hash)*64), nil
|
||||
}
|
||||
|
||||
// ToString returns a hex representation of big hash
|
||||
|
@ -127,6 +127,31 @@ func TestSerialization(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDifferentBitSizeHash(t *testing.T) {
|
||||
checkErr := func(err error) {
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
}
|
||||
file, err := os.Open("_examples/sample1.jpg")
|
||||
checkErr(err)
|
||||
defer file.Close()
|
||||
|
||||
img, _, err := image.Decode(file)
|
||||
checkErr(err)
|
||||
|
||||
hash1, _ := AverageHashExtend(img, 32)
|
||||
hash2, _ := DifferenceHashExtend(img, 32)
|
||||
_, err = hash1.Distance(hash2)
|
||||
if err == nil {
|
||||
t.Errorf("Should got error with different kinds of hashes")
|
||||
}
|
||||
hash3, _ := AverageHashExtend(img, 31)
|
||||
_, err = hash1.Distance(hash3)
|
||||
if err == nil {
|
||||
t.Errorf("Should got error with different bits of hashes")
|
||||
}
|
||||
}
|
||||
func TestDumpAndLoad(t *testing.T) {
|
||||
checkErr := func(err error) {
|
||||
if err != nil {
|
||||
@ -168,6 +193,10 @@ func TestDumpAndLoad(t *testing.T) {
|
||||
if distance != 0 {
|
||||
t.Errorf("Original and unserialized objects should be identical, got distance=%v", distance)
|
||||
}
|
||||
|
||||
if hash.Bits() != 64 || reHash.Bits() != 64 {
|
||||
t.Errorf("Hash bits should be 64 but got, %v, %v", hash.Bits(), reHash.Bits())
|
||||
}
|
||||
}
|
||||
|
||||
// test for ExtIExtImageHash
|
||||
@ -195,6 +224,10 @@ func TestDumpAndLoad(t *testing.T) {
|
||||
if distance != 0 {
|
||||
t.Errorf("Original and unserialized objects should be identical, got distance=%v", distance)
|
||||
}
|
||||
|
||||
if hash.Bits() != hashSize*hashSize || reHash.Bits() != hashSize*hashSize {
|
||||
t.Errorf("Hash bits should be 64 but got, %v, %v", hash.Bits(), reHash.Bits())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user