mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-13 17:45:20 +08:00
Merge pull request #1783 from ivoflipse/fix_hog
Fixing Cythonized version of HOG
This commit is contained in:
Binary file not shown.
+11
-6
@@ -5,7 +5,8 @@ from . import _hoghistogram
|
||||
|
||||
|
||||
def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
cells_per_block=(3, 3), visualise=False, normalise=False):
|
||||
cells_per_block=(3, 3), visualise=False, normalise=False,
|
||||
feature_vector=True):
|
||||
"""Extract Histogram of Oriented Gradients (HOG) for a given image.
|
||||
|
||||
Compute a Histogram of Oriented Gradients (HOG) by
|
||||
@@ -31,6 +32,9 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
normalise : bool, optional
|
||||
Apply power law compression to normalise the image before
|
||||
processing.
|
||||
feature_vector : bool, optional
|
||||
Return the data as a feature vector by calling .ravel() on the result
|
||||
just before returning.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -127,13 +131,11 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
orientations_arr = np.arange(orientations)
|
||||
dx_arr = radius * np.cos(orientations_arr / orientations * np.pi)
|
||||
dy_arr = radius * np.sin(orientations_arr / orientations * np.pi)
|
||||
cr2 = cy + cy
|
||||
cc2 = 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 * cr2 // 2, x * cc2 // 2])
|
||||
centre = tuple([y * cy + cy // 2, x * cx + cx // 2])
|
||||
rr, cc = draw.line(int(centre[0] - dx),
|
||||
int(centre[1] + dy),
|
||||
int(centre[0] + dx),
|
||||
@@ -171,8 +173,11 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
overlapping grid of blocks covering the detection window into a combined
|
||||
feature vector for use in the window classifier.
|
||||
"""
|
||||
|
||||
if feature_vector:
|
||||
normalised_blocks = normalised_blocks.ravel()
|
||||
|
||||
if visualise:
|
||||
return normalised_blocks.ravel(), hog_image
|
||||
return normalised_blocks, hog_image
|
||||
else:
|
||||
return normalised_blocks.ravel()
|
||||
return normalised_blocks
|
||||
|
||||
@@ -10,7 +10,9 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
float orientation_start, float orientation_end,
|
||||
int cell_columns, int cell_rows,
|
||||
int column_index, int row_index,
|
||||
int size_columns, int size_rows) nogil:
|
||||
int size_columns, int size_rows,
|
||||
int range_rows_start, int range_rows_stop,
|
||||
int range_columns_start, int range_columns_stop) nogil:
|
||||
"""Calculation of the cell's HOG value
|
||||
|
||||
Parameters
|
||||
@@ -35,22 +37,23 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
Number of columns.
|
||||
size_rows : int
|
||||
Number of rows.
|
||||
range_rows_start : int
|
||||
Start row of cell.
|
||||
range_rows_stop : int
|
||||
Stop row of cell.
|
||||
range_columns_start : int
|
||||
Start column of cell.
|
||||
range_columns_stop : int
|
||||
Stop column of cell
|
||||
|
||||
Returns
|
||||
-------
|
||||
total : float
|
||||
The total HOG value.
|
||||
"""
|
||||
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 int cell_column, cell_row, cell_row_index, cell_column_index
|
||||
cdef float total = 0.
|
||||
|
||||
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):
|
||||
@@ -67,7 +70,7 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
|
||||
total += magnitude[cell_row_index, cell_column_index]
|
||||
|
||||
return total
|
||||
return total / (cell_rows * cell_columns)
|
||||
|
||||
def hog_histograms(double[:, ::1] gradient_columns,
|
||||
double[:, ::1] gradient_rows,
|
||||
@@ -106,7 +109,9 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
gradient_rows)
|
||||
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 int i, x, y, o, yi, xi, cc, cr, x0, y0, \
|
||||
range_rows_start, range_rows_stop, \
|
||||
range_columns_start, range_columns_stop
|
||||
cdef float orientation_start, orientation_end, \
|
||||
number_of_orientations_per_180
|
||||
|
||||
@@ -115,6 +120,10 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
cc = cell_rows * number_of_cells_rows
|
||||
cr = cell_columns * number_of_cells_columns
|
||||
number_of_orientations_per_180 = 180. / number_of_orientations
|
||||
range_rows_stop = cell_rows/2
|
||||
range_rows_start = -range_rows_stop
|
||||
range_columns_stop = cell_columns/2
|
||||
range_columns_start = -range_columns_stop
|
||||
|
||||
with nogil:
|
||||
# compute orientations integral images
|
||||
@@ -134,7 +143,8 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
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)
|
||||
cell_columns, cell_rows, x, y, size_columns, size_rows,
|
||||
range_rows_start, range_rows_stop, range_columns_start, range_columns_stop)
|
||||
xi += 1
|
||||
x += cell_columns
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
import numpy as np
|
||||
from scipy import ndimage as ndi
|
||||
import skimage as si
|
||||
from skimage import data
|
||||
from skimage import feature
|
||||
from skimage import img_as_float
|
||||
@@ -9,7 +11,7 @@ from numpy.testing import (assert_raises,
|
||||
)
|
||||
|
||||
|
||||
def test_histogram_of_oriented_gradients():
|
||||
def test_histogram_of_oriented_gradients_output_size():
|
||||
img = img_as_float(data.astronaut()[:256, :].mean(axis=2))
|
||||
|
||||
fd = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
|
||||
@@ -18,6 +20,17 @@ def test_histogram_of_oriented_gradients():
|
||||
assert len(fd) == 9 * (256 // 8) * (512 // 8)
|
||||
|
||||
|
||||
def test_histogram_of_oriented_gradients_output_correctness():
|
||||
img = np.load(os.path.join(si.data_dir, 'lena_GRAY_U8.npy'))
|
||||
correct_output = np.load(os.path.join(si.data_dir, 'lena_GRAY_U8_hog.npy'))
|
||||
|
||||
output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
|
||||
cells_per_block=(3, 3), feature_vector=True,
|
||||
normalise=False, visualise=False)
|
||||
|
||||
assert_almost_equal(output, correct_output)
|
||||
|
||||
|
||||
def test_hog_image_size_cell_size_mismatch():
|
||||
image = data.camera()[:150, :200]
|
||||
fd = feature.hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
|
||||
Reference in New Issue
Block a user