def lbp(image, radius, points, ignore_zeros=False): ''' features = lbp(image, radius, points, ignore_zeros=False) Compute Linear Binary Patterns Parameters ---------- image : ndarray input image (2-D numpy ndarray) radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider ignore_zeros : boolean, optional whether to ignore zeros (default: False) Returns ------- features : 1-D numpy ndarray histogram of features Reference --------- Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns Ojala, T. Pietikainen, M. Maenpaa, T. LECTURE NOTES IN COMPUTER SCIENCE (Springer) 2000, ISSU 1842, pages 404-420 ''' from ..interpolate import shift from mahotas.features import _lbp if ignore_zeros: Y,X = np.nonzero(image) def select(im): return im[Y,X].ravel() pixels = image[Y,X].ravel() else: select = np.ravel pixels = image.ravel() image = image.astype(np.float64) angles = np.linspace(0, 2*np.pi, points+1)[:-1] data = [] for dy,dx in zip(np.sin(angles), np.cos(angles)): data.append( select(shift(image, [radius*dy,radius*dx], order=1))) data = np.array(data) codes = (data > pixels).astype(np.int32) codes *= (2**np.arange(points)[:,np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) final = fullhistogram(codes.astype(np.uint32)) codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) compressed = final[pivots[:len(final)]] compressed = np.concatenate((compressed, [0]*(npivots - len(compressed)))) return compressed
def lbp_names(radius, points): '''Return list of names (string) for LBP features Parameters ---------- radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider Returns ------- names : list of str See Also -------- lbp : function Compute LBP features ''' from mahotas.features import _lbp codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) return ['lbp_r{}_p{}_{}'.format(radius, points, i) for i in range(npivots)]
def lbp_transform_local(image, radius, points, ignore_zeros=False, preserve_shape=True): if ignore_zeros and preserve_shape: raise ValueError('mahotas.features.lbp_transform: *ignore_zeros* and *preserve_shape* cannot both be used together') image = np.asanyarray(image, dtype=np.float64) if image.ndim != 2: raise ValueError('mahotas.features.lbp_transform: This function is only defined for two dimensional images') if ignore_zeros: Y,X = np.nonzero(image) def select(im): return im[Y,X].ravel() else: select = np.ravel pixels = select(image) angles = np.linspace(0, 2*np.pi, points+1)[:-1] data = [] for dy,dx in zip(np.sin(angles), np.cos(angles)): data.append( select(shift(image, [radius*dy,radius*dx], order=1))) data = np.array(data) codes = (data > pixels).astype(np.int32) codes *= (2**np.arange(points)[:,np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) if preserve_shape: codes = codes.reshape(image.shape) return codes
def take_hist(codes, points): final = fullhistogram(codes.astype(np.uint32)) codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) compressed = final[pivots[:len(final)]] compressed = np.append(compressed, np.zeros(npivots - len(compressed))) return compressed
def lbp(image, radius, points, ignore_zeros=False): ''' features = lbp(image, radius, points, ignore_zeros=False) Compute Linear Binary Patterns The return value is a **histogram** of feature counts, where position ``i`` corresponds to the number of pixels that had code ``i``. The codes are compressed so that impossible codes are not used. Therefore, this is the ``i``th feature, not just the feature with binary code ``i``. Parameters ---------- image : ndarray input image (2-D numpy ndarray) radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider ignore_zeros : boolean, optional whether to ignore zeros (default: False) Returns ------- features : 1-D numpy ndarray histogram of features. See above for a caveat on the interpretation of these. Reference --------- Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns Ojala, T. Pietikainen, M. Maenpaa, T. Lecture Notes in Computer Science (Springer) 2000, ISSU 1842, pages 404-420 ''' from mahotas.features import _lbp codes = lbp_transform(image, radius, points, ignore_zeros=ignore_zeros, preserve_shape=False) final = fullhistogram(codes.astype(np.uint32)) codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) compressed = final[pivots[:len(final)]] compressed = np.append(compressed, np.zeros(npivots - len(compressed))) return compressed
def lbp_transform(image, radius, points, ignore_zeros=False, preserve_shape=True): ''' transformed = lbp(image, radius, points, ignore_zeros=False, preserve_shape=True) Compute Linear Binary Pattern Transform The return value are the transformed pixel values **histogram** of feature counts, where position ``i`` corresponds to the number of pixels that had code ``i``. The codes are compressed so that impossible codes are not used. Therefore, this is the ``i``th feature, not just the feature with binary code ``i``. Parameters ---------- image : ndarray input image (2-D numpy ndarray) radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider ignore_zeros : boolean, optional whether to ignore zeros. Note that if you set this to ``True``, you will need to set ``preserve_shape`` to False. (default: False) preserve_shape : boolean, optional whether to return an array with the same shape as ``image``. (default: True) Returns ------- features : 1-D numpy ndarray histogram of features. See above for a caveat on the interpretation of these. Reference --------- Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns Ojala, T. Pietikainen, M. Maenpaa, T. Lecture Notes in Computer Science (Springer) 2000, ISSU 1842, pages 404-420 ''' from ..interpolate import shift from mahotas.features import _lbp if ignore_zeros and preserve_shape: raise ValueError('mahotas.features.lbp_transform: *ignore_zeros* and *preserve_shape* cannot both be used together') image = np.asanyarray(image, dtype=np.float64) if ignore_zeros: Y,X = np.nonzero(image) def select(im): return im[Y,X].ravel() else: select = np.ravel pixels = select(image) angles = np.linspace(0, 2*np.pi, points+1)[:-1] data = [] for dy,dx in zip(np.sin(angles), np.cos(angles)): data.append( select(shift(image, [radius*dy,radius*dx], order=1))) data = np.array(data) codes = (data > pixels).astype(np.int32) codes *= (2**np.arange(points)[:,np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) if preserve_shape: codes = codes.reshape(image.shape) return codes
def lbp_transform(image, radius, points, ignore_zeros=False, preserve_shape=True): ''' transformed = lbp(image, radius, points, ignore_zeros=False, preserve_shape=True) Compute Linear Binary Pattern Transform The return value are the transformed pixel values **histogram** of feature counts, where position ``i`` corresponds to the number of pixels that had code ``i``. The codes are compressed so that impossible codes are not used. Therefore, this is the ``i``th feature, not just the feature with binary code ``i``. Parameters ---------- image : ndarray input image (2-D numpy ndarray) radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider ignore_zeros : boolean, optional whether to ignore zeros. Note that if you set this to ``True``, you will need to set ``preserve_shape`` to False. (default: False) preserve_shape : boolean, optional whether to return an array with the same shape as ``image``. (default: True) Returns ------- features : 1-D numpy ndarray histogram of features. See above for a caveat on the interpretation of these. References ---------- Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns Ojala, T. Pietikainen, M. Maenpaa, T. Lecture Notes in Computer Science (Springer) 2000, ISSU 1842, pages 404-420 ''' from ..interpolate import shift from mahotas.features import _lbp if ignore_zeros and preserve_shape: raise ValueError( 'mahotas.features.lbp_transform: *ignore_zeros* and *preserve_shape* cannot both be used together' ) image = np.asanyarray(image, dtype=np.float64) if image.ndim != 2: raise ValueError( 'mahotas.features.lbp_transform: This function is only defined for two dimensional images' ) if ignore_zeros: Y, X = np.nonzero(image) def select(im): return im[Y, X].ravel() else: select = np.ravel pixels = select(image) angles = np.linspace(0, 2 * np.pi, points + 1)[:-1] data = [] for dy, dx in zip(np.sin(angles), np.cos(angles)): data.append(select(shift(image, [radius * dy, radius * dx], order=1))) data = np.array(data) codes = (data > pixels).astype(np.int32) codes *= (2**np.arange(points)[:, np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) if preserve_shape: codes = codes.reshape(image.shape) return codes
def lbp(image, radius, points, ignore_zeros=False): ''' features = lbp(image, radius, points, ignore_zeros=False) Compute Linear Binary Patterns Parameters ---------- image : ndarray input image (2-D numpy ndarray) radius : number (integer or floating point) radius (in pixels) points : integer nr of points to consider ignore_zeros : boolean, optional whether to ignore zeros (default: False) Returns ------- features : 1-D numpy ndarray histogram of features Reference --------- Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns Ojala, T. Pietikainen, M. Maenpaa, T. LECTURE NOTES IN COMPUTER SCIENCE (Springer) 2000, ISSU 1842, pages 404-420 ''' from ..interpolate import shift from mahotas.features import _lbp if ignore_zeros: Y, X = np.nonzero(image) def select(im): return im[Y, X].ravel() pixels = image[Y, X].ravel() else: select = np.ravel pixels = image.ravel() image = image.astype(np.float64) angles = np.linspace(0, 2 * np.pi, points + 1)[:-1] data = [] for dy, dx in zip(np.sin(angles), np.cos(angles)): data.append(select(shift(image, [radius * dy, radius * dx], order=1))) data = np.array(data) codes = (data > pixels).astype(np.int32) codes *= (2**np.arange(points)[:, np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) final = fullhistogram(codes.astype(np.uint32)) codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) compressed = final[pivots[:len(final)]] compressed = np.concatenate( (compressed, [0] * (npivots - len(compressed)))) return compressed
def test_map(): assert len(set(_lbp.map(np.arange(256, dtype=np.uint32), 8))) == 36
def test_map(): assert len(set(_lbp.map(np.arange(256,dtype=np.uint32), 8))) == 36
def lddp(image, radius1, radius2, points, ignore_zeros=False, preserve_shape=True): """ Custom implementation of 2nd order local directional derivative pattern Originally obtained from mahotas.features.lbp_transform function. An inner and an outer radius with respect to a point, which is each image pixel are selected. Then, a set of points are obtained by interpolation on these radii, according to the number defined by *points* argument. Note that if, for example, 8 points are given, there are 8 points that are considered on the inner radius defined by equal angles starting from the central point and each one of them. If these two points (the origin, or the centre) and each point define a straight line, also 8 points on the same lines are considered for the outer radius. For reference see : Guo, Zhenhua, et al. "Local directional derivative pattern for rotation invariant texture classification." Neural Computing and Applications 21.8 (2012): 1893-1904. :param np.array image: numpy array input image :param int radius1: inner radius (in pixels) :param int radius2: outer radius (in pixels) :param int points: number of points to consider. It should be given regarding the inner radius, as the second set of points will be aligned to the ones lying in the inner circle. :return: lddp histogram """ from mahotas import interpolate from mahotas.features import _lbp from mahotas import histogram if ignore_zeros and preserve_shape: raise ValueError( 'mahotas.features.lbp_transform: *ignore_zeros* and *preserve_shape* cannot both be used together' ) image = np.asanyarray(image, dtype=np.float64) if image.ndim != 2: raise ValueError( 'mahotas.features.lbp_transform: This function is only defined for two dimensional images' ) if ignore_zeros: Y, X = np.nonzero(image) def select(im): return im[Y, X].ravel() else: select = np.ravel pixels = select(image) angles = np.linspace(0, 2 * np.pi, points + 1)[:-1] data1 = [] for dy, dx in zip(np.sin(angles), np.cos(angles)): data1.append( select( interpolate.shift(image, [radius1 * dy, radius1 * dx], order=1))) data1 = np.array(data1) data2 = [] for dy, dx in zip(np.sin(angles), np.cos(angles)): data2.append( select( interpolate.shift(image, [radius2 * dy, radius2 * dx], order=1))) data2 = np.array(data2) data = np.array(data2 + pixels - 2 * data1) codes = (data >= 0).astype(np.int32) codes *= (2**np.arange(points)[:, np.newaxis]) codes = codes.sum(0) codes = _lbp.map(codes.astype(np.uint32), points) if preserve_shape: codes = codes.reshape(image.shape) final = histogram.fullhistogram(codes.astype(np.uint32)) codes = np.arange(2**points, dtype=np.uint32) iters = codes.copy() codes = _lbp.map(codes.astype(np.uint32), points) pivots = (codes == iters) npivots = np.sum(pivots) compressed = final[pivots[:len(final)]] compressed = np.append(compressed, np.zeros(npivots - len(compressed))) return compressed