Skip to content

OverflowError: cannot convert float infinity to integer #205

@dkbarn

Description

@dkbarn

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions