scikit-image
160 строк · 5.5 Кб
1# cython: cdivision=True
2# cython: boundscheck=False
3# cython: wraparound=False
4
5import numpy as np
6cimport numpy as cnp
7
8from .._shared.fused_numerics cimport np_floats
9cnp.import_array()
10
11
12cdef np_floats cell_hog(np_floats[:, ::1] magnitude,
13np_floats[:, ::1] orientation,
14np_floats orientation_start, np_floats orientation_end,
15int cell_columns, int cell_rows,
16int column_index, int row_index,
17int size_columns, int size_rows,
18int range_rows_start, int range_rows_stop,
19int range_columns_start, int range_columns_stop) noexcept nogil:
20"""Calculation of the cell's HOG value
21
22Parameters
23----------
24magnitude : ndarray
25The gradient magnitudes of the pixels.
26orientation : ndarray
27Lookup table for orientations.
28orientation_start : float
29Orientation range start.
30orientation_end : float
31Orientation range end.
32cell_columns : int
33Pixels per cell (rows).
34cell_rows : int
35Pixels per cell (columns).
36column_index : int
37Block column index.
38row_index : int
39Block row index.
40size_columns : int
41Number of columns.
42size_rows : int
43Number of rows.
44range_rows_start : int
45Start row of cell.
46range_rows_stop : int
47Stop row of cell.
48range_columns_start : int
49Start column of cell.
50range_columns_stop : int
51Stop column of cell
52
53Returns
54-------
55total : float
56The total HOG value.
57"""
58cdef int cell_column, cell_row, cell_row_index, cell_column_index
59cdef cnp.float32_t total = 0.
60
61for cell_row in range(range_rows_start, range_rows_stop):
62cell_row_index = row_index + cell_row
63if (cell_row_index < 0 or cell_row_index >= size_rows):
64continue
65
66for cell_column in range(range_columns_start, range_columns_stop):
67cell_column_index = column_index + cell_column
68if (cell_column_index < 0 or cell_column_index >= size_columns
69or orientation[cell_row_index, cell_column_index]
70>= orientation_start
71or orientation[cell_row_index, cell_column_index]
72< orientation_end):
73continue
74
75total += magnitude[cell_row_index, cell_column_index]
76
77return total / (cell_rows * cell_columns)
78
79
80def hog_histograms(np_floats[:, ::1] gradient_columns,
81np_floats[:, ::1] gradient_rows,
82int cell_columns, int cell_rows,
83int size_columns, int size_rows,
84int number_of_cells_columns, int number_of_cells_rows,
85int number_of_orientations,
86np_floats[:, :, ::1] orientation_histogram):
87"""Extract Histogram of Oriented Gradients (HOG) for a given image.
88
89Parameters
90----------
91gradient_columns : ndarray
92First order image gradients (rows).
93gradient_rows : ndarray
94First order image gradients (columns).
95cell_columns : int
96Pixels per cell (rows).
97cell_rows : int
98Pixels per cell (columns).
99size_columns : int
100Number of columns.
101size_rows : int
102Number of rows.
103number_of_cells_columns : int
104Number of cells (rows).
105number_of_cells_rows : int
106Number of cells (columns).
107number_of_orientations : int
108Number of orientation bins.
109orientation_histogram : ndarray
110The histogram array which is modified in place.
111"""
112
113cdef np_floats[:, ::1] magnitude = np.hypot(gradient_columns,
114gradient_rows)
115cdef np_floats[:, ::1] orientation = \
116np.rad2deg(np.arctan2(gradient_rows, gradient_columns)) % 180
117cdef int i, c, r, r_i, c_i, cc, cr, c_0, r_0, \
118range_rows_start, range_rows_stop, \
119range_columns_start, range_columns_stop
120cdef np_floats orientation_start, orientation_end, \
121number_of_orientations_per_180
122
123r_0 = cell_rows / 2
124c_0 = cell_columns / 2
125cc = cell_rows * number_of_cells_rows
126cr = cell_columns * number_of_cells_columns
127range_rows_stop = (cell_rows + 1) / 2
128range_rows_start = -(cell_rows / 2)
129range_columns_stop = (cell_columns + 1) / 2
130range_columns_start = -(cell_columns / 2)
131number_of_orientations_per_180 = 180. / number_of_orientations
132
133with nogil:
134# compute orientations integral images
135for i in range(number_of_orientations):
136# isolate orientations in this range
137orientation_start = number_of_orientations_per_180 * (i + 1)
138orientation_end = number_of_orientations_per_180 * i
139c = c_0
140r = r_0
141r_i = 0
142c_i = 0
143
144while r < cc:
145c_i = 0
146c = c_0
147
148while c < cr:
149orientation_histogram[r_i, c_i, i] = \
150cell_hog(magnitude, orientation,
151orientation_start, orientation_end,
152cell_columns, cell_rows, c, r,
153size_columns, size_rows,
154range_rows_start, range_rows_stop,
155range_columns_start, range_columns_stop)
156c_i += 1
157c += cell_columns
158
159r_i += 1
160r += cell_rows
161