Merge pull request #1232 from jni/negative-histogram

Protect exposure.histogram from integer overflow
This commit is contained in:
Steven Silvester
2014-11-24 18:42:27 -06:00
2 changed files with 33 additions and 3 deletions
+12 -3
View File
@@ -62,9 +62,18 @@ def histogram(image, nbins=256):
# For integer types, histogramming with bincount is more efficient.
if np.issubdtype(image.dtype, np.integer):
offset = 0
if np.min(image) < 0:
offset = np.min(image)
hist = np.bincount(image.ravel() - offset)
image_min = np.min(image)
if image_min < 0:
offset = image_min
image_range = np.max(image).astype(np.int64) - image_min
# get smallest dtype that can hold both minimum and offset maximum
offset_dtype = np.promote_types(np.min_scalar_type(image_range),
np.min_scalar_type(image_min))
if image.dtype != offset_dtype:
# prevent overflow errors when offsetting
image = image.astype(offset_dtype)
image = image - offset
hist = np.bincount(image.ravel())
bin_centers = np.arange(len(hist)) + offset
# clip histogram to start with a non-zero bin
+21
View File
@@ -12,6 +12,27 @@ from skimage.color import rgb2gray
from skimage.util.dtype import dtype_range
# Test integer histograms
# =======================
def test_negative_overflow():
im = np.array([-1, 127], dtype=np.int8)
frequencies, bin_centers = exposure.histogram(im)
assert_array_equal(bin_centers, np.arange(-1, 128))
assert frequencies[0] == 1
assert frequencies[-1] == 1
assert_array_equal(frequencies[1:-1], 0)
def test_all_negative_image():
im = np.array([-128, -1], dtype=np.int8)
frequencies, bin_centers = exposure.histogram(im)
assert_array_equal(bin_centers, np.arange(-128, 0))
assert frequencies[0] == 1
assert frequencies[-1] == 1
assert_array_equal(frequencies[1:-1], 0)
# Test histogram equalization
# ===========================