goimagehash

repository·master·Indexed 21 days ago

https://github.com/corona10/goimagehash

A Go library for generating and comparing perceptual image hashes to detect visually similar images. It supports standard 64-bit and extended hashes using algorithms such as AverageHash (aHash), DifferenceHash (dHash), and PerceptionHash (pHash). The library allows calculating the Hamming distance between hashes and provides functionality to serialize and deserialize hashes via io.Writer and io.Reader.

Tokens
2K
Snippets
9
Records
11
Agent score
73%

What's inside goimagehash

  1. Compare image similarity using hashing algorithms

    master

    The library provides several hashing algorithms to generate perceptual hashes from images. Once hashes are generated, you can use the Distance method to calculate the Hamming distance between them; a lower distance indicates higher similarity.

    Supported algorithms include:

    • AverageHash
    • DifferenceHash
    • PerceptionHash (enhanced in v1.1.0)
    • ExtAverageHash (Extended Average Hash with custom width/height)
    • ExtDifferenceHash (Extended Difference Hash)
    • ExtPerceptionHash (Extended Perception Hash)

    Note: Ext versions allow you to specify the width and height of the hash bit size.

    // Example: Comparing two images using AverageHash
    img1, _ := jpeg.Decode(file1)
    img2, _ := jpeg.Decode(file2)
    
    hash1, _ := goimagehash.AverageHash(img1)
    hash2, _ := goimagehash.AverageHash(img2)
    
    distance, _ := hash1.Distance(hash2)
    fmt.Printf("Distance between images: %v\n", distance)
  2. Serialize and deserialize image hashes

    master

    You can persist image hashes by dumping them to an io.Writer and reloading them from an io.Reader. This is useful for storing hashes in databases or files to avoid re-processing images.

    • Use Dump(io.Writer) to serialize a hash.
    • Use LoadImageHash(io.Reader) or LoadExtImageHash(io.Reader) to deserialize a hash.

    Note: The older FromString methods are deprecated as of v1.0.0.

    var b bytes.Buffer
    foo := bufio.NewWriter(&b)
    
    // Serialize
    _ = hash4.Dump(foo)
    foo.Flush()
    
    // Deserialize
    bar := bufio.NewReader(&b)
    hash5, _ := goimagehash.LoadExtImageHash(bar)
  3. Check hash bit size

    master

    Use the Bits() method on a hash object to retrieve the actual bit size of the generated hash. This is particularly useful when using extended hash functions where the dimensions are configurable.

    fmt.Printf("hash bit size: %v\n", hash.Bits())
  4. Use ExtImageHash for large (multi-uint64) hashes

    master

    The ExtImageHash type is used for hashes that exceed 64 bits, represented as a slice of uint64. It includes the bits count and the Kind. Use NewExtImageHash to initialize it. You can compare two extended hashes using Distance(other *ExtImageHash), which requires both hashes to have the same Kind, the same total bit size, and the same number of uint64 elements.

    import "github.com/corona10/goimagehash"
    
    // Create an extended hash (e.g., 128 bits using two uint64s)
    hash1 := goimagehash.NewExtImageHash([]uint64{1, 2}, goimagehash.DHash, 128)
    hash2 := goimagehash.NewExtImageHash([]uint64{1, 3}, goimagehash.DHash, 128)
    
    dist, err := hash1.Distance(hash2)
    if err != nil {
    	// handle error
    }
    fmt.Printf("Distance: %d\n", dist)
  5. Compute extended hashes with ExtAverageHash, ExtDifferenceHash, and ExtPerceptionHash

    master

    When you need a hash larger than 64 bits (e.g., 256 bits), use the extended hash functions. These functions allow you to specify a custom width and height.

    Requirements:

    • The product of width * height must be a power of 2.
    • If the product is not a power of 2, ExtPerceptionHash will return an error: width * height should be power of 2.

    Functions:

    • ExtAverageHash(img image.Image, width, height int): Returns an *ExtImageHash using the average hash algorithm.
    • ExtDifferenceHash(img image.Image, width, height int): Returns an *ExtImageHash using the difference hash algorithm.
    • ExtPerceptionHash(img image.Image, width, height int): Returns an *ExtImageHash using the perception hash algorithm.

    Commonly supported sizes include 64-bit (8x8) and 256-bit (16x16).

    import (
    	"image"
    	"github.com/corona10/goimagehash"
    )
    
    // Example: 256-bit Average Hash (16x16)
    extHash, err := goimagehash.ExtAverageHash(myImage, 16, 16)
    if err != nil {
    	// handle error
    }
  6. Serialize and deserialize ImageHash

    master

    You can persist ImageHash or ExtImageHash objects using binary serialization via the gob package.

    For ImageHash:

    • Use Dump(w io.Writer) to write the hash to a stream.
    • Use LoadImageHash(b io.Reader) to reconstruct a hash from a stream.

    For ExtImageHash:

    • Use Dump(w io.Writer) to write the hash to a stream.
    • Use LoadExtImageHash(b io.Reader) to reconstruct a hash from a stream.
  7. Use ImageHash for 64-bit hashes

    master

    The ImageHash type represents a standard 64-bit image hash. It is used to store the hash value and its algorithm type (Kind). You can create a new hash using NewImageHash, retrieve its value via GetHash(), and calculate the Hamming distance between two hashes using Distance(other *ImageHash). Note that Distance requires both hashes to have the same Kind.

    import "github.com/corona10/goimagehash"
    
    // Create a new 64-bit hash
    hash1 := goimagehash.NewImageHash(123456789, goimagehash.PHash)
    hash2 := goimagehash.NewImageHash(123456790, goimagehash.PHash)
    
    // Calculate distance
    dist, err := hash1.Distance(hash2)
    if err != nil {
    	// handle error
    }
    fmt.Printf("Distance: %d\n", dist)
  8. Compute standard 64-bit hashes with AverageHash, DifferenceHash, and PerceptionHash

    master

    Use these functions to generate standard 64-bit image hashes. They all take an image.Image as input and return an *ImageHash and an error. If the input image is nil, they return an error: image object can not be nil.

    • AverageHash(img image.Image): Computes an average hash (aHash).
    • DifferenceHash(img image.Image): Computes a difference hash (dHash).
    • PerceptionHash(img image.Image): Computes a perception hash (pHash) using DCT (Discrete Cosine Transform).
    import (
    	"image"
    	"github.com/corona10/goimagehash"
    )
    
    // Example usage
    hash, err := goimagehash.AverageHash(myImage)
    if err != nil {
    	// handle error
    }
  9. Convert ImageHash to and from strings

    master

    You can represent hashes as hex strings for easy storage or transmission.

    ImageHash (64-bit):

    • ToString(): Returns a string in the format k:hex (e.g., p:0000000000000001).
    • ImageHashFromString(s string): Deprecated. Use LoadImageHash with a binary stream instead.

    ExtImageHash (Large):

    • ToString(): Returns a string in the format k:hex_sequence (e.g., d:010203...).
    • ExtImageHashFromString(s string): Deprecated. Use LoadExtImageHash with a binary stream instead.
  10. Supported hash kinds

    master

    The Kind type defines the algorithm used to generate the hash. When comparing hashes via Distance, the Kind must match.

    Supported values:

    • Unknown: Default/unknown hash type.
    • AHash: Average hash.
    • PHash: Perceptual hash.
    • DHash: Difference hash.
    • WHash: Wavelet hash.
    const (
    	Unknown Kind = iota
    	AHash
    	PHash
    	DHash
    	WHash
    )