mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-06 02:31:02 +08:00
178 lines
5.0 KiB
Python
178 lines
5.0 KiB
Python
import warnings
|
|
|
|
import numpy as np
|
|
from numpy.testing import assert_array_almost_equal as assert_close
|
|
import skimage
|
|
from skimage import data
|
|
from skimage import exposure
|
|
from skimage.color import rgb2gray
|
|
from skimage.util.dtype import dtype_range
|
|
|
|
|
|
# Test histogram equalization
|
|
# ===========================
|
|
|
|
# squeeze image intensities to lower image contrast
|
|
test_img = skimage.img_as_float(data.camera())
|
|
test_img = exposure.rescale_intensity(test_img / 5. + 100)
|
|
|
|
|
|
def test_equalize_ubyte():
|
|
img = skimage.img_as_ubyte(test_img)
|
|
img_eq = exposure.equalize_hist(img)
|
|
|
|
cdf, bin_edges = exposure.cumulative_distribution(img_eq)
|
|
check_cdf_slope(cdf)
|
|
|
|
|
|
def test_equalize_float():
|
|
img = skimage.img_as_float(test_img)
|
|
img_eq = exposure.equalize_hist(img)
|
|
|
|
cdf, bin_edges = exposure.cumulative_distribution(img_eq)
|
|
check_cdf_slope(cdf)
|
|
|
|
|
|
def check_cdf_slope(cdf):
|
|
"""Slope of cdf which should equal 1 for an equalized histogram."""
|
|
norm_intensity = np.linspace(0, 1, len(cdf))
|
|
slope, intercept = np.polyfit(norm_intensity, cdf, 1)
|
|
assert 0.9 < slope < 1.1
|
|
|
|
|
|
# Test rescale intensity
|
|
# ======================
|
|
|
|
def test_rescale_stretch():
|
|
image = np.array([51, 102, 153], dtype=np.uint8)
|
|
out = exposure.rescale_intensity(image)
|
|
assert out.dtype == np.uint8
|
|
assert_close(out, [0, 127, 255])
|
|
|
|
|
|
def test_rescale_shrink():
|
|
image = np.array([51., 102., 153.])
|
|
out = exposure.rescale_intensity(image)
|
|
assert_close(out, [0, 0.5, 1])
|
|
|
|
|
|
def test_rescale_in_range():
|
|
image = np.array([51., 102., 153.])
|
|
out = exposure.rescale_intensity(image, in_range=(0, 255))
|
|
assert_close(out, [0.2, 0.4, 0.6])
|
|
|
|
|
|
def test_rescale_in_range_clip():
|
|
image = np.array([51., 102., 153.])
|
|
out = exposure.rescale_intensity(image, in_range=(0, 102))
|
|
assert_close(out, [0.5, 1, 1])
|
|
|
|
|
|
def test_rescale_out_range():
|
|
image = np.array([-10, 0, 10], dtype=np.int8)
|
|
out = exposure.rescale_intensity(image, out_range=(0, 127))
|
|
assert out.dtype == np.int8
|
|
assert_close(out, [0, 63, 127])
|
|
|
|
|
|
# Test adaptive histogram equalization
|
|
# ====================================
|
|
|
|
def test_adapthist_scalar():
|
|
'''Test a scalar uint8 image
|
|
'''
|
|
img = skimage.img_as_ubyte(data.moon())
|
|
adapted = exposure.equalize_adapthist(img, clip_limit=0.02)
|
|
assert adapted.min() == 0
|
|
assert adapted.max() == (1 << 16) - 1
|
|
assert img.shape == adapted.shape
|
|
full_scale = skimage.exposure.rescale_intensity(skimage.img_as_uint(img))
|
|
|
|
assert_almost_equal = np.testing.assert_almost_equal
|
|
assert_almost_equal(peak_snr(full_scale, adapted), 101.231, 3)
|
|
assert_almost_equal(norm_brightness_err(full_scale, adapted),
|
|
0.041, 3)
|
|
return img, adapted
|
|
|
|
|
|
def test_adapthist_grayscale():
|
|
'''Test a grayscale float image
|
|
'''
|
|
img = skimage.img_as_float(data.lena())
|
|
img = rgb2gray(img)
|
|
img = np.dstack((img, img, img))
|
|
adapted = exposure.equalize_adapthist(img, 10, 9, clip_limit=0.01,
|
|
nbins=128)
|
|
assert_almost_equal = np.testing.assert_almost_equal
|
|
assert img.shape == adapted.shape
|
|
assert_almost_equal(peak_snr(img, adapted), 97.531, 3)
|
|
assert_almost_equal(norm_brightness_err(img, adapted), 0.0313, 3)
|
|
return data, adapted
|
|
|
|
|
|
def test_adapthist_color():
|
|
'''Test an RGB color uint16 image
|
|
'''
|
|
img = skimage.img_as_uint(data.lena())
|
|
with warnings.catch_warnings(record=True) as w:
|
|
warnings.simplefilter('always')
|
|
hist, bin_centers = exposure.histogram(img)
|
|
assert len(w) > 0
|
|
adapted = exposure.equalize_adapthist(img, clip_limit=0.01)
|
|
assert_almost_equal = np.testing.assert_almost_equal
|
|
assert adapted.min() == 0
|
|
assert adapted.max() == 1.0
|
|
assert img.shape == adapted.shape
|
|
full_scale = skimage.exposure.rescale_intensity(img)
|
|
assert_almost_equal(peak_snr(full_scale, adapted), 102.940, 3)
|
|
assert_almost_equal(norm_brightness_err(full_scale, adapted),
|
|
0.0110, 3)
|
|
return data, adapted
|
|
|
|
|
|
def peak_snr(img1, img2):
|
|
'''Peak signal to noise ratio of two images
|
|
|
|
Parameters
|
|
----------
|
|
img1 : array-like
|
|
img2 : array-like
|
|
|
|
Returns
|
|
-------
|
|
peak_snr : float
|
|
Peak signal to noise ratio
|
|
'''
|
|
if img1.ndim == 3:
|
|
img1, img2 = rgb2gray(img1.copy()), rgb2gray(img2.copy())
|
|
img1 = skimage.img_as_float(img1)
|
|
img2 = skimage.img_as_float(img2)
|
|
mse = 1. / img1.size * np.square(img1 - img2).sum()
|
|
_, max_ = dtype_range[img1.dtype.type]
|
|
return 20 * np.log(max_ / mse)
|
|
|
|
|
|
def norm_brightness_err(img1, img2):
|
|
'''Normalized Absolute Mean Brightness Error between two images
|
|
|
|
Parameters
|
|
----------
|
|
img1 : array-like
|
|
img2 : array-like
|
|
|
|
Returns
|
|
-------
|
|
norm_brightness_error : float
|
|
Normalized absolute mean brightness error
|
|
'''
|
|
if img1.ndim == 3:
|
|
img1, img2 = rgb2gray(img1), rgb2gray(img2)
|
|
ambe = np.abs(img1.mean() - img2.mean())
|
|
nbe = ambe / dtype_range[img1.dtype.type][1]
|
|
return nbe
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from numpy import testing
|
|
testing.run_module_suite()
|