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

Crop solid background colours (e.g. black or white borders) #65

Open
garygreen opened this issue Sep 14, 2020 · 2 comments
Open

Crop solid background colours (e.g. black or white borders) #65

garygreen opened this issue Sep 14, 2020 · 2 comments

Comments

@garygreen
Copy link

At the moment there doesn't appear to be any way to hook into imagehash to remove solid colours from the image - this causes two images with a heavy black border to look similar.

It would be great if there was a way to filter the image before the perceptual hash is generated.

Take for example these two images - notice the black border on either side. This causes the two images to look 76% similar simply due to the black borders.

7tjPlVMsX5WlUhO4yG3t9uJ9and

7tjPlVMsX5WlUhO4yGgergre3tf

GD provides a imagecropauto which I believe will auto crop out the black / white borders, maybe this could be used?

@qathom
Copy link

qathom commented May 19, 2021

Hi @garygreen
I agree with you - but I am not sure if imagehash should handle this.
If you ask me, it's more an image preprocessing task.

I also faced this issue and I created this helper "remove_constant_colors()".
It will remove all constant colors, all repetitive pixel colors in both vertical and horizontal directions.
By applying this preprocessing task, the image looks like this:
image

When I compare both images, I get a result of hash difference value of 313 which is very high so different images.

Let me know what you think! :-)

import cv2
import numpy as np
from PIL import Image
import imagehash

def remove_constant_colors(path: str):
    image = cv2.imread(path)
    image_h, image_w, nb_col = image.shape
    
    selection_rows = np.invert(np.all(image == image[0], axis = 0))
    image_1 = image[:,selection_rows[:,0]]
    
    image_1_h, image_1_w, nb_col = image_1.shape
    
    selection_cols = np.invert(np.all(image_1 == image_1[0], axis = 1))
    image_2 = image_1[selection_cols[:,0]]

    return image_2

# Usage: hash comparison between the 2 images
path_1 = 'test.jpg'
path_2 = 'test2.jpg'
image_hash_1 = imagehash.average_hash(Image.fromarray(remove_constant_colors(path_1)), hash_size=32)
image_hash_2 = imagehash.average_hash(Image.fromarray(remove_constant_colors(path_2)), hash_size=32)

diff_hash = image_hash_1 - image_hash_2

print('Diff hash', diff_hash) # Returns 313

@omidMolaverdi
Copy link

I guess the easy way is to use imagecropauto(). This can be embedded into the hash function as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants