Reputation: 2909
I am using Imagemagick in order to get the perceptual hash of an image. I use the following command:
identify -verbose -define identify:moments x.png
The output returns amongst other params also the pereceptual hash:
I1: 0.0017694 (0.451197) I2: 3.22345e-07 (0.0209605) I3: 2.88038e-10 (0.00477606) I4: 3.93968e-12 (6.53253e-05) I5: 1.2326e-22 (3.38892e-08) I6: -1.94034e-15 (-8.20426e-06) I7: -4.91938e-23 (-1.35254e-08) I8: 5.56374e-16 (2.35249e-06) Channel perceptual hash: Red, Hue: PH1: 0.407586, 0.690687 PH2: 1.88394, 2.91999 PH3: 2.36028, 3.96979 PH4: 5.36184, 5.3591 PH5: 9.25849, 11 PH6: 6.30422, 6.93025 PH7: 9.6332, 10.0241 Green, Chroma: PH1: 0.293148, -0.0406998 PH2: 1.49146, 2.52843 PH3: 2.21568, 0.992456 PH4: 3.52683, 2.3777 PH5: 6.48291, 4.06334 PH6: 4.38149, 4.23342 PH7: 6.64322, 5.35487 Blue, Luma: PH1: 0.329865, 0.33357 PH2: 1.6461, 1.63528 PH3: 2.39206, 2.26483 PH4: 3.72747, 4.09284 PH5: 6.789, 7.36151 PH6: 4.56493, 5.0171 PH7: 7.83416, 7.50669
I want to save the hash and then compute the distance between 2 images. How can I convert the above output to a hash and calculate the distance between 2 hashes?
Upvotes: 2
Views: 2279
Reputation: 53071
See http://www.fmwconcepts.com/misc_tests/perceptual_hash_test_results_510/index.html for detailed information and tests of this perceptual hash.
Basically it creates 42 floating point values that need to be compared with another set of 42 floating point values from another image using Sum Squared metric.
This is not a simple binary hash that can be easily stored as a string of 1s and 0x and compared using the Hamming distance.
But you can compare two images from their perceptual hashes in ImageMagick using
compare -metric phash image1 image2 null:
You can output the phash values to a .json file if you want.
Alternately, I have two bash unix ImageMagick shell scripts (phashconvert and phashcompare). One will convert the 42 floats to a string of digits that can be saved in the file in the comment section. The second will read two file's comment sections to extract the string, convert them back to floats and then use the Sum Squared Metric to evaluate them. But note this process is only an approximation due to the conversion back and forth from floats to digits.
If you just want to extract the 42 floats, this should do it (from my script phashconvert)
identify -quiet -verbose -moments -alpha off "x.png" | grep "PH[1-7]" | sed -n 's/.*: \(.*\)$/\1/p' | sed 's/ *//g' | tr "," "\n"
Upvotes: 4