Skip to content

Commit

Permalink
ENH Add generalized Bernsen thresholding
Browse files Browse the repository at this point in the history
This allows the user to specify their own structuring element.
  • Loading branch information
luispedro committed Feb 2, 2013
1 parent 0abf253 commit a90badd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
2 changes: 1 addition & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Version 0.9.6+
* Add ``verbose`` argument to tests.run()
* Add ``circle_se`` to ``morph``
* Allow ``loc(max|min)`` to take floating point inputs
* Add Bernsen local thresholding
* Add Bernsen local thresholding (``bernsen`` and ``gbernsen`` functions)

Version 0.9.6 2012-12-02 by luispedro
* Fix distance() of non-boolean images (issue #24 on github)
Expand Down
14 changes: 12 additions & 2 deletions mahotas/tests/test_thresholding.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License: MIT

import numpy as np
from mahotas.thresholding import otsu, rc, bernsen
from mahotas.thresholding import otsu, rc, bernsen, gbernsen
from mahotas.histogram import fullhistogram

def slow_otsu(img, ignore_zeros=False):
Expand Down Expand Up @@ -102,7 +102,17 @@ def test_soft_threhold():
def test_bernsen():
np.random.seed(120)
for i in range(4):
f = 32*np.random.rand(128,128)
f = 32*np.random.rand(40,68)
f = f.astype(np.uint8)
b = bernsen(f, 8, 15)
assert f.shape == b.shape
b = bernsen(f, 8, 15, 34)
assert f.shape == b.shape

def test_gbernsen():
np.random.seed(120)
for i in range(4):
f = 32*np.random.rand(64,96)
f = f.astype(np.uint8)
b = gbernsen(f, np.ones((3,3), bool), 15, 145)
assert f.shape == b.shape
43 changes: 38 additions & 5 deletions mahotas/thresholding.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,47 @@ def bernsen(f, radius, contrast_threshold, gthresh=None):
Returns
-------
thresholded : binary ndarray
See Also
--------
gbernsen : function
Generalised Bernsen thresholding
'''
from mahotas import morph
from mahotas.convolve import rank_filter
from mahotas.morph import circle_se
if gthresh is None:
gthresh = 128
circle = morph.circle_se(radius)
fmax = rank_filter(f, circle, circle.sum()-1)
fmin = rank_filter(f, circle, 0)
return gbernsen(f, circle_se(radius), contrast_threshold, gthresh)

def gbernsen(f, se, contrast_threshold, gthresh):
'''
thresholded = gbernsen(f, se, contrast_threshold, gthresh)
Generalised Bernsen local thresholding
Parameters
----------
f : ndarray
input image
se : boolean ndarray
structuring element to use for "locality"
contrast_threshold : integer
contrast threshold
gthresh : numeric, optional
global threshold to fall back in low contrast regions
Returns
-------
thresholded : binary ndarray
See Also
--------
bernsen : function
Bernsen thresholding with a circular region
'''
from mahotas.convolve import rank_filter
fmax = rank_filter(f, se, se.sum()-1)
fmin = rank_filter(f, se, 0)
fptp = fmax - fmin
fmean = fmax/.2 + fmin/.2 # Do not use (fmax + fmin) as that may overflow
return np.choose(fptp < contrast_threshold, (fmean < gthresh, fmean > f))

0 comments on commit a90badd

Please sign in to comment.