Skip to content

elcuervo/ph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PH

Perceptual Hashing

What is it?

Perceptual hashing is the technique to generate a fingerprint of an image.

Install

gem install ph

Usage

PH Generates a perceptual hash from an array of pixels. The way you get that pixel data is up to you. Different techniques can shield different values. Hashes exist on a similar space but different reads could yield different (subtle) hashes.

Vips

size = 64
img = Vips::Image.new_from_file(file)
width, height = img.width, img.height
w_scale, v_scale = size.fdiv(width), size.fdiv(height)

img = img
  .resize(w_scale, vscale: v_scale)
  .colourspace(:grey16)

pixels_2d = img.to_a.map(&:flatten)

PH.hash(pixels_2d)
# => "859091ce633aaebb"

RMagick

img = Magick::ImageList.new(file)
size = 64
img = img
  .scale(size, size)
  .dispatch(0, 0, size, size, "I")
  .each_slice(size)
  .to_a

PH.new(img).vector
# => [1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]

Distance

Since hashes exist on a metric space you can measure how far a hash is from another. You can use the hamming gem for calculations if needed

Hamming.distance(hash_a, hash_b)

# You can also transform hashes based on your storage:
Hamming.vector_to_hash(hash)
Hamming.hash_to_vector(vector)