mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-05 14:44:58 +08:00
MBLBP optimized by taking out constants definition out of function. Visualization function of MBLBP now supports colors and opacity. Examples are updated.
This commit is contained in:
@@ -7,18 +7,18 @@ In this example, we will see how to compute the multi-block
|
||||
local binary pattern at a specified image and how to visualize it.
|
||||
|
||||
The features are calculated in a way similar to local binary
|
||||
patterns, except that block summed up pixel values
|
||||
patterns, except that summed up pixel values
|
||||
rather than pixel values are used.
|
||||
|
||||
`MB-LBP` is an extension of LBP that can be computed on any
|
||||
scales in a constant time using integral image. It consists of
|
||||
scale in a constant time using integral image. It consists of
|
||||
`9` equal-sized rectangles. They are used to compute a feature.
|
||||
Sum of pixels' intensity values in each of them are compared
|
||||
to the central rectangle and depending on comparison result,
|
||||
the feature descriptor is computed.
|
||||
|
||||
We will start with a simple image that we will generate by our
|
||||
own to show how the `MB-LBP` works. We will create a `(9, 9)`
|
||||
We will start with a simple image that we will generate
|
||||
to show how the `MB-LBP` works. We will create a `(9, 9)`
|
||||
rectangle with and divide it into `9` blocks. After this
|
||||
we will apply `MB-LBP` on it.
|
||||
|
||||
@@ -55,10 +55,8 @@ print(lbp_code == correct_answer)
|
||||
"""
|
||||
Now let's apply the operator to a real image and see how the visualization works.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from skimage.feature import (multiblock_local_binary_pattern,
|
||||
visualize_multiblock_lbp)
|
||||
draw_multiblock_lbp)
|
||||
from skimage.util import img_as_float
|
||||
from skimage.transform import integral_image
|
||||
from skimage import data
|
||||
@@ -71,8 +69,8 @@ int_img = integral_image(test_img)
|
||||
|
||||
lbp_code = multiblock_local_binary_pattern(int_img, 0, 0, 90, 90)
|
||||
|
||||
img = visualize_multiblock_lbp(test_img, 0, 0, 90, 90,
|
||||
lbp_code=lbp_code)
|
||||
img = draw_multiblock_lbp(test_img, 0, 0, 90, 90,
|
||||
lbp_code=lbp_code, alpha=0.5)
|
||||
|
||||
|
||||
plt.imshow(img, interpolation='nearest')
|
||||
|
||||
@@ -3,7 +3,7 @@ from ._daisy import daisy
|
||||
from ._hog import hog
|
||||
from .texture import (greycomatrix, greycoprops,
|
||||
local_binary_pattern,
|
||||
visualize_multiblock_lbp)
|
||||
draw_multiblock_lbp)
|
||||
|
||||
from ._texture import multiblock_local_binary_pattern
|
||||
from .peak import peak_local_max
|
||||
@@ -30,7 +30,7 @@ __all__ = ['canny',
|
||||
'greycoprops',
|
||||
'local_binary_pattern',
|
||||
'multiblock_local_binary_pattern',
|
||||
'visualize_multiblock_lbp',
|
||||
'draw_multiblock_lbp',
|
||||
'peak_local_max',
|
||||
'structure_tensor',
|
||||
'structure_tensor_eigvals',
|
||||
|
||||
@@ -266,35 +266,9 @@ def _local_binary_pattern(double[:, ::1] image,
|
||||
return np.asarray(output)
|
||||
|
||||
|
||||
cdef inline Py_ssize_t _clip(Py_ssize_t x, Py_ssize_t low,
|
||||
Py_ssize_t high) nogil:
|
||||
"""Clips coordinate between high and low.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : int
|
||||
Coordinate to be clipped.
|
||||
low : int
|
||||
The lower bound.
|
||||
high : int
|
||||
The higher bound.
|
||||
|
||||
Returns
|
||||
-------
|
||||
x : int
|
||||
`x` clipped between `high` and `low`.
|
||||
"""
|
||||
|
||||
if(x > high):
|
||||
return high
|
||||
if(x < low):
|
||||
return low
|
||||
return x
|
||||
|
||||
|
||||
cdef inline cnp.double_t _integ(
|
||||
cnp.double_t[:, ::1] img, Py_ssize_t r0, Py_ssize_t c0,
|
||||
Py_ssize_t r1, Py_ssize_t c1) nogil:
|
||||
cdef inline cnp.double_t _integ(cnp.double_t[:, ::1] img,
|
||||
Py_ssize_t r0, Py_ssize_t c0,
|
||||
Py_ssize_t r1, Py_ssize_t c1) nogil:
|
||||
"""Integrate over the integral image in the given window
|
||||
|
||||
This method was created so that `multiblock_local_binary_pattern`
|
||||
@@ -319,12 +293,6 @@ cdef inline cnp.double_t _integ(
|
||||
The integral over the given window.
|
||||
"""
|
||||
|
||||
r = _clip(r0, 0, img.shape[0] - 1)
|
||||
c = _clip(c0, 0, img.shape[1] - 1)
|
||||
|
||||
r2 = _clip(r1, 0, img.shape[0] - 1)
|
||||
c2 = _clip(c1, 0, img.shape[1] - 1)
|
||||
|
||||
cdef cnp.double_t ans = img[r1, c1]
|
||||
|
||||
if (r0 >= 1) and (c0 >= 1):
|
||||
@@ -339,6 +307,14 @@ cdef inline cnp.double_t _integ(
|
||||
return ans
|
||||
|
||||
|
||||
# Constant values that are used by `multiblock_local_binary_pattern` function.
|
||||
# These values are taken out for performance improvement.
|
||||
# Values represent offsets of neighbour rectangles relative to central one.
|
||||
# It has order starting from top left and going clockwise.
|
||||
cdef:
|
||||
Py_ssize_t[::1] mlbp_x_offsets = np.asarray([-1, 0, 1, 1, 1, 0, -1, -1])
|
||||
Py_ssize_t[::1] mlbp_y_offsets = np.asarray([-1, -1, -1, 0, 1, 1, 1, 0])
|
||||
|
||||
def multiblock_local_binary_pattern(cnp.double_t[:, ::1] int_image,
|
||||
Py_ssize_t x,
|
||||
Py_ssize_t y,
|
||||
@@ -347,11 +323,11 @@ def multiblock_local_binary_pattern(cnp.double_t[:, ::1] int_image,
|
||||
"""Multi-block local binary pattern.
|
||||
|
||||
The features are calculated in a way similar to local binary
|
||||
patterns, except that block summed up pixel values
|
||||
patterns, except that summed up pixel values
|
||||
rather than pixel values are used.
|
||||
|
||||
MB-LBP is an extension of LBP that can be computed on any
|
||||
scales in a constant time using integral image. It consists of
|
||||
scale in a constant time using integral image. It consists of
|
||||
9 equal-sized rectangles. They are used to compute a feature.
|
||||
Sum of pixels' intensity values in each of them are compared
|
||||
to the central rectangle and depending on comparison result,
|
||||
@@ -397,13 +373,7 @@ def multiblock_local_binary_pattern(cnp.double_t[:, ::1] int_image,
|
||||
central_rect_y + height - 1,
|
||||
central_rect_x + width - 1)
|
||||
|
||||
#print central_rect_x, central_rect_y
|
||||
|
||||
# Offsets of neighbour rectangles relative to central one.
|
||||
# It has order starting from top left and going clockwise
|
||||
cdef:
|
||||
Py_ssize_t *x_offsets = [-1, 0, 1, 1, 1, 0, -1, -1]
|
||||
Py_ssize_t *y_offsets = [-1, -1, -1, 0, 1, 1, 1, 0]
|
||||
Py_ssize_t element_num, offset_x, offset_y
|
||||
Py_ssize_t current_rect_x, current_rect_y
|
||||
double current_rect_val
|
||||
@@ -412,8 +382,8 @@ def multiblock_local_binary_pattern(cnp.double_t[:, ::1] int_image,
|
||||
|
||||
for element_num in range(8):
|
||||
|
||||
offset_x = x_offsets[element_num]
|
||||
offset_y = y_offsets[element_num]
|
||||
offset_x = mlbp_x_offsets[element_num]
|
||||
offset_y = mlbp_y_offsets[element_num]
|
||||
|
||||
|
||||
current_rect_x = central_rect_x + offset_x * width
|
||||
|
||||
+36
-14
@@ -294,7 +294,16 @@ def local_binary_pattern(image, P, R, method='default'):
|
||||
return output
|
||||
|
||||
|
||||
def visualize_multiblock_lbp(img, x, y, width, height, lbp_code=0):
|
||||
def draw_multiblock_lbp(img,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
lbp_code=0,
|
||||
color_greater_block=[1, 1, 1],
|
||||
color_less_block=[0, 0.69, 0.96],
|
||||
alpha=0.5
|
||||
):
|
||||
"""Multi-block local binary pattern visualization.
|
||||
|
||||
MB-LBP is an extension of LBP that can be computed on many
|
||||
@@ -326,11 +335,24 @@ def visualize_multiblock_lbp(img, x, y, width, height, lbp_code=0):
|
||||
lbp_code : int
|
||||
The descriptor of feature to visualize. If not provided,
|
||||
the descriptor with 0 value will be used.
|
||||
color_greater_block : list of 3 floats
|
||||
Floats specifying the color for the block that
|
||||
has greater intensity value. They should be
|
||||
in the range [0, 1]. Corresponding values define
|
||||
(R, G, B) values. Default value is white [1, 1, 1].
|
||||
color_greater_block : list of 3 floats
|
||||
Floats specifying the color for the block that
|
||||
has greater intensity value. They should be
|
||||
in the range [0, 1]. Corresponding values define
|
||||
(R, G, B) values. Default value is cyan [0, 0.69, 0.96].
|
||||
alpha : float
|
||||
Value in the range [0, 1] that specifies opacity of
|
||||
visualization. 1 - fully transparent, 0 - opaque.
|
||||
|
||||
Returns
|
||||
-------
|
||||
output :
|
||||
Float image with visualization.
|
||||
output : ndarray of float
|
||||
Image with visualization.
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -343,26 +365,26 @@ def visualize_multiblock_lbp(img, x, y, width, height, lbp_code=0):
|
||||
# Default colors for regions.
|
||||
# White is for the blocks that are brighter.
|
||||
# Cyan is for the blocks that has less intensity.
|
||||
color_greater_block = np.asarray([1, 1, 1], dtype='float64')
|
||||
color_less_block = np.asarray([0, 0.69, 0.96], dtype='float64')
|
||||
color_greater_block = np.asarray(color_greater_block, dtype='float64')
|
||||
color_less_block = np.asarray(color_less_block, dtype='float64')
|
||||
|
||||
# Copy array to avoid the changes to the original one
|
||||
# Copy array to avoid the changes to the original one.
|
||||
output = np.copy(img)
|
||||
|
||||
# As the visualization uses RGB color we need 3 bands.
|
||||
if len(img.shape) < 3:
|
||||
output = np.dstack((img,) * 3)
|
||||
|
||||
# Colors are specified in floats
|
||||
# Colors are specified in floats.
|
||||
output = img_as_float(output)
|
||||
|
||||
# Offsets of neighbour rectangles relative to central one.
|
||||
# It has order starting from top left and going clockwise
|
||||
# It has order starting from top left and going clockwise.
|
||||
neighbour_rect_offsets = ((-1, -1), (0, -1), (1, -1),
|
||||
(1, 0), (1, 1), (0, 1),
|
||||
(-1, 1), (-1, 0))
|
||||
|
||||
# Top-left coordinates of central rectangle
|
||||
# Top-left coordinates of central rectangle.
|
||||
central_rect_x = x + width
|
||||
central_rect_y = y + height
|
||||
|
||||
@@ -375,14 +397,14 @@ def visualize_multiblock_lbp(img, x, y, width, height, lbp_code=0):
|
||||
|
||||
has_greater_value = lbp_code & (1 << (7-element_num))
|
||||
|
||||
# Mix-in the visualization colors
|
||||
# Mix-in the visualization colors.
|
||||
if has_greater_value:
|
||||
output[curr_y:curr_y+height, curr_x:curr_x+width] = \
|
||||
0.5 * output[curr_y:curr_y+height, curr_x:curr_x+width] \
|
||||
+ 0.5 * color_greater_block
|
||||
(1-alpha) * output[curr_y:curr_y+height, curr_x:curr_x+width] \
|
||||
+ alpha * color_greater_block
|
||||
else:
|
||||
output[curr_y:curr_y+height, curr_x:curr_x+width] = \
|
||||
0.5 * output[curr_y:curr_y+height, curr_x:curr_x+width] \
|
||||
+ 0.5 * color_less_block
|
||||
(1-alpha) * output[curr_y:curr_y+height, curr_x:curr_x+width] \
|
||||
+ alpha * color_less_block
|
||||
|
||||
return output
|
||||
|
||||
Reference in New Issue
Block a user