当前位置:   article > 正文

Matlab中的LBP算法源码和python中scikit-image库中的源码_vision.internal.inputvalidation.checkimagesize

vision.internal.inputvalidation.checkimagesize

参考文献:《Rotation Invariant Texture Classification using feature distributions

Multiresolution gray scale and rotation ivariant texture classification with local binary patterns

matlab中的源码

  1. function features = extractLBPFeatures(I,varargin)
  2. %extractLBPFeatures Extract LBP features.
  3. % features = extractLBPFeatures(I) extracts uniform local binary patterns
  4. % (LBP) from a grayscale image I and returns the features in
  5. % a 1-by-N vector. LBP features encode local texture information and can
  6. % be used for many tasks including classification, detection, and
  7. % recognition.
  8. %
  9. % The LBP feature length, N, is based on the image size and the parameter
  10. % values listed below. See the <a href="matlab:helpview(fullfile(docroot,'toolbox','vision','vision.map'),'lbpFeatureLength')" >documentation</a> for more information.
  11. %
  12. % [...] = extractLBPFeatures(..., Name, Value) specifies additional
  13. % name-value pairs described below. LBP algorithm parameters control how
  14. % local binary patterns are computed for each pixel in I. LBP histogram
  15. % parameters determine how the distribution of binary patterns is
  16. % aggregated over I to produce the output features.
  17. %
  18. % LBP algorithm parameters
  19. % ------------------------
  20. %
  21. % 'NumNeighbors' The number of neighbors used to compute the local binary
  22. % pattern for each pixel in I. The set of neighbors is
  23. % selected from a circularly symmetric pattern around each
  24. % pixel. Increase the number of neighbors to encode
  25. % greater detail around each pixel. Typical values are
  26. % between 4 and 24.
  27. %
  28. % Default: 8
  29. %
  30. % 'Radius' The radius, in pixels, of the circular pattern used to
  31. % select neighbors for each pixel in I. Increase the
  32. % radius to capture detail over a larger spatial scale.
  33. % Typical values range from 1 to 5.
  34. %
  35. % Default: 0
  36. %
  37. % 'Upright' A logical scalar. When set to true, the LBP features do
  38. % not encode rotation information. Set 'Upright' to false
  39. % when rotationally invariant features are required.
  40. %
  41. % Default: true
  42. %
  43. % 'Interpolation' Specify the interpolation method used to compute pixel
  44. % neighbors as 'Nearest' or 'Linear'. Use 'Nearest' for
  45. % faster computation at the cost of accuracy.
  46. %
  47. % Default: 'Linear'
  48. %
  49. % LBP histogram parameters
  50. % ------------------------
  51. %
  52. % 'CellSize' A 2-element vector that partitions I into
  53. % floor(size(I)./CellSize) non-overlapping cells.
  54. % Select larger cell sizes to collect information over
  55. % larger regions at the cost of loosing local detail.
  56. %
  57. % Default: size(I)
  58. %
  59. % 'Normalization' Specify the type of normalization applied to the LBP
  60. % histograms as 'L2' or 'None'. Select 'None' to apply a
  61. % custom normalization method as a post-processing step.
  62. %
  63. % Default: 'L2'
  64. %
  65. % Class Support
  66. % -------------
  67. % The input image I can be uint8, uint16, int16, double, single, or
  68. % logical, and it must be real and non-sparse.
  69. %
  70. % Notes
  71. % -----
  72. % This function extracts uniform local binary patterns. Uniform patterns
  73. % have at most two 1-to-0 or 0-to-1 bit transitions.
  74. %
  75. % Example - Differentiate images by texture using LBP features.
  76. % ---------------------------------------------------------------
  77. % % Read images that contain different textures.
  78. % brickWall = imread('bricks.jpg');
  79. % rotatedBrickWall = imread('bricksRotated.jpg');
  80. % carpet = imread('carpet.jpg');
  81. %
  82. % figure
  83. % imshow(brickWall)
  84. % title('Bricks')
  85. %
  86. % figure
  87. % imshow(rotatedBrickWall)
  88. % title('Rotated bricks')
  89. %
  90. % figure
  91. % imshow(carpet)
  92. % title('Carpet')
  93. %
  94. % % Extract LBP features to encode image texture information.
  95. % lbpBricks1 = extractLBPFeatures(brickWall,'Upright',false);
  96. % lbpBricks2 = extractLBPFeatures(rotatedBrickWall,'Upright',false);
  97. % lbpCarpet = extractLBPFeatures(carpet,'Upright',false);
  98. %
  99. % % Compute the squared error between the LBP features. This helps gauge
  100. % % the similarity between the LBP features.
  101. % brickVsBrick = (lbpBricks1 - lbpBricks2).^2;
  102. % brickVsCarpet = (lbpBricks1 - lbpCarpet).^2;
  103. %
  104. % % Visualize the squared error to compare bricks vs. bricks and bricks vs.
  105. % % carpet. The squared error is smaller when images have similar texture.
  106. % figure
  107. % bar([brickVsBrick; brickVsCarpet]', 'grouped')
  108. % title('Squared error of LBP Histograms')
  109. % xlabel('LBP Histogram Bins')
  110. % legend('Bricks vs Rotated Bricks', 'Bricks vs Carpet')
  111. %
  112. % See also extractHOGFeatures, extractFeatures, detectHarrisFeatures,
  113. % detectFASTFeatures, detectMinEigenFeatures, detectSURFFeatures,
  114. % detectMSERFeatures, detectBRISKFeatures
  115. % Copyright 2015 The MathWorks, Inc.
  116. %
  117. % References
  118. % ----------
  119. % Ojala, Timo, Matti Pietikainen, and Topi Maenpaa. "Multiresolution
  120. % gray-scale and rotation invariant texture classification with local
  121. % binary patterns." Pattern Analysis and Machine Intelligence, IEEE
  122. % Transactions on 24.7 (2002): 971-987.
  123. %#codegen
  124. if isempty(coder.target)
  125. params = parseInputs(I,varargin{:});
  126. lbpImpl = vision.internal.LBPImpl.getImpl(params);
  127. features = lbpImpl.extractLBPFeatures(I);
  128. else
  129. [numNeighbors, radius, interpolation, uniform, upright, cellSize,...
  130. normalization] = codegenParseInputs(I,varargin{:});
  131. features = vision.internal.LBPImpl.codegenExtractLBPFeatures(...
  132. I, numNeighbors, radius, interpolation, ...
  133. uniform, upright, cellSize, normalization);
  134. end
  135. % -------------------------------------------------------------------------
  136. function params = parseInputs(I, varargin)
  137. vision.internal.inputValidation.validateImage(I, 'I', 'grayscale');
  138. szI = size(I);
  139. parser = getInputParser();
  140. parser.parse(varargin{:});
  141. userInput = parser.Results;
  142. usingDefaultCellSize = ismember('CellSize', parser.UsingDefaults);
  143. if usingDefaultCellSize
  144. userInput.CellSize = szI; % cell size default is size(I)
  145. end
  146. [validInterpolation, validNormalization] = validate(...
  147. userInput.NumNeighbors, userInput.Radius, userInput.CellSize, ...
  148. userInput.Upright, userInput.Interpolation, userInput.Normalization);
  149. params = setParams(userInput, validInterpolation, validNormalization);
  150. crossCheckParams(szI, params.CellSize, params.Radius)
  151. % -------------------------------------------------------------------------
  152. function [numNeighbors, radius, interpolation, uniform, upright, ...
  153. cellSize, normalization] = codegenParseInputs(I, varargin)
  154. vision.internal.inputValidation.validateImage(I, 'I', 'grayscale');
  155. eml_invariant(eml_is_const(ismatrix(I)), eml_message('vision:dims:imageNot2D'));
  156. szI = size(I);
  157. pvPairs = struct( ...
  158. 'NumNeighbors', uint32(0), ...
  159. 'Radius', uint32(0), ...
  160. 'CellSize', uint32(0), ...
  161. 'Upright', uint32(0),...
  162. 'Interpolation', uint32(0),...
  163. 'Normalization', uint32(0));
  164. popt = struct( ...
  165. 'CaseSensitivity', false, ...
  166. 'StructExpand' , true, ...
  167. 'PartialMatching', true);
  168. defaults = getParamDefaults();
  169. optarg = eml_parse_parameter_inputs(pvPairs, popt, varargin{:});
  170. usingDefaultCellSize = ~optarg.CellSize;
  171. numNeighbors = eml_get_parameter_value(optarg.NumNeighbors, ...
  172. defaults.NumNeighbors, varargin{:});
  173. radius = eml_get_parameter_value(optarg.Radius, ...
  174. defaults.Radius, varargin{:});
  175. cellSize = eml_get_parameter_value(optarg.CellSize, ...
  176. defaults.CellSize, varargin{:});
  177. upright = eml_get_parameter_value(optarg.Upright, ...
  178. defaults.Upright, varargin{:});
  179. userInterpolation = eml_get_parameter_value(optarg.Interpolation, ...
  180. defaults.Interpolation, varargin{:});
  181. userNormalization = eml_get_parameter_value(optarg.Normalization, ...
  182. defaults.Normalization, varargin{:});
  183. % check const-ness before assigning to struct
  184. vision.internal.errorIfNotConst(numNeighbors, 'NumNeighbors');
  185. vision.internal.errorIfNotConst(radius, 'Radius');
  186. vision.internal.errorIfNotConst(userInterpolation, 'Interpolation');
  187. vision.internal.errorIfNotConst(userNormalization, 'Normalization');
  188. vision.internal.errorIfNotConst(upright, 'Upright');
  189. % check const-ness of size
  190. vision.internal.errorIfNotFixedSize(numNeighbors, 'NumNeighbors');
  191. vision.internal.errorIfNotFixedSize(radius, 'Radius');
  192. vision.internal.errorIfNotFixedSize(cellSize, 'CellSize');
  193. if usingDefaultCellSize
  194. cellSize = szI; % cell size default is size(I)
  195. end
  196. [interpolation, normalization] = validate(numNeighbors, radius, cellSize, ...
  197. upright, userInterpolation, userNormalization);
  198. numNeighbors = single(numNeighbors);
  199. radius = single(radius);
  200. cellSize = single(cellSize);
  201. upright = logical(upright);
  202. uniform = true;
  203. crossCheckParams(szI, cellSize, radius)
  204. % -------------------------------------------------------------------------
  205. function params = setParams(userInput, interpMethod, normMethod)
  206. params.NumNeighbors = single(userInput.NumNeighbors);
  207. params.Radius = single(userInput.Radius);
  208. params.CellSize = single(userInput.CellSize);
  209. params.Upright = logical(userInput.Upright);
  210. params.Interpolation = interpMethod;
  211. params.Normalization = normMethod;
  212. params.Uniform = true;
  213. params.UseLUT = false; % reset later based on other params
  214. % -------------------------------------------------------------------------
  215. function crossCheckParams(szI, cellSize, radius)
  216. crossCheckImageSizeAndCellSize(szI, cellSize);
  217. crossCheckImageSizeAndRadius(szI, radius);
  218. crossCheckCellSizeAndRadius(cellSize, radius);
  219. % -------------------------------------------------------------------------
  220. function [validInterpolation, validNormalization] = validate(numNeighbors, ...
  221. radius, cellSize, upright, interpolation, normalization)
  222. checkNumNeighbors(numNeighbors);
  223. checkRadius(radius);
  224. vision.internal.inputValidation.validateLogical(upright, 'Upright');
  225. checkCellSize(cellSize);
  226. validInterpolation = checkInterpolation(interpolation);
  227. validNormalization = checkNormalization(normalization);
  228. % -------------------------------------------------------------------------
  229. function checkNumNeighbors(n)
  230. vision.internal.errorIfNotFixedSize(n, 'NumNeighbors');
  231. validateattributes(n, {'numeric'}, ...
  232. {'integer', 'real', 'nonsparse', 'scalar', '>=', 2' '<=' 32'},...
  233. mfilename, 'NumNeighbors'); %#ok<*EMCA>
  234. % -------------------------------------------------------------------------
  235. function checkRadius(r)
  236. validateattributes(r, {'numeric'}, ...
  237. {'integer', 'real', 'nonsparse', 'scalar', '>=', 1},...
  238. mfilename, 'Radius');
  239. % -------------------------------------------------------------------------
  240. function str = checkInterpolation(method)
  241. str = validatestring(method, {'Nearest', 'Linear'},...
  242. mfilename, 'Interpolation');
  243. % -------------------------------------------------------------------------
  244. function str = checkNormalization(method)
  245. str = validatestring(method, {'L2', 'None'},...
  246. mfilename, 'Normalization');
  247. % -------------------------------------------------------------------------
  248. function checkCellSize(sz)
  249. validateattributes(sz, {'numeric'}, ...
  250. {'vector', 'numel', 2, 'positive', 'real', 'integer', 'nonsparse'},...
  251. mfilename, 'CellSize');
  252. % -------------------------------------------------------------------------
  253. function crossCheckCellSizeAndRadius(sz, r)
  254. coder.internal.errorIf(any(sz < (2*r + 1)),...
  255. 'vision:extractLBPFeatures:cellSizeLTRadius');
  256. % -------------------------------------------------------------------------
  257. function crossCheckImageSizeAndCellSize(imgSize, cellSize)
  258. coder.internal.errorIf(any(cellSize(:) > imgSize(:)), ...
  259. 'vision:extractLBPFeatures:imgSizeLTCellSize');
  260. % -------------------------------------------------------------------------
  261. function crossCheckImageSizeAndRadius(sz, r)
  262. coder.internal.errorIf(any(sz < (2*r + 1)),...
  263. 'vision:extractLBPFeatures:imgSizeLTRadius');
  264. % -------------------------------------------------------------------------
  265. function parser = getInputParser()
  266. persistent p; % cache parser for speed
  267. if isempty(p)
  268. defaults = getParamDefaults();
  269. p = inputParser();
  270. addParameter(p, 'NumNeighbors', defaults.NumNeighbors);
  271. addParameter(p, 'Radius', defaults.Radius);
  272. addParameter(p, 'Upright', defaults.Upright);
  273. addParameter(p, 'CellSize', defaults.CellSize);
  274. addParameter(p, 'Normalization', defaults.Normalization);
  275. addParameter(p, 'Interpolation', defaults.Interpolation);
  276. end
  277. parser = p;
  278. % -------------------------------------------------------------------------
  279. function defaults = getParamDefaults()
  280. defaults.NumNeighbors = single(8);
  281. defaults.Radius = single(1);
  282. defaults.Upright = true;
  283. defaults.CellSize = [3 3]; % default is size(I), but give values here to define dims/type
  284. defaults.Normalization = 'L2';
  285. defaults.Interpolation = 'Linear';

python scikit-image库中的LBP算法源码:

  1. #cython: cdivision=True
  2. #cython: boundscheck=False
  3. #cython: nonecheck=False
  4. #cython: wraparound=False
  5. import numpy as np
  6. cimport numpy as cnp
  7. from libc.math cimport sin, cos, abs
  8. from .._shared.interpolation cimport bilinear_interpolation, round
  9. from .._shared.transform cimport integrate
  10. cdef extern from "numpy/npy_math.h":
  11. double NAN "NPY_NAN"
  12. from .._shared.fused_numerics cimport np_anyint as any_int
  13. from .._shared.fused_numerics cimport np_real_numeric
  14. def _glcm_loop(any_int[:, ::1] image, double[:] distances,
  15. double[:] angles, Py_ssize_t levels,
  16. cnp.uint32_t[:, :, :, ::1] out):
  17. """Perform co-occurrence matrix accumulation.
  18. Parameters
  19. ----------
  20. image : ndarray
  21. Integer typed input image. Only positive valued images are supported.
  22. If type is other than uint8, the argument `levels` needs to be set.
  23. distances : ndarray
  24. List of pixel pair distance offsets.
  25. angles : ndarray
  26. List of pixel pair angles in radians.
  27. levels : int
  28. The input image should contain integers in [0, `levels`-1],
  29. where levels indicate the number of gray-levels counted
  30. (typically 256 for an 8-bit image).
  31. out : ndarray
  32. On input a 4D array of zeros, and on output it contains
  33. the results of the GLCM computation.
  34. """
  35. cdef:
  36. Py_ssize_t a_idx, d_idx, r, c, rows, cols, row, col, start_row,\
  37. end_row, start_col, end_col, offset_row, offset_col
  38. any_int i, j
  39. cnp.float64_t angle, distance
  40. with nogil:
  41. rows = image.shape[0]
  42. cols = image.shape[1]
  43. for a_idx in range(angles.shape[0]):
  44. angle = angles[a_idx]
  45. for d_idx in range(distances.shape[0]):
  46. distance = distances[d_idx]
  47. offset_row = round(sin(angle) * distance)
  48. offset_col = round(cos(angle) * distance)
  49. start_row = max(0, -offset_row)
  50. end_row = min(rows, rows - offset_row)
  51. start_col = max(0, -offset_col)
  52. end_col = min(cols, cols - offset_col)
  53. for r in range(start_row, end_row):
  54. for c in range(start_col, end_col):
  55. i = image[r, c]
  56. # compute the location of the offset pixel
  57. row = r + offset_row
  58. col = c + offset_col
  59. j = image[row, col]
  60. if 0 <= i < levels and 0 <= j < levels:
  61. out[i, j, d_idx, a_idx] += 1
  62. cdef inline int _bit_rotate_right(int value, int length) nogil:
  63. """Cyclic bit shift to the right.
  64. Parameters
  65. ----------
  66. value : int
  67. integer value to shift
  68. length : int
  69. number of bits of integer
  70. """
  71. return (value >> 1) | ((value & 1) << (length - 1))
  72. def _local_binary_pattern(double[:, ::1] image,
  73. int P, float R, char method=b'D'):
  74. """Gray scale and rotation invariant LBP (Local Binary Patterns).
  75. LBP is an invariant descriptor that can be used for texture classification.
  76. Parameters
  77. ----------
  78. image : (N, M) double array
  79. Graylevel image.
  80. P : int
  81. Number of circularly symmetric neighbour set points (quantization of
  82. the angular space).
  83. R : float
  84. Radius of circle (spatial resolution of the operator).
  85. method : {'D', 'R', 'U', 'N', 'V'}
  86. Method to determine the pattern.
  87. * 'D': 'default'
  88. * 'R': 'ror'
  89. * 'U': 'uniform'
  90. * 'N': 'nri_uniform'
  91. * 'V': 'var'
  92. Returns
  93. -------
  94. output : (N, M) array
  95. LBP image.
  96. """
  97. # texture weights
  98. cdef int[::1] weights = 2 ** np.arange(P, dtype=np.int32)
  99. # local position of texture elements
  100. rr = - R * np.sin(2 * np.pi * np.arange(P, dtype=np.double) / P)
  101. cc = R * np.cos(2 * np.pi * np.arange(P, dtype=np.double) / P)
  102. cdef double[::1] rp = np.round(rr, 5)
  103. cdef double[::1] cp = np.round(cc, 5)
  104. # pre-allocate arrays for computation
  105. cdef double[::1] texture = np.zeros(P, dtype=np.double)
  106. cdef signed char[::1] signed_texture = np.zeros(P, dtype=np.int8)
  107. cdef int[::1] rotation_chain = np.zeros(P, dtype=np.int32)
  108. output_shape = (image.shape[0], image.shape[1])
  109. cdef double[:, ::1] output = np.zeros(output_shape, dtype=np.double)
  110. cdef Py_ssize_t rows = image.shape[0]
  111. cdef Py_ssize_t cols = image.shape[1]
  112. cdef double lbp
  113. cdef Py_ssize_t r, c, changes, i
  114. cdef Py_ssize_t rot_index, n_ones
  115. cdef cnp.int8_t first_zero, first_one
  116. # To compute the variance features
  117. cdef double sum_, var_, texture_i
  118. with nogil:
  119. for r in range(image.shape[0]):
  120. for c in range(image.shape[1]):
  121. for i in range(P):
  122. bilinear_interpolation[cnp.float64_t, double, double](
  123. &image[0, 0], rows, cols, r + rp[i], c + cp[i],
  124. b'C', 0, &texture[i])
  125. # signed / thresholded texture
  126. for i in range(P):
  127. if texture[i] - image[r, c] >= 0:
  128. signed_texture[i] = 1
  129. else:
  130. signed_texture[i] = 0
  131. lbp = 0
  132. # if method == b'var':
  133. if method == b'V':
  134. # Compute the variance without passing from numpy.
  135. # Following the LBP paper, we're taking a biased estimate
  136. # of the variance (ddof=0)
  137. sum_ = 0.0
  138. var_ = 0.0
  139. for i in range(P):
  140. texture_i = texture[i]
  141. sum_ += texture_i
  142. var_ += texture_i * texture_i
  143. var_ = (var_ - (sum_ * sum_) / P) / P
  144. if var_ != 0:
  145. lbp = var_
  146. else:
  147. lbp = NAN
  148. # if method == b'uniform':
  149. elif method == b'U' or method == b'N':
  150. # determine number of 0 - 1 changes
  151. changes = 0
  152. for i in range(P - 1):
  153. changes += (signed_texture[i]
  154. - signed_texture[i + 1]) != 0
  155. if method == b'N':
  156. # Uniform local binary patterns are defined as patterns
  157. # with at most 2 value changes (from 0 to 1 or from 1 to
  158. # 0). Uniform patterns can be characterized by their
  159. # number `n_ones` of 1. The possible values for
  160. # `n_ones` range from 0 to P.
  161. #
  162. # Here is an example for P = 4:
  163. # n_ones=0: 0000
  164. # n_ones=1: 0001, 1000, 0100, 0010
  165. # n_ones=2: 0011, 1001, 1100, 0110
  166. # n_ones=3: 0111, 1011, 1101, 1110
  167. # n_ones=4: 1111
  168. #
  169. # For a pattern of size P there are 2 constant patterns
  170. # corresponding to n_ones=0 and n_ones=P. For each other
  171. # value of `n_ones` , i.e n_ones=[1..P-1], there are P
  172. # possible patterns which are related to each other
  173. # through circular permutations. The total number of
  174. # uniform patterns is thus (2 + P * (P - 1)).
  175. # Given any pattern (uniform or not) we must be able to
  176. # associate a unique code:
  177. #
  178. # 1. Constant patterns patterns (with n_ones=0 and
  179. # n_ones=P) and non uniform patterns are given fixed
  180. # code values.
  181. #
  182. # 2. Other uniform patterns are indexed considering the
  183. # value of n_ones, and an index called 'rot_index'
  184. # reprenting the number of circular right shifts
  185. # required to obtain the pattern starting from a
  186. # reference position (corresponding to all zeros stacked
  187. # on the right). This number of rotations (or circular
  188. # right shifts) 'rot_index' is efficiently computed by
  189. # considering the positions of the first 1 and the first
  190. # 0 found in the pattern.
  191. if changes <= 2:
  192. # We have a uniform pattern
  193. n_ones = 0 # determines the number of ones
  194. first_one = -1 # position was the first one
  195. first_zero = -1 # position of the first zero
  196. for i in range(P):
  197. if signed_texture[i]:
  198. n_ones += 1
  199. if first_one == -1:
  200. first_one = i
  201. else:
  202. if first_zero == -1:
  203. first_zero = i
  204. if n_ones == 0:
  205. lbp = 0
  206. elif n_ones == P:
  207. lbp = P * (P - 1) + 1
  208. else:
  209. if first_one == 0:
  210. rot_index = n_ones - first_zero
  211. else:
  212. rot_index = P - first_one
  213. lbp = 1 + (n_ones - 1) * P + rot_index
  214. else: # changes > 2
  215. lbp = P * (P - 1) + 2
  216. else: # method != 'N'
  217. if changes <= 2:
  218. for i in range(P):
  219. lbp += signed_texture[i]
  220. else:
  221. lbp = P + 1
  222. else:
  223. # method == b'default'
  224. for i in range(P):
  225. lbp += signed_texture[i] * weights[i]
  226. # method == b'ror'
  227. if method == b'R':
  228. # shift LBP P times to the right and get minimum value
  229. rotation_chain[0] = <int>lbp
  230. for i in range(1, P):
  231. rotation_chain[i] = \
  232. _bit_rotate_right(rotation_chain[i - 1], P)
  233. lbp = rotation_chain[0]
  234. for i in range(1, P):
  235. lbp = min(lbp, rotation_chain[i])
  236. output[r, c] = lbp
  237. return np.asarray(output)
  238. # Constant values that are used by `_multiblock_lbp` function.
  239. # Values represent offsets of neighbour rectangles relative to central one.
  240. # It has order starting from top left and going clockwise.
  241. cdef:
  242. Py_ssize_t[::1] mlbp_r_offsets = np.asarray([-1, -1, -1, 0, 1, 1, 1, 0], dtype=np.intp)
  243. Py_ssize_t[::1] mlbp_c_offsets = np.asarray([-1, 0, 1, 1, 1, 0, -1, -1], dtype=np.intp)
  244. cpdef int _multiblock_lbp(float[:, ::1] int_image,
  245. Py_ssize_t r,
  246. Py_ssize_t c,
  247. Py_ssize_t width,
  248. Py_ssize_t height) nogil:
  249. """Multi-block local binary pattern (MB-LBP) [1]_.
  250. Parameters
  251. ----------
  252. int_image : (N, M) float array
  253. Integral image.
  254. r : int
  255. Row-coordinate of top left corner of a rectangle containing feature.
  256. c : int
  257. Column-coordinate of top left corner of a rectangle containing feature.
  258. width : int
  259. Width of one of 9 equal rectangles that will be used to compute
  260. a feature.
  261. height : int
  262. Height of one of 9 equal rectangles that will be used to compute
  263. a feature.
  264. Returns
  265. -------
  266. output : int
  267. 8-bit MB-LBP feature descriptor.
  268. References
  269. ----------
  270. .. [1] Face Detection Based on Multi-Block LBP
  271. Representation. Lun Zhang, Rufeng Chu, Shiming Xiang, Shengcai Liao,
  272. Stan Z. Li
  273. http://www.cbsr.ia.ac.cn/users/scliao/papers/Zhang-ICB07-MBLBP.pdf
  274. """
  275. cdef:
  276. # Top-left coordinates of central rectangle.
  277. Py_ssize_t central_rect_r = r + height
  278. Py_ssize_t central_rect_c = c + width
  279. Py_ssize_t r_shift = height - 1
  280. Py_ssize_t c_shift = width - 1
  281. Py_ssize_t current_rect_r, current_rect_c
  282. Py_ssize_t element_num, i
  283. double current_rect_val
  284. int has_greater_value
  285. int lbp_code = 0
  286. # Sum of intensity values of central rectangle.
  287. cdef float central_rect_val = integrate(int_image, central_rect_r, central_rect_c,
  288. central_rect_r + r_shift,
  289. central_rect_c + c_shift)
  290. for element_num in range(8):
  291. current_rect_r = central_rect_r + mlbp_r_offsets[element_num]*height
  292. current_rect_c = central_rect_c + mlbp_c_offsets[element_num]*width
  293. current_rect_val = integrate(int_image, current_rect_r, current_rect_c,
  294. current_rect_r + r_shift,
  295. current_rect_c + c_shift)
  296. has_greater_value = current_rect_val >= central_rect_val
  297. # If current rectangle's intensity value is bigger
  298. # make corresponding bit to 1.
  299. lbp_code |= has_greater_value << (7 - element_num)
  300. return lbp_code

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/898942
推荐阅读
相关标签
  

闽ICP备14008679号