OverflowError: cannot convert float infinity to integer
Opened this issue · 2 comments
The attached image throws an error when run through the crop_resistant_hash function using the whash hashing algorithm.
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
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
probably the line hashes.append(...) should be skipped if the bounding box is empty.