add percentile mean

This commit is contained in:
Olivier Debeir
2012-10-05 12:09:03 +02:00
parent d9efa0bc6c
commit 5e14bf201b
4 changed files with 75 additions and 30 deletions
+10
View File
@@ -0,0 +1,10 @@
import numpy as np
def find_bitdepth(image):
"""returns the max bith depth of a uint16 image
"""
umax = np.max(image)
if umax>2:
return int(np.log2(umax))
else:
return 1
+26 -4
View File
@@ -7,11 +7,14 @@ __docformat__ = 'restructuredtext en'
import warnings
from skimage import img_as_ubyte
import numpy as np
from .generic import find_bitdepth
import _crank16_percentiles,_crank8_percentiles
__all__ = ['percentile_mean']
def percentile_mean(image, selem, out=None, shift_x=False, shift_y=False, p0=.0, p1=1.):
def percentile_mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False, p0=.0, p1=1.):
"""Return greyscale local mean of an image.
Mean is computed on the given structuring element. Only pixel values contained inside the
@@ -20,16 +23,22 @@ def percentile_mean(image, selem, out=None, shift_x=False, shift_y=False, p0=.0,
Parameters
----------
image : ndarray
Image array (uint8 array or uint16).
Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram,
an exception will be raised if image has a value > 4095
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
The array to store the result of the morphology. If None is
passed, a new array will be allocated.
mask : ndarray (uint8)
Mask array that defines (>0) area of the image included in the local neighborhood.
If None, the complete image is used (default).
shift_x, shift_y : bool
shift structuring element about center point. This only affects
eccentric structuring elements (i.e. selem with even numbered sides).
Shift is bounded to the structuring element sizes.
p0, p1 : float in [0.,...,1.]
define the [p0,p1] percentile interval to be considered for computing the value.
Returns
-------
@@ -54,5 +63,18 @@ def percentile_mean(image, selem, out=None, shift_x=False, shift_y=False, p0=.0,
[0, 0, 0, 0, 0]], dtype=uint8)
"""
pass
selem = img_as_ubyte(selem)
if mask is not None:
mask = img_as_ubyte(mask)
if image.dtype == np.uint8:
return _crank8_percentiles.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask,out=out,p0=p0,p1=p1)
elif image.dtype == np.uint16:
bitdepth = find_bitdepth(image)
if bitdepth>11:
raise ValueError("only uint16 <4096 image (12bit) supported!")
return _crank16_percentiles.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask,bitdepth=bitdepth+1,
out=out,p0=p0,p1=p1)
else:
raise TypeError("only uint8 and uint16 image supported!")
+28 -26
View File
@@ -9,21 +9,13 @@ import warnings
from skimage import img_as_ubyte
import numpy as np
from .generic import find_bitdepth
import _crank16,_crank8
__all__ = ['mean']
def find_bitdepth(image):
"""returns the max bith depth of a uint16 image
"""
umax = np.max(image)
if umax>2:
return int(np.log2(umax))
else:
return 1
def mean(image, selem, mask=None, out=None, shift_x=False, shift_y=False):
def mean(image, selem, out=None, mask=None, shift_x=False, shift_y=False):
"""Return greyscale local mean of an image.
Mean is computed on the given structuring element.
@@ -33,14 +25,14 @@ def mean(image, selem, mask=None, out=None, shift_x=False, shift_y=False):
image : ndarray
Image array (uint8 array or uint16). If image is uint16, as the algorithm uses max. 12bit histogram,
an exception will be raised if image has a value > 4095
mask : ndarray (uint8)
Mask array that defines (>0) area of the image included in the local neighborhood.
If None, the complete image is used (default).
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
The array to store the result of the morphology. If None is
passed, a new array will be allocated.
mask : ndarray (uint8)
Mask array that defines (>0) area of the image included in the local neighborhood.
If None, the complete image is used (default).
shift_x, shift_y : bool
shift structuring element about center point. This only affects
eccentric structuring elements (i.e. selem with even numbered sides).
@@ -54,33 +46,43 @@ def mean(image, selem, mask=None, out=None, shift_x=False, shift_y=False):
Examples
--------
to be updated
>>> # Erosion shrinks bright regions
>>> # Local mean
>>> from skimage.morphology import square
>>> bright_square = np.array([[0, 0, 0, 0, 0],
>>> ima8 = 255*np.array([[0, 0, 0, 0, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 1, 1, 0],
... [0, 0, 0, 0, 0]], dtype=np.uint8)
>>> erosion(bright_square, square(3))
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]], dtype=uint8)
>>> mean(ima8, square(3))
array([[ 63, 85, 127, 85, 63],
[ 85, 113, 170, 113, 85],
[127, 170, 255, 170, 127],
[ 85, 113, 170, 113, 85],
[ 63, 85, 127, 85, 63]], dtype=uint8)
>>> ima16 = 4095*np.array([[0, 0, 0, 0, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 1, 1, 0],
... [0, 0, 0, 0, 0]], dtype=np.uint16)
>>> mean(ima16, square(3))
array([[1023, 1365, 2047, 1365, 1023],
[1365, 1820, 2730, 1820, 1365],
[2047, 2730, 4095, 2730, 2047],
[1365, 1820, 2730, 1820, 1365],
[1023, 1365, 2047, 1365, 1023]], dtype=uint16)
"""
if image is out:
raise NotImplementedError("In-place erosion not supported!")
selem = img_as_ubyte(selem)
if mask is not None:
mask = img_as_ubyte(mask)
if image.dtype == np.uint8:
return _crank8.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask)
return _crank8.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask,out=out)
elif image.dtype == np.uint16:
bitdepth = find_bitdepth(image)
if bitdepth>11:
raise ValueError("only uint16 <4096 image are supported!")
return _crank16.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask,bitdepth=bitdepth+1)
raise ValueError("only uint16 <4096 image (12bit) supported!")
return _crank16.mean(image,selem,shift_x=shift_x,shift_y=shift_y,mask=mask,bitdepth=bitdepth+1,out=out)
else:
raise TypeError("only uint8 and uint16 image supported!")
+11
View File
@@ -24,6 +24,17 @@ plt.colorbar()
plt.figure()
plt.imshow(np.hstack((a16,f16)))
plt.colorbar()
f8 = rank.percentile_mean(a8,selem,p0=.1,p1=.9)
f16 = rank.percentile_mean(a16,selem,p0=.1,p1=.9)
plt.figure()
plt.imshow(np.hstack((a8,f8)))
plt.colorbar()
plt.figure()
plt.imshow(np.hstack((a16,f16)))
plt.colorbar()
plt.show()