--- a +++ b/functions/functions_FeatExtr/HashingHist.m @@ -0,0 +1,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 + +