-
Notifications
You must be signed in to change notification settings - Fork 1
/
HashingHist.m
149 lines (116 loc) · 5.28 KB
/
HashingHist.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
145
146
147
148
149
function [f BlkIdx] = HashingHist(PCANet,ImgIdx,OutImg)
% Output layer of PCANet (Hashing plus local histogram)
% ========= INPUT ============
% PCANet PCANet parameters (struct)
% .PCANet.NumStages
% the number of stages in PCANet; e.g., 2
% .PatchSize
% the patch size (filter size) for square patches; e.g., [5 3]
% means patch size equalt to 5 and 3 in the first stage and second stage, respectively
% .NumFilters
% the number of filters in each stage; e.g., [16 8] means 16 and
% 8 filters in the first stage and second stage, respectively
% .HistBlockSize
% the size of each block for local histogram; e.g., [10 10]
% .BlkOverLapRatio
% overlapped block region ratio; e.g., 0 means no overlapped
% between blocks, and 0.3 means 30% of blocksize is overlapped
% .Pyramid
% spatial pyramid matching; e.g., [1 2 4], and [] if no Pyramid
% is applied
% ImgIdx Image index for OutImg (column vector)
% OutImg PCA filter output before the last stage (cell structure)
% ========= OUTPUT ===========
% f PCANet features (each column corresponds to feature of each image)
% BlkIdx index of local block from which the histogram is compuated
% ============================
addpath('./Utils')
NumImg = max(ImgIdx);
f = cell(NumImg,1);
map_weights = 2.^((PCANet.NumFilters(end)-1):-1:0); % weights for binary to decimal conversion
for Idx = 1:NumImg
Idx_span = find(ImgIdx == Idx);
NumOs = length(Idx_span)/PCANet.NumFilters(end); % the number of "O"s
Bhist = cell(NumOs,1);
for i = 1:NumOs
T = 0;
ImgSize = size(OutImg{Idx_span(PCANet.NumFilters(end)*(i-1) + 1)});
for j = 1:PCANet.NumFilters(end)
T = T + map_weights(j)*Heaviside(OutImg{Idx_span(PCANet.NumFilters(end)*(i-1)+j)});
% weighted combination; hashing codes to decimal number conversion
OutImg{Idx_span(PCANet.NumFilters(end)*(i-1)+j)} = [];
end
if isempty(PCANet.HistBlockSize)
NumBlk = ceil((PCANet.ImgBlkRatio - 1)./PCANet.BlkOverLapRatio) + 1;
HistBlockSize = ceil(size(T)./PCANet.ImgBlkRatio);
OverLapinPixel = ceil((size(T) - HistBlockSize)./(NumBlk - 1));
NImgSize = (NumBlk-1).*OverLapinPixel + HistBlockSize;
Tmp = zeros(NImgSize);
Tmp(1:size(T,1), 1:size(T,2)) = T;
Bhist{i} = sparse(histc(im2col_general(Tmp,HistBlockSize,...
OverLapinPixel),(0:2^PCANet.NumFilters(end)-1)'));
else
stride = round((1-PCANet.BlkOverLapRatio)*PCANet.HistBlockSize);
blkwise_fea = sparse(histc(im2col_general(T,PCANet.HistBlockSize,...
stride),(0:2^PCANet.NumFilters(end)-1)'));
% calculate histogram for each local block in "T"
if ~isempty(PCANet.Pyramid)
x_start = ceil(PCANet.HistBlockSize(2)/2);
y_start = ceil(PCANet.HistBlockSize(1)/2);
x_end = floor(ImgSize(2) - PCANet.HistBlockSize(2)/2);
y_end = floor(ImgSize(1) - PCANet.HistBlockSize(1)/2);
sam_coordinate = [...
kron(x_start:stride:x_end,ones(1,length(y_start:stride: y_end)));
kron(ones(1,length(x_start:stride:x_end)),y_start:stride: y_end)];
blkwise_fea = spp(blkwise_fea, sam_coordinate, ImgSize, PCANet.Pyramid)';
else
blkwise_fea = bsxfun(@times, blkwise_fea, ...
2^PCANet.NumFilters(end)./sum(blkwise_fea));
end
Bhist{i} = blkwise_fea;
end
end
f{Idx} = vec([Bhist{:}]');
if ~isempty(PCANet.Pyramid)
f{Idx} = sparse(f{Idx}/norm(f{Idx}));
end
end
f = [f{:}];
if ~isempty(PCANet.Pyramid)
BlkIdx = kron((1:size(Bhist{1},1))',ones(length(Bhist)*size(Bhist{1},2),1));
else
BlkIdx = kron(ones(NumOs,1),kron((1:size(Bhist{1},2))',ones(size(Bhist{1},1),1)));
end
%-------------------------------
function X = Heaviside(X) % binary quantization
X = sign(X);
X(X<=0) = 0;
function x = vec(X) % vectorization
x = X(:);
function beta = spp(blkwise_fea, sam_coordinate, ImgSize, pyramid)
[dSize, ~] = size(blkwise_fea);
img_width = ImgSize(2);
img_height = ImgSize(1);
% spatial levels
pyramid_Levels = length(pyramid);
pyramid_Bins = pyramid.^2;
tBins = sum(pyramid_Bins);
beta = zeros(dSize, tBins);
cnt = 0;
for i1 = 1:pyramid_Levels,
Num_Bins = pyramid_Bins(i1);
wUnit = img_width / pyramid(i1);
hUnit = img_height / pyramid(i1);
% find to which spatial bin each local descriptor belongs
xBin = ceil(sam_coordinate(1,:) / wUnit);
yBin = ceil(sam_coordinate(2,:) / hUnit);
idxBin = (yBin - 1)*pyramid(i1) + xBin;
for i2 = 1:Num_Bins,
cnt = cnt + 1;
sidxBin = find(idxBin == i2);
if isempty(sidxBin),
continue;
end
beta(:, cnt) = max(blkwise_fea(:, sidxBin), [], 2);
end
end