Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add convenience wrapper for quick similarity computation #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package imagehash

import (
"fmt"

"github.com/vitali-fedulov/images4"
)

// Default hyper space parameters.
const (
epsPct = 0.25
numBuckets = 4
)

// HyperParams holds hyper space parameters for hash computations.
type HyperParams struct {
epsPct float64
numBuckets int
}

// Open opens and decodes an image file for a given path. It is a convenience wrapper around
// imagehash and images4 that returns the icon and hashes.
//
// Takes as input a single optional params that holds epsPct and numBuckets hyper space parameters.
func Open(path string, params ...HyperParams) (Image, error) {
if len(params) > 1 {
return Image{}, fmt.Errorf("Open() only accepts a single HyperParams as input, got %d instead", len(params))
}
eps := epsPct
buckets := numBuckets
if len(params) == 1 {
eps = params[0].epsPct
buckets = params[0].numBuckets
}

img, err := images4.Open(path)
if err != nil {
return Image{}, err
}
icon := images4.Icon(img)
centralHash := CentralHash(icon, HyperPoints10, eps, buckets)
hashSet := HashSet(icon, HyperPoints10, eps, buckets)
return Image{Icon: icon, CentralHash: centralHash, HashSet: hashSet}, nil
}

// Image is a convenience wrapper for holding objects necessary for computing image similarity.
//
// Call Similar() on an Image object for quick similarity computation instead of images4.Similar().
type Image struct {
Icon images4.IconT
CentralHash uint64
HashSet []uint64
}

// Similar returns true if img2 is similar to img. It is a convenience wrapper around imagehash and
// images4 that first compares the images using CentralHash & Hashset, and then using the
// images4.Similar() function iff there is a match between the hashes.
//
// It is faster than calling images4.Similar() directly for dissimilar images and
// only slightly slower for similar images.
func (img Image) Similar(img2 Image) bool {
foundSimilarImage := false
for _, hash := range img2.HashSet {
if img.CentralHash == hash {
foundSimilarImage = true
break
}
}
return foundSimilarImage && images4.Similar(img.Icon, img2.Icon)
}