-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathcompute_HOG.m
executable file
·150 lines (114 loc) · 4.6 KB
/
compute_HOG.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
function H = compute_HOG(I, cell_size, block_size,n_bins)
% COMPUTE_HOG Computes the HOG descriptor of the given image computed
% with the specified paramters.
%
% INPUT:
% I: image to extract HOGs
% cell_size: size of the cells in pixels
% block_size: size of the blocks in cells
% n_bins: number of bins of the histograms
%
% OUTPUT:
% H: HoG descriptor in a column vector form.
%
%
%$ Author Jose Marcos Rodriguez $
%$ Date: 2013/20/08 22:00:00 $
%$ Revision: 1.1 $
%% Setting gradient configuration
% gradient angle range control
epsilon = 0.0001;
L_norm = 2;
desp = 1;
total_angles = 180.0;
bin_width = total_angles/n_bins;
%% column matrix for mapping indices to bin center values
bin_centers_map = (bin_width/2:bin_width:total_angles)';
%% Compute the gradient in polar coordinates
[angles, magnitudes] = compute_gradient(I);
%% Split the gradient in cells
cell_coords = compute_cell_coordinates(angles,cell_size,cell_size,false);
%% initialize 3 dimensional matrix to hold all the histograms
% number of vertical and horizontal cells
[height,width] = size(I(:,:,1));
n_v_cells = floor(height/cell_size);
n_h_cells = floor(width/cell_size);
% init the histograms 3D matrix (7x14x9)
histograms = zeros(n_v_cells,n_h_cells,n_bins);
% ================================================
%% Computing histograms for all image cells
% ================================================
for index=1:size(cell_coords,2)
% current cell histogram initialization
h = zeros(1,n_bins);
% cell coords
x_min = cell_coords(1,index);
x_max = cell_coords(2,index);
y_min = cell_coords(3,index);
y_max = cell_coords(4,index);
% retrieve angles and magnitudes for all the pixels in the
% cell and conversion to degrees.
angs = angles(y_min:y_max,x_min:x_max);
angs = angs.*180/pi;
mags = magnitudes(y_min:y_max,x_min:x_max);
% indices for the left and right histogram bins that bound
% the current angle value for all the pixels in the cell
left_indices = round(angs/bin_width);
right_indices = left_indices+1;
% wraping contributions over the histogram boundaries.
left_indices(left_indices==0) = 9;
right_indices(right_indices==10) = 1;
% retrieving the left bin center value.
left_bin_centers = bin_centers_map(left_indices);
angs(angs < left_bin_centers) = ...
total_angles + angs(angs < left_bin_centers);
% calculating the contribution to both bins sides (vote weight)
% (matrices with same size as the cell)
right_contributions = (angs-left_bin_centers)/bin_width;
left_contributions = 1 - right_contributions;
left_contributions = mags.*left_contributions;
right_contributions = mags.*right_contributions;
% computing contributions for the current histogram bin by bin.
for bin=1:n_bins
% pixels that contribute to the bin with its left portion
pixels_to_left = (left_indices == bin);
h(bin) = h(bin) + sum(left_contributions(pixels_to_left));
% pixels that contribute to the bin with its right portion
pixels_to_right = (right_indices == bin);
h(bin) = h(bin) + sum(right_contributions(pixels_to_right));
end
% appending current hist. to the histograms matrix
row_offset = floor(index/n_h_cells + 1);
column_offset = mod(index-1,n_h_cells)+1;
histograms(row_offset,column_offset,:) = h(1,:);
end
% ================================================
%% block normalization (L2 norm)
% ================================================
hist_size = block_size*block_size*n_bins;
descriptor_size = hist_size*(n_v_cells-block_size+desp)*(n_h_cells-block_size+desp);
H = zeros(descriptor_size, 1);
col = 1;
row = 1;
% H = [];
%% Split the histogram matrix in blocks (this code assumes an 50% of overlap as desp is hard coded as 1)
while row <= n_v_cells-block_size+1
while col <= n_h_cells-block_size+1
% Getting all the histograms for a block
blockHists = ...
histograms(row:row+block_size-1, col:col+block_size-1, :);
% Getting the magnitude of the histograms of the block
magnitude = norm(blockHists(:),L_norm);
% Divide all of the histogram values by the magnitude to normalize
% them.
normalized = blockHists / (magnitude + epsilon);
% H = [H; normalized(:)];
offset = (row-1)*(n_h_cells-block_size+1)+col;
ini = (offset-1)*hist_size+1;
fin = offset*hist_size;
H(ini:fin,1) = normalized(:);
col = col+desp;
end
row = row+desp;
col = 1;
end