@@ -64,6 +64,48 @@ def gaussian_derivative_edge_detector(image):
6464 return edges
6565
6666
67+ def hog (image , cell_size = 8 , bins = 9 , block_size = 2 ):
68+ """Histogram of Oriented Gradients (HOG) feature descriptor [#446].
69+
70+ Implements Dalal & Triggs (2005) -- the descriptor referenced by AIMA Chapter
71+ 24 (Perception), for which the book gives no pseudocode. The steps are:
72+ gradient magnitude and unsigned (0-180 deg) orientation; for each
73+ ``cell_size`` x ``cell_size`` cell, a ``bins``-bin orientation histogram weighted
74+ by gradient magnitude; L2 normalization over each ``block_size`` x ``block_size``
75+ block of cells; the normalized blocks concatenated into one feature vector.
76+
77+ Source: N. Dalal & B. Triggs, "Histograms of Oriented Gradients for Human
78+ Detection", CVPR 2005.
79+ """
80+ image = np .asarray (image , dtype = float )
81+ if image .ndim == 3 : # collapse colour channels to grayscale
82+ image = image .mean (axis = 2 )
83+
84+ gy , gx = np .gradient (image )
85+ magnitude = np .hypot (gx , gy )
86+ orientation = np .rad2deg (np .arctan2 (gy , gx )) % 180 # unsigned gradient angle
87+
88+ cells_y , cells_x = image .shape [0 ] // cell_size , image .shape [1 ] // cell_size
89+ bin_width = 180 / bins
90+ histograms = np .zeros ((cells_y , cells_x , bins ))
91+ for cy in range (cells_y ):
92+ for cx in range (cells_x ):
93+ rows = slice (cy * cell_size , (cy + 1 ) * cell_size )
94+ cols = slice (cx * cell_size , (cx + 1 ) * cell_size )
95+ cell_bins = (orientation [rows , cols ] // bin_width ).astype (int ) % bins
96+ cell_mag = magnitude [rows , cols ]
97+ for k in range (bins ):
98+ histograms [cy , cx , k ] = cell_mag [cell_bins == k ].sum ()
99+
100+ eps = 1e-5
101+ features = []
102+ for by in range (cells_y - block_size + 1 ):
103+ for bx in range (cells_x - block_size + 1 ):
104+ block = histograms [by :by + block_size , bx :bx + block_size ].ravel ()
105+ features .append (block / np .sqrt ((block ** 2 ).sum () + eps ** 2 ))
106+ return np .concatenate (features ) if features else histograms .ravel ()
107+
108+
67109def laplacian_edge_detector (image ):
68110 """Extract image edge with laplacian filter"""
69111 if not isinstance (image , np .ndarray ):
0 commit comments