diff --git a/skimage/feature/_hog.py b/skimage/feature/_hog.py index 760102e7..c5d7ad90 100644 --- a/skimage/feature/_hog.py +++ b/skimage/feature/_hog.py @@ -2,11 +2,12 @@ from __future__ import division import numpy as np from .._shared.utils import assert_nD from . import _hoghistogram +import warnings def hog(image, orientations=9, pixels_per_cell=(8, 8), - cells_per_block=(3, 3), visualise=False, normalise=False, - feature_vector=True): + cells_per_block=(3, 3), visualise=False, transform_sqrt=False, + feature_vector=True, normalise=None): """Extract Histogram of Oriented Gradients (HOG) for a given image. Compute a Histogram of Oriented Gradients (HOG) by @@ -29,12 +30,16 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8), Number of cells in each block. visualise : bool, optional Also return an image of the HOG. - normalise : bool, optional + transform_sqrt : bool, optional Apply power law compression to normalise the image before - processing. + processing. DO NOT use this if the image contains negative + values. Also see `notes` section below. feature_vector : bool, optional Return the data as a feature vector by calling .ravel() on the result just before returning. + normalise : bool, deprecated + The parameter is deprecated. Use `transform_sqrt` for power law + compression. `normalise` has been deprecated. Returns ------- @@ -51,6 +56,13 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8), Human Detection, IEEE Computer Society Conference on Computer Vision and Pattern Recognition 2005 San Diego, CA, USA + Notes + ----- + Power law compression, also known as Gamma correction, is used to reduce + the effects of shadowing and illumination variations. The compression makes + the dark regions lighter. When the kwarg `transform_sqrt` is set to + ``True``, the function computes the square root of each color channel + and then applies the hog algorithm to the image. """ image = np.atleast_2d(image) @@ -66,7 +78,13 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8), assert_nD(image, 2) - if normalise: + if normalise is not None: + raise ValueError("The normalise parameter was removed due to incorrect " + "behavior; it only applied a square root instead of a " + "true normalization. If you wish to duplicate the old " + "behavior, set ``transform_sqrt=True``.") + + if transform_sqrt: image = np.sqrt(image) """ @@ -173,7 +191,7 @@ 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() diff --git a/skimage/feature/tests/test_hog.py b/skimage/feature/tests/test_hog.py index 852dbff5..0a31b910 100644 --- a/skimage/feature/tests/test_hog.py +++ b/skimage/feature/tests/test_hog.py @@ -24,11 +24,11 @@ def test_histogram_of_oriented_gradients_output_size(): def test_histogram_of_oriented_gradients_output_correctness(): img = color.rgb2gray(data.astronaut()) correct_output = np.load(os.path.join(si.data_dir, 'astronaut_GRAY_hog.npy')) - - output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8), + + output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(3, 3), feature_vector=True, - normalise=False, visualise=False) - + transform_sqrt=False, visualise=False) + assert_almost_equal(output, correct_output) @@ -49,7 +49,7 @@ def test_hog_basic_orientations_and_data_types(): # 1) create image (with float values) where upper half is filled by # zeros, bottom half by 100 # 2) create unsigned integer version of this image - # 3) calculate feature.hog() for both images, both with 'normalise' + # 3) calculate feature.hog() for both images, both with 'transform_sqrt' # option enabled and disabled # 4) verify that all results are equal where expected # 5) verify that computed feature vector is as expected @@ -70,16 +70,16 @@ def test_hog_basic_orientations_and_data_types(): (hog_float, hog_img_float) = feature.hog( image_float, orientations=4, pixels_per_cell=(8, 8), - cells_per_block=(1, 1), visualise=True, normalise=False) + cells_per_block=(1, 1), visualise=True, transform_sqrt=False) (hog_uint8, hog_img_uint8) = feature.hog( image_uint8, orientations=4, pixels_per_cell=(8, 8), - cells_per_block=(1, 1), visualise=True, normalise=False) + cells_per_block=(1, 1), visualise=True, transform_sqrt=False) (hog_float_norm, hog_img_float_norm) = feature.hog( image_float, orientations=4, pixels_per_cell=(8, 8), - cells_per_block=(1, 1), visualise=True, normalise=True) + cells_per_block=(1, 1), visualise=True, transform_sqrt=True) (hog_uint8_norm, hog_img_uint8_norm) = feature.hog( image_uint8, orientations=4, pixels_per_cell=(8, 8), - cells_per_block=(1, 1), visualise=True, normalise=True) + cells_per_block=(1, 1), visualise=True, transform_sqrt=True) # set to True to enable manual debugging with graphical output, # must be False for automatic testing @@ -101,11 +101,11 @@ def test_hog_basic_orientations_and_data_types(): plt.subplot(2, 3, 3) plt.imshow(hog_img_float_norm) plt.colorbar() - plt.title('HOG result (normalise) visualisation (float img)') + plt.title('HOG result (transform_sqrt) visualisation (float img)') plt.subplot(2, 3, 6) plt.imshow(hog_img_uint8_norm) plt.colorbar() - plt.title('HOG result (normalise) visualisation (uint8 img)') + plt.title('HOG result (transform_sqrt) visualisation (uint8 img)') plt.show() # results (features and visualisation) for float and uint8 images must @@ -113,7 +113,7 @@ def test_hog_basic_orientations_and_data_types(): assert_almost_equal(hog_float, hog_uint8) assert_almost_equal(hog_img_float, hog_img_uint8) - # resulting features should be almost equal when 'normalise' is enabled + # resulting features should be almost equal when 'transform_sqrt' is enabled # or disabled (for current simple testing image) assert_almost_equal(hog_float, hog_float_norm, decimal=4) assert_almost_equal(hog_float, hog_uint8_norm, decimal=4) @@ -157,7 +157,7 @@ def test_hog_orientations_circle(): (hog, hog_img) = feature.hog(image, orientations=orientations, pixels_per_cell=(8, 8), cells_per_block=(1, 1), visualise=True, - normalise=False) + transform_sqrt=False) # set to True to enable manual debugging with graphical output, # must be False for automatic testing @@ -188,5 +188,9 @@ def test_hog_orientations_circle(): assert_almost_equal(actual, desired, decimal=1) +def test_hog_normalise_none_error_raised(): + img = np.array([1, 2, 3]) + assert_raises(ValueError, feature.hog, img, normalise=True) + if __name__ == '__main__': np.testing.run_module_suite()