From bea9886a12e329ba5eef139e6a8caeafa1b42f7e Mon Sep 17 00:00:00 2001 From: Ivo Flipse Date: Thu, 18 Jun 2015 22:01:44 +0200 Subject: [PATCH 1/4] I noticed that cy+cy and cx+cx was repeated in the inner-most loop as well --- skimage/feature/_hog.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/skimage/feature/_hog.py b/skimage/feature/_hog.py index a66e5e4e..743597b0 100644 --- a/skimage/feature/_hog.py +++ b/skimage/feature/_hog.py @@ -128,11 +128,13 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8), dx_arr = radius * np.cos(orientations_arr / orientations_arr * np.pi) dy_arr = radius * np.sin(orientations_arr / orientations_arr * np.pi) + cc = cy + cy + cr = cx + cx hog_image = np.zeros((sy, sx), dtype=float) for x in range(n_cellsx): for y in range(n_cellsy): for o, dx, dy in zip(orientations_arr, dx_arr, dy_arr): - centre = tuple([y * cy + cy // 2, x * cx + cx // 2]) + centre = tuple([y * cc // 2, x * cr // 2]) rr, cc = draw.line(int(centre[0] - dx), int(centre[1] + dy), From 3d85503472ad3e27071b9766458184d242bc1ff2 Mon Sep 17 00:00:00 2001 From: Ivo Flipse Date: Thu, 18 Jun 2015 22:03:21 +0200 Subject: [PATCH 2/4] Renamed x to rows and y to columns, though I might have still missed it in some spots. Indented the long if statements and put continue on a new line Precomputed the range start and stop values Defined additional variables --- skimage/feature/_hoghistogram.pyx | 52 +++++++++++++++++-------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/skimage/feature/_hoghistogram.pyx b/skimage/feature/_hoghistogram.pyx index 6366e070..bd304c64 100644 --- a/skimage/feature/_hoghistogram.pyx +++ b/skimage/feature/_hoghistogram.pyx @@ -24,9 +24,9 @@ cdef float cell_hog(cnp.float64_t[:, :] magnitude, orientation_end : float Orientation range end. cell_columns : int - Pixels per cell (x). + Pixels per cell (rows). cell_rows : int - Pixels per cell (y). + Pixels per cell (columns). column_index : int Block column index. row_index : int @@ -41,21 +41,29 @@ cdef float cell_hog(cnp.float64_t[:, :] magnitude, total : float The total HOG value. """ - cdef int cell_column, cell_row + cdef int cell_column, cell_row, cell_row_index, cell_column_index, \ + range_columns_start, range_columns_stop, range_rows_start, \ + range_rows_stop + + range_rows_stop = cell_rows/2 + range_rows_start = -range_rows_stop + range_columns_stop = cell_columns/2 + range_columns_start = -range_columns_stop cdef float total = 0. - for cell_row in range(-cell_rows/2, cell_rows/2): + for cell_row in range(range_rows_start, range_rows_stop): cell_row_index = row_index + cell_row if (cell_row_index < 0 or cell_row_index >= size_rows): continue - for cell_column in range(-cell_columns/2, cell_columns/2): + for cell_column in range(range_columns_start, range_columns_stop): cell_column_index = column_index + cell_column if (cell_column_index < 0 or cell_column_index >= size_columns - or orientation[cell_row_index, cell_column_index] + or orientation[cell_row_index, cell_column_index] >= orientation_start - or orientation[cell_row_index, cell_column_index] - < orientation_end): continue + or orientation[cell_row_index, cell_column_index] + < orientation_end): + continue total += magnitude[cell_row_index, cell_column_index] @@ -73,21 +81,21 @@ def hog_histograms(cnp.float64_t[:, :] gradient_columns, Parameters ---------- gradient_columns : ndarray - First order image gradients (x). + First order image gradients (rows). gradient_rows : ndarray - First order image gradients (y). + First order image gradients (columns). cell_columns : int - Pixels per cell (x). + Pixels per cell (rows). cell_rows : int - Pixels per cell (y). + Pixels per cell (columns). size_columns : int Number of columns. size_rows : int Number of rows. number_of_cells_columns : int - Number of cells (x). + Number of cells (rows). number_of_cells_rows : int - Number of cells (y). + Number of cells (columns). number_of_orientations : int Number of orientation bins. orientation_histogram : ndarray @@ -98,14 +106,14 @@ def hog_histograms(cnp.float64_t[:, :] gradient_columns, gradient_rows) cdef cnp.float64_t[:, :] orientation = \ np.arctan2(gradient_rows, gradient_columns) * (180 / np.pi) % 180 - cdef int i, x, y, o, yi, xi, cy1, cy2, cx1, cx2 - cdef float orientation_start, orientation_end + cdef int i, x, y, o, yi, xi, cc, cr, x0, y0 + cdef float orientation_start, orientation_end, \ + number_of_orientations_per_180 x0 = cell_columns / 2 y0 = cell_rows / 2 - cy2 = cell_rows * number_of_cells_rows - cx2 = cell_columns * number_of_cells_columns - + cc = cell_rows * number_of_cells_rows + cr = cell_columns * number_of_cells_columns number_of_orientations_per_180 = 180. / number_of_orientations # compute orientations integral images @@ -113,17 +121,16 @@ def hog_histograms(cnp.float64_t[:, :] gradient_columns, # isolate orientations in this range orientation_start = number_of_orientations_per_180 * (i + 1) orientation_end = number_of_orientations_per_180 * i - x = x0 y = y0 yi = 0 xi = 0 - while y < cy2: + while y < cc: xi = 0 x = x0 - while x < cx2: + while x < cr: orientation_histogram[yi, xi, i] = cell_hog(magnitude, orientation, orientation_start, orientation_end, cell_columns, cell_rows, x, y, size_columns, size_rows) @@ -132,4 +139,3 @@ def hog_histograms(cnp.float64_t[:, :] gradient_columns, yi += 1 y += cell_rows - From 2500c21b12a7184da4bb14d5b4ea0e47f8e9ab4a Mon Sep 17 00:00:00 2001 From: Ivo Flipse Date: Thu, 18 Jun 2015 22:07:28 +0200 Subject: [PATCH 3/4] Converted orientation and magnitude to typed memory view. Also changed gradient_columns and gradient_rows, hopefully in the right way. --- skimage/feature/_hoghistogram.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/feature/_hoghistogram.pyx b/skimage/feature/_hoghistogram.pyx index bd304c64..9731251b 100644 --- a/skimage/feature/_hoghistogram.pyx +++ b/skimage/feature/_hoghistogram.pyx @@ -5,8 +5,8 @@ import numpy as np cimport numpy as cnp -cdef float cell_hog(cnp.float64_t[:, :] magnitude, - cnp.float64_t[:, :] orientation, +cdef float cell_hog(double[:, ::1] magnitude, + double[:, ::1] orientation, float orientation_start, float orientation_end, int cell_columns, int cell_rows, int column_index, int row_index, @@ -69,8 +69,8 @@ cdef float cell_hog(cnp.float64_t[:, :] magnitude, return total -def hog_histograms(cnp.float64_t[:, :] gradient_columns, - cnp.float64_t[:, :] gradient_rows, +def hog_histograms(double[:, ::1] gradient_columns, + double[:, ::1] gradient_rows, int cell_columns, int cell_rows, int size_columns, int size_rows, int number_of_cells_columns, int number_of_cells_rows, @@ -102,9 +102,9 @@ def hog_histograms(cnp.float64_t[:, :] gradient_columns, The histogram array which is modified in place. """ - cdef cnp.float64_t[:, :] magnitude = np.hypot(gradient_columns, + cdef double[:, ::1] magnitude = np.hypot(gradient_columns, gradient_rows) - cdef cnp.float64_t[:, :] orientation = \ + cdef double[:, ::1] orientation = \ np.arctan2(gradient_rows, gradient_columns) * (180 / np.pi) % 180 cdef int i, x, y, o, yi, xi, cc, cr, x0, y0 cdef float orientation_start, orientation_end, \ From 167c8eeeb6d67a457c87caa414fc35adad73e4dd Mon Sep 17 00:00:00 2001 From: Ivo Flipse Date: Thu, 18 Jun 2015 22:08:34 +0200 Subject: [PATCH 4/4] I hadn't realized when I changed orientations to an array, that its actually just an int and the original code said range(orientations), so I changed it to np.arange(orientations). Hopefully the tests will now pass again --- skimage/feature/_hog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/feature/_hog.py b/skimage/feature/_hog.py index 743597b0..64bb1221 100644 --- a/skimage/feature/_hog.py +++ b/skimage/feature/_hog.py @@ -124,7 +124,7 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8), from .. import draw radius = min(cx, cy) // 2 - 1 - orientations_arr = np.array(orientations) + orientations_arr = np.arange(orientations) dx_arr = radius * np.cos(orientations_arr / orientations_arr * np.pi) dy_arr = radius * np.sin(orientations_arr / orientations_arr * np.pi)