mirror of
https://github.com/wassname/scikit-image.git
synced 2026-06-30 04:19:36 +08:00
Prevented info loss, implemented Log and Sigmoid Correction
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from .exposure import histogram, equalize, equalize_hist, \
|
||||
rescale_intensity, cumulative_distribution
|
||||
rescale_intensity, cumulative_distribution, \
|
||||
adjust_gamma, adjust_sigmoid, adjust_log
|
||||
|
||||
from ._adapthist import equalize_adapthist
|
||||
|
||||
@@ -9,4 +10,6 @@ __all__ = ['histogram',
|
||||
'equalize_adapthist',
|
||||
'rescale_intensity',
|
||||
'cumulative_distribution',
|
||||
'gammaCorrect']
|
||||
'adjust_gamma',
|
||||
'adjust_sigmoid',
|
||||
'adjust_log']
|
||||
|
||||
@@ -218,40 +218,106 @@ def rescale_intensity(image, in_range=None, out_range=None):
|
||||
return dtype(image * (omax - omin) + omin)
|
||||
|
||||
|
||||
def gammaCorrect(image, gamma = 1):
|
||||
"""Transform an image according to Gamma Correction also known as the
|
||||
Power Law Transform.
|
||||
def correct(image, type = None, param1 = None, param2 = None ):
|
||||
"""Performs pixelwise image correction based on the type passed.
|
||||
|
||||
Ref :: http://en.wikipedia.org/wiki/Gamma_correction
|
||||
Types of correction : gamma, logarithmic, sigmoid
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : ndarray
|
||||
image : ndarray, type, param1, param2
|
||||
Input image.
|
||||
gamma : float
|
||||
Non-negative real number
|
||||
|
||||
type : {'gamma', 'logarithmic', 'sigmoid'}
|
||||
Type of correction.
|
||||
'gamma'
|
||||
Gamma Correction or Power Law Transform.
|
||||
|
||||
'logarithmic'
|
||||
Logarithmic and Inverse Logarithmic transform.
|
||||
|
||||
'sigmoid'
|
||||
Sigmoidal Transform or Contrast Adjustment
|
||||
|
||||
param1 : float
|
||||
For type 'gamma', gamma varying from zero to infinity. Default value 1.
|
||||
For type 'logarithmic', param1 should be -1 for inverse logarithmic,
|
||||
else correction will be logarithmic. Default to logarithmic.
|
||||
For type 'sigmoid', gain. Default value 10.
|
||||
|
||||
param2 : float
|
||||
For type 'gamma', positive constatnt multiplier. Default value 1.
|
||||
For type 'logarithmic', positive constatnt multiplier. Default value 1.
|
||||
For type 'sigmoid', cutoff between 0 and 1. Default value 0.5.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
Image with Gamma Correction on the input image.
|
||||
Corrected input image according to the type used.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function transforms the input image pixelwise according to the
|
||||
equation O = I**gamma after scaling each pixel in the range 0 to 1.
|
||||
|
||||
For gamma greater than 1, the histogram will shift towards left and
|
||||
the output image will be darker than the input image.
|
||||
|
||||
For gamma less than 1, the histogram will shift towards right and
|
||||
the output image will be brighter than the input image.
|
||||
References
|
||||
----------
|
||||
..[1] http://en.wikipedia.org/wiki/Gamma_correction
|
||||
..[2] http://www.ece.ucsb.edu/Faculty/Manjunath/courses/ece178W03/EnhancePart1.pdf
|
||||
..[3] http://bme.med.upatras.gr/improc/matalb_code_toc.htm#12. Adjust Contrast :
|
||||
|
||||
"""
|
||||
if type == None:
|
||||
return image
|
||||
|
||||
if type == 'gamma':
|
||||
|
||||
if param1 == None:
|
||||
param1 = 1
|
||||
if param2 == None:
|
||||
param2 = 1
|
||||
|
||||
|
||||
gamma = param1
|
||||
dtype = image.dtype.type
|
||||
|
||||
if gamma < 0:
|
||||
return "Gamma should be a non-negative real number"
|
||||
|
||||
scale = float(dtype_range[dtype][1] - dtype_range[dtype][0])
|
||||
out = ((image/scale)**gamma)*scale*param2
|
||||
return dtype(out)
|
||||
|
||||
if type == 'logarithmic':
|
||||
|
||||
dtype = image.dtype.type
|
||||
scale = float(dtype_range[dtype][1] - dtype_range[dtype][0])
|
||||
|
||||
if param2 == None:
|
||||
param2 = 1
|
||||
if param1 == -1:
|
||||
out = (2**(image/scale) - 1)*scale*param2
|
||||
return dtype(out)
|
||||
|
||||
dtype = image.dtype.type
|
||||
scale = float(dtype_range[dtype][1] - dtype_range[dtype][0])
|
||||
out = np.log2(1 + image/scale)*scale*param2
|
||||
return dtype(out)
|
||||
|
||||
if type == 'sigmoid':
|
||||
|
||||
if param1 == None:
|
||||
param1 = 10
|
||||
if param2 == None:
|
||||
param2 = 0.5
|
||||
|
||||
gain = param1
|
||||
cutoff = param2
|
||||
|
||||
dtype = image.dtype.type
|
||||
scale = float(dtype_range[dtype][1] - dtype_range[dtype][0])
|
||||
out = (1/(1 + np.exp(gain*(cutoff - image/scale))))*scale
|
||||
return dtype(out)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if gamma < 0:
|
||||
return "Gamma should be a non-negative real number"
|
||||
scale = 255.0
|
||||
temp = img_as_ubyte(image)
|
||||
out = ((temp/scale)**gamma)*scale
|
||||
return out
|
||||
|
||||
@@ -180,28 +180,72 @@ if __name__ == '__main__':
|
||||
# Test Gamma Correction
|
||||
# =====================
|
||||
|
||||
def test_gammaCorrect_one():
|
||||
def test_gamma_correct_one():
|
||||
"""Same image should be returned for gamma equal to one"""
|
||||
image = skimage.data.camera()
|
||||
result = exposure.gammaCorrect(image, 1)
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'gamma', 1)
|
||||
assert result.mean() == image.mean()
|
||||
assert result.std() == image.std()
|
||||
|
||||
def test_gammaCorrect_zero():
|
||||
"""White image should be returned for gamma less than zero"""
|
||||
image = skimage.img_as_float(data.camera())
|
||||
result = exposure.gammaCorrect(image, 0)
|
||||
assert result.mean() == 255
|
||||
|
||||
def test_gamma_correct_zero():
|
||||
"""White image should be returned for gamma equal to zero"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'gamma', 0)
|
||||
dtype = image.dtype.type
|
||||
assert result.mean() == dtype_range[dtype][1]
|
||||
assert result.std() == 0
|
||||
|
||||
def test_gammaCorrect_less_one():
|
||||
"""Output's mean should be greater than input's mean for gamma less than one"""
|
||||
image = skimage.data.camera()
|
||||
result = exposure.gammaCorrect(image, 0.5)
|
||||
|
||||
def test_gamma_correct_less_one():
|
||||
"""Output's mean should be greater than input's mean for gamma less than
|
||||
one"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'gamma', 0.5)
|
||||
assert result.mean() > image.mean()
|
||||
|
||||
def test_gammaCorrect_greater_one():
|
||||
"""Output's mean should be less than input's mean for gamma greater than one"""
|
||||
image = skimage.data.camera()
|
||||
result = exposure.gammaCorrect(image, 2)
|
||||
|
||||
def test_gamma_correct_greater_one():
|
||||
"""Output's mean should be less than input's mean for gamma greater than
|
||||
one"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image,'gamma', 2)
|
||||
assert result.mean() < image.mean()
|
||||
|
||||
|
||||
# Test Logarithmic Correction
|
||||
# ===========================
|
||||
|
||||
def test_logarithmic_correct():
|
||||
"""Output's mean should be greater than input's mean for logarithmic
|
||||
correction with multiplier constant equal to unity"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'logarithmic')
|
||||
assert result.mean() > image.mean()
|
||||
|
||||
|
||||
def test_inv_logarithmic_correct():
|
||||
"""Output's mean should be less than input's mean for inverse logarithmic
|
||||
correction with multiplier constant equal to unity"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'logarithmic', -1)
|
||||
assert result.mean() < image.mean()
|
||||
|
||||
|
||||
# Test Sigmoid Correction
|
||||
# =======================
|
||||
|
||||
def test_sigmoid_correct_cutoff_one():
|
||||
"""Output's mean should be less than input's mean for sigmoid
|
||||
correction with cutoff equal to one and gain of 10"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'sigmoid', 10, 1)
|
||||
assert result.mean() < image.mean()
|
||||
|
||||
|
||||
def test_sigmoid_correct_cutoff_zero():
|
||||
"""Output's mean should be greater than input's mean for sigmoid
|
||||
correction with cutoff equal to zero and gain of 10"""
|
||||
image = data.camera()
|
||||
result = exposure.correct(image, 'sigmoid', 10, 0)
|
||||
assert result.mean() > image.mean()
|
||||
|
||||
Reference in New Issue
Block a user