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

OverflowError: cannot convert float infinity to integer #205

Open
dkbarn opened this issue Jan 5, 2024 · 2 comments
Open

OverflowError: cannot convert float infinity to integer #205

dkbarn opened this issue Jan 5, 2024 · 2 comments

Comments

@dkbarn
Copy link

dkbarn commented Jan 5, 2024

The attached image throws an error when run through the crop_resistant_hash function using the whash hashing algorithm.
input

Steps to reproduce:

from PIL import Image
import imagehash

image = Image.open("input.jpg")
imagehash.crop_resistant_hash(image, imagehash.whash)

Traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/share/venv/lib/python3.10/site-packages/imagehash/__init__.py", line 695, in crop_resistant_hash
    hashes.append(hash_func(bounding_box))
  File "/share/venv/lib/python3.10/site-packages/imagehash/__init__.py", line 364, in whash
    image_natural_scale = 2**int(numpy.log2(min(image.size)))
OverflowError: cannot convert float infinity to integer

The OverflowError is caused by the fact that on this line of code, image.size is (150, 0). In other words, the image segmentation has produced a bounding box with a 0-pixel dimension. The state of the variables at this point are:

orig_w, orig_h = orig_image.size # (150, 150)
scale_w = float(orig_w) / segmentation_image_size # 0.5
scale_h = float(orig_h) / segmentation_image_size # 0.5
min_y = min(coord[0] for coord in segment) * scale_h # 37.5
min_x = min(coord[1] for coord in segment) * scale_w # 0.0
max_y = (max(coord[0] for coord in segment) + 1) * scale_h # 38.5
max_x = (max(coord[1] for coord in segment) + 1) * scale_w # 150.0
bounding_box = orig_image.crop((min_x, min_y, max_x, max_y)) # <PIL.Image.Image image mode=RGB size=150x0>

So the fact that min_y is 37.5 and max_y is 38.5, when passed into orig_image.crop this seems to generate a 0-pixel height image.

Note that Pillow's Image.crop method is not documented as supporting floating-point x,y coordinates: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop

And we can see from the source that is calling int(round(x)) on each coordinate: https://github.com/python-pillow/Pillow/blob/main/src/PIL/Image.py#L1234

Bizarrely, both 37.5 and 38.5 are getting rounded to 38 on my system 😳

>>> int(round(37.5))
38
>>> int(round(38.5))
38

In case it matters, I'm on Ubuntu 22.04.3 with Python 3.10.12

@Rotzbua
Copy link

Rotzbua commented Feb 16, 2024

Bizarrely, both 37.5 and 38.5 are getting rounded to 38 on my system 😳

Works correct. There are different round rules. Python uses round to even.
https://docs.python.org/3/library/functions.html#round

@JohannesBuchner
Copy link
Owner

probably the line hashes.append(...) should be skipped if the bounding box is empty.

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