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

Added changes from faisyl, made corrections #3

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ __pycache__/
*.py[cod]
*$py.class

# Backups
*.bak

# Test images
test_images

# C extensions
*.so

Expand Down
38 changes: 38 additions & 0 deletions compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

""" basic image compare """

import sys

# Custom libphash bindings
import pyphash as phash

# Helpers
def hamming_distance(string1, string2):
return sum(map(str.__ne__, string1, string2))

def get_image_hashes(imagename):
base_image_path = imagename
base_phash_digest = phash.image_digest(base_image_path)
base_phash_imagehash = phash.imagehash(base_image_path)
return (base_phash_digest, base_phash_imagehash)

def test_image_correlations(image1, image2):
hashes1 = get_image_hashes(image1)
hashes2 = get_image_hashes(image2)

print("{} pHash digest: {} and DCT: {}".format(image1, hashes1[0], hashes1[1]))
print("{} pHash digest: {} and DCT: {}".format(image2, hashes2[0], hashes2[1]))

print("Cross-correlation: %5.2f%%" % (
100 * phash.cross_correlation(hashes1[0], hashes2[0])
))

if __name__ == "__main__":
if len(sys.argv) < 3:
print("Please specify two images on the command-line")
sys.exit(1)
image1 = sys.argv[1]
image2 = sys.argv[2]
test_image_correlations(image1, image2)
22 changes: 12 additions & 10 deletions generate_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ set -eux

mkdir -p test_images

SAMPLE_NAME=sample-city-park-400x300.jpg

cd test_images
wget http://s3.amazonaws.com/i.jpg.to/l/8453 -O tony.jpg
wget https://download.samplelib.com/jpeg/$SAMPLE_NAME

convert tony.jpg tony.png
convert $SAMPLE_NAME sample.png

# Scaled
convert tony.png -resize 50% tony-scaled-50.png
convert tony.png -resize 75% tony-scaled-75.png
convert tony.png -resize 150% tony-scaled-150.png
convert sample.png -resize 50% sample-scaled-50.png
convert sample.png -resize 75% sample-scaled-75.png
convert sample.png -resize 150% sample-scaled-150.png

# Blurs
convert tony.png -blur 2x2 tony-blur-2x2.png
convert tony.png -blur 5x2 tony-blur-5x2.png
convert tony.png -blur 0x4 tony-blur-0x4.png
convert sample.png -blur 2x2 sample-blur-2x2.png
convert sample.png -blur 5x2 sample-blur-5x2.png
convert sample.png -blur 0x4 sample-blur-0x4.png

# Rotations
for i in $(seq 1 360); do
convert tony.png -rotate $i "tony-rotate-$i.png"
for i in $(seq 1 90); do
convert sample.png -rotate $i "sample-rotate-$i.png"
done
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# setup.py contributed by Faisal Puthuparackat <[email protected]>

from setuptools import setup

setup(name='pyphash',
version='0.1',
description='A python ctypes wrapper for the pHash library',
url='https://github.com/paulkiernan/pyphash',
author='Paul Kiernan',
author_email='[email protected]',
license='GPLv3',
packages=['pyphash'],
zip_safe=False)
74 changes: 22 additions & 52 deletions test_hashing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,48 @@
""" phashlib Core C++ interface
"""

# Future-proof
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

# Standard Library Imports
from hashlib import md5
from itertools import imap

# Third-party Libraries
import matplotlib.pyplot as plt
from IPython.display import Image, display

# Custom libphash bindings
import python_phash as phash
import pyphash as phash
print(phash)
print(dir(phash))


TEST_IMAGES = {
'base': 'test_images/tony.png',
'base': 'test_images/sample.png',
'blurs': {
'2x2': 'test_images/tony-blur-2x2.png',
'5x2': 'test_images/tony-blur-5x2.png',
'0x4': 'test_images/tony-blur-0x4.png',
'2x2': 'test_images/sample-blur-2x2.png',
'5x2': 'test_images/sample-blur-5x2.png',
'0x4': 'test_images/sample-blur-0x4.png',
},
'rotations': {
'10°': 'test_images/tony-rotate-10.png',
'30°': 'test_images/tony-rotate-30.png',
'90°': 'test_images/tony-rotate-90.png',
'180°': 'test_images/tony-rotate-180.png',
'10°': 'test_images/sample-rotate-10.png',
'30°': 'test_images/sample-rotate-30.png',
'70°': 'test_images/sample-rotate-70.png',
'90°': 'test_images/sample-rotate-90.png',
},
'scaled': {
'50%': 'test_images/tony-scaled-50.png',
'75%': 'test_images/tony-scaled-75.png',
'150%': 'test_images/tony-scaled-150.png',
'50%': 'test_images/sample-scaled-50.png',
'75%': 'test_images/sample-scaled-75.png',
'150%': 'test_images/sample-scaled-150.png',
}
}

# Helpers
def hamming_distance(string1, string2):
return sum(imap(str.__ne__, string1, string2))
return sum(map(str.__ne__, string1, string2))


def test_image_correlations(image_distortion_type, is_ipython_notebook=False):

def test_image_correlations(image_distortion_type):
base_image_path = TEST_IMAGES.get('base')
base_image = Image(filename=base_image_path)
base_phash_digest = phash.image_digest(base_image_path)
base_phash_imagehash = phash.imagehash(base_image_path)
base_md5_digest = md5(open(base_image_path).read()).hexdigest()

if is_ipython_notebook:
display(base_image)
print("md5 Digest: {0}".format(base_md5_digest))
print("pHash Digest: {0}".format(base_phash_digest))
print("pHash DCT Hash: {0}".format(base_phash_imagehash))

for distortion_info, image_path in TEST_IMAGES.get(image_distortion_type).iteritems():
_image = Image(filename=image_path)
if is_ipython_notebook:
display(_image)
for distortion_info, image_path in TEST_IMAGES.get(image_distortion_type).items():
_image_phash_digest = phash.image_digest(image_path)
_image_phash_imagehash = phash.imagehash(image_path)
_image_md5_digest = md5(open(image_path).read()).hexdigest()
print("md5 Digest: {0}".format(_image_md5_digest))
print("md5 Hamming Distance: {0}".format(hamming_distance(base_md5_digest, _image_md5_digest)))
print("pHash Digest: {0}".format(_image_phash_digest))
print("pHash DCT Hash: {0}".format(_image_phash_imagehash))
print("pHash DCT Hash Hamming Distance: {0}".format(
Expand All @@ -88,25 +62,21 @@ def test_image_correlations(image_distortion_type, is_ipython_notebook=False):


def test_rotations():

base_image_path = TEST_IMAGES.get('base')
base_phash_digest = phash.image_digest(base_image_path)

correlations = []
for x in xrange(1, 361):
_image_path = "test_images/tony-rotate-{0}.png".format(x)
for x in range(1, 90):
_image_path = "test_images/sample-rotate-{0}.png".format(x)
_image_phash_digest = phash.image_digest(_image_path)
correlations.append((
x,
phash.cross_correlation(base_phash_digest, _image_phash_digest)
))

return zip(*correlations)
return list(zip(*correlations))

test_image_correlations('scaled', is_ipython_notebook=False)
test_image_correlations('blurs', is_ipython_notebook=False)
test_image_correlations('rotations', is_ipython_notebook=False)
xx, yy = test_rotations()
plt.plot(xx, yy)
plt.plot(xx[:10], yy[:10])
plt.plot(xx[-10:], yy[-10:])
if __name__ == "__main__":
test_image_correlations('scaled')
test_image_correlations('blurs')
test_image_correlations('rotations')