Merge pull request #4 from ClinicalGraphics/fasthog

I feel I have the easy job here!
This commit is contained in:
Tim Sheerman-Chase
2015-06-16 09:05:35 +01:00
2 changed files with 70 additions and 68 deletions
+3 -6
View File
@@ -1,8 +1,8 @@
import numpy as np
from scipy.ndimage import uniform_filter
from .._shared.utils import assert_nD
from . import _hoghistogram
def hog(image, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(3, 3), visualise=False, normalise=False):
"""Extract Histogram of Oriented Gradients (HOG) for a given image.
@@ -103,9 +103,6 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
cell are used to vote into the orientation histogram.
"""
magnitude = np.hypot(gx, gy)
orientation = np.arctan2(gy, gx) * (180 / np.pi) % 180
sy, sx = image.shape
cx, cy = pixels_per_cell
bx, by = cells_per_block
@@ -116,8 +113,8 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
# compute orientations integral images
orientation_histogram = np.zeros((n_cellsy, n_cellsx, orientations))
_hoghistogram.HogHistograms(gx, gy, cx, cy, sx, sy, n_cellsx, n_cellsy,
visualise, orientations, orientation_histogram)
_hoghistogram.hog_histograms(gx, gy, cx, cy, sx, sy, n_cellsx, n_cellsy,
orientations, orientation_histogram)
# now for each cell, compute the histogram
hog_image = None
+67 -62
View File
@@ -5,11 +5,13 @@
import numpy as np
cimport numpy as cnp
cdef float CellHog(cnp.float64_t[:, :] magnitude,
cnp.float64_t[:, :] orientation,
float ori1, float ori2,
int cx, int cy, int xi, int yi, int sx, int sy):
"""CellHog
cdef float cell_hog(cnp.float64_t[:, :] magnitude,
cnp.float64_t[:, :] orientation,
float orientation_start, float orientation_end,
int cell_columns, int cell_rows,
int column_index, int row_index,
int size_columns, int size_rows):
"""Calculation of the cell's HOG value
Parameters
----------
@@ -17,109 +19,112 @@ cdef float CellHog(cnp.float64_t[:, :] magnitude,
The gradient magnitudes of the pixels.
orientation : ndarray
Lookup table for orientations.
ori1 : float
orientation_start : float
Orientation range start.
ori2 : float
orientation_end : float
Orientation range end.
cx : int
cell_columns : int
Pixels per cell (x).
cy : int
cell_rows : int
Pixels per cell (y).
xi : int
Block index (x).
yi : int
Block index (y).
sx : int
Image size (x).
sy : int
Image size (y).
column_index : int
Block column index.
row_index : int
Block row index.
size_columns : int
Number of columns.
size_rows : int
Number of rows.
Returns
-------
total : float
The total HOG value.
"""
cdef int cx1, cy1
cdef int cell_column, cell_row
cdef float total = 0.
for cy1 in range(-cy/2, cy/2):
for cx1 in range(-cx/2, cx/2):
if (yi + cy1 < 0
or yi + cy1 >= sy
or xi + cx1 < 0
or xi + cx1 >= sx
or orientation[yi + cy1, xi + cx1] >= ori1
or orientation[yi + cy1, xi + cx1] < ori2): continue
for cell_row in range(-cell_rows/2, cell_rows/2):
for cell_column in range(-cell_columns/2, cell_columns/2):
if (row_index + cell_row < 0
or row_index + cell_row >= size_rows
or column_index + cell_column < 0
or column_index + cell_column >= size_columns
or orientation[row_index + cell_row, column_index + cell_column]
>= orientation_start
or orientation[row_index + cell_row, column_index + cell_column]
< orientation_end): continue
total += magnitude[yi + cy1, xi + cx1]
total += magnitude[row_index + cell_row, column_index + cell_column]
return total
def HogHistograms(cnp.float64_t[:, :] gx,
cnp.float64_t[:, :] gy,
int cx, int cy,
int sx, int sy,
int n_cellsx, int n_cellsy,
int visualise, int orientations,
cnp.float64_t[:, :, :] orientation_histogram):
def hog_histograms(cnp.float64_t[:, :] gradient_columns,
cnp.float64_t[:, :] gradient_rows,
int cell_columns, int cell_rows,
int size_columns, int size_rows,
int number_of_cells_columns, int number_of_cells_rows,
int number_of_orientations,
cnp.float64_t[:, :, :] orientation_histogram):
"""Extract Histogram of Oriented Gradients (HOG) for a given image.
Parameters
----------
gx : ndarray
gradient_columns : ndarray
First order image gradients (x).
gy : ndarray
gradient_rows : ndarray
First order image gradients (y).
cx : int
cell_columns : int
Pixels per cell (x).
cy : int
cell_rows : int
Pixels per cell (y).
sx : int
Image size (x).
sy : int
Image size (y).
n_cellsx : int
size_columns : int
Number of columns.
size_rows : int
Number of rows.
number_of_cells_columns : int
Number of cells (x).
n_cellsy : int
number_of_cells_rows : int
Number of cells (y).
visualise : int
Also return an image of the HOG.
orientations : int
number_of_orientations : int
Number of orientation bins.
orientation_histogram : ndarray
The histogram to fill.
"""
cdef cnp.float64_t[:, :] magnitude = np.hypot(gx, gy)
cdef cnp.float64_t[:, :] orientation = np.arctan2(gy, gx) * (180 / np.pi) % 180
cdef cnp.float64_t[:, :] magnitude = np.hypot(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 ori1, ori2
cdef float orientation_start, orientation_end
# compute orientations integral images
for i in range(orientations):
for i in range(number_of_orientations):
# isolate orientations in this range
ori1 = 180. / orientations * (i + 1)
ori2 = 180. / orientations * i
orientation_start = 180. / number_of_orientations * (i + 1)
orientation_end = 180. / number_of_orientations * i
y = cy / 2
cy2 = cy * n_cellsy
x = cx / 2
cx2 = cx * n_cellsx
y = cell_rows / 2
cy2 = cell_rows * number_of_cells_rows
x = cell_columns / 2
cx2 = cell_columns * number_of_cells_columns
yi = 0
xi = 0
while y < cy2:
xi = 0
x = cx / 2
x = cell_columns / 2
while x < cx2:
orientation_histogram[yi, xi, i] = CellHog(magnitude,
orientation, ori1, ori2, cx, cy, x, y, sx, sy)
orientation_histogram[yi, xi, i] = cell_hog(magnitude,
orientation, orientation_start, orientation_end,
cell_columns, cell_rows, x, y, size_columns, size_rows)
xi += 1
x += cx
x += cell_columns
yi += 1
y += cy
y += cell_rows