Initial attempt at optimising HOG features with cython

This commit is contained in:
Tim Sheerman-Chase
2013-06-19 09:39:22 +01:00
committed by Korijn van Golen
parent 7132df764e
commit f09907961a
3 changed files with 76 additions and 17 deletions
+3 -17
View File
@@ -2,7 +2,7 @@ import numpy as np
from scipy import sqrt, pi, arctan2, cos, sin
from scipy.ndimage import uniform_filter
from .._shared.utils import assert_nD
import _hoghistogram
def hog(image, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(3, 3), visualise=False, normalise=False):
@@ -114,24 +114,10 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
n_cellsx = int(np.floor(sx // cx)) # number of cells in x
n_cellsy = int(np.floor(sy // cy)) # number of cells in y
# compute orientations integral images
orientation_histogram = np.zeros((n_cellsy, n_cellsx, orientations))
subsample = np.index_exp[cy // 2:cy * n_cellsy:cy,
cx // 2:cx * n_cellsx:cx]
for i in range(orientations):
# create new integral image for this orientation
# isolate orientations in this range
temp_ori = np.where(orientation < 180.0 / orientations * (i + 1),
orientation, -1)
temp_ori = np.where(orientation >= 180.0 / orientations * i,
temp_ori, -1)
# select magnitudes for those orientations
cond2 = temp_ori > -1
temp_mag = np.where(cond2, magnitude, 0)
temp_filt = uniform_filter(temp_mag, size=(cy, cx))
orientation_histogram[:, :, i] = temp_filt[subsample]
_hoghistogram.HogHistograms(gx, gy, cx, cy, sx, sy, n_cellsx, n_cellsy, visualise, orientations,
orientation_histogram)
# now for each cell, compute the histogram
hog_image = None
+70
View File
@@ -0,0 +1,70 @@
# cython: profile=True
# cython: cdivision=True
# cython: boundscheck=False
# cython: wraparound=False
import cmath, math
cimport numpy as np
import numpy as np
from scipy import pi, arctan2, cos, sin
cdef float CellHog(np.ndarray[np.float64_t, ndim=2] magnitude,
np.ndarray[np.float64_t, ndim=2] orientation,
float ori1, float ori2,
int cx, int cy, int xi, int yi, int sx, int sy):
cdef int cx1, cy1
cdef float total = 0.
for cy1 in range(-cy/2, cy/2):
for cx1 in range(-cx/2, cx/2):
if yi + cy1 < 0: continue
if yi + cy1 >= sy: continue
if xi + cx1 < 0: continue
if xi + cx1 >= sx: continue
if orientation[yi + cy1, xi + cx1] >= ori1: continue
if orientation[yi + cy1, xi + cx1] < ori2: continue
total += magnitude[yi + cy1, xi + cx1]
return total
def HogHistograms(np.ndarray[np.float64_t, ndim=2] gx, \
np.ndarray[np.float64_t, ndim=2] gy,
int cx, int cy, #Pixels per cell
int sx, int sy, #Image size
int n_cellsx, int n_cellsy,
int visualise, int orientations,
np.ndarray[np.float64_t, ndim=3] orientation_histogram):
cdef np.ndarray[np.float64_t, ndim=2] magnitude = np.sqrt(gx**2 + gy**2)
cdef np.ndarray[np.float64_t, ndim=2] orientation = arctan2(gy, gx) * (180 / pi) % 180
cdef int i, x, y, o, yi, xi, cy1, cy2, cx1, cx2
cdef float ori1, ori2
# compute orientations integral images
for i in range(orientations):
# isolate orientations in this range
ori1 = 180. / orientations * (i + 1)
ori2 = 180. / orientations * i
y = cy / 2
cy2 = cy * n_cellsy
x = cx / 2
cx2 = cx * n_cellsx
yi = 0
xi = 0
while y < cy2:
xi = 0
x = cx / 2
while x < cx2:
orientation_histogram[yi, xi, i] = CellHog(magnitude, orientation, ori1, ori2, cx, cy, x, y, sx, sy)
xi += 1
x += cx
yi += 1
y += cy
+3
View File
@@ -18,6 +18,7 @@ def configuration(parent_package='', top_path=None):
cython(['brief_cy.pyx'], working_path=base_path)
cython(['_texture.pyx'], working_path=base_path)
cython(['_hessian_det_appx.pyx'], working_path=base_path)
cython(['_hoghistogram.pyx'], working_path=base_path)
config.add_extension('corner_cy', sources=['corner_cy.c'],
include_dirs=[get_numpy_include_dirs()])
@@ -31,6 +32,8 @@ def configuration(parent_package='', top_path=None):
include_dirs=[get_numpy_include_dirs(), '../_shared'])
config.add_extension('_hessian_det_appx', sources=['_hessian_det_appx.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_hoghistogram', sources=['_hoghistogram.c'],
include_dirs=[get_numpy_include_dirs(), '../_shared'])
return config