diff --git a/tracking/computeHistogram.m b/tracking/computeHistogram.m new file mode 100644 index 0000000..9207538 --- /dev/null +++ b/tracking/computeHistogram.m @@ -0,0 +1,24 @@ +function histogram = computeHistogram(patch, mask, n_bins, grayscale_sequence) +%COMPUTEHISTOGRAM creates a colour (or grayscale) histogram of an image patch +% MASK has the same size as the image patch and selects what should +% be used when computing the histogram (i.e. out-of-frame regions are ignored) + + [h, w, d] = size(patch); + + assert(all([h w]==size(mask)) == 1, 'mask and image are not the same size'); + + bin_width = 256/n_bins; + + % convert image to 1d array with same n channels of img patch + patch_array = reshape(double(patch), w*h, d); + % compute to which bin each pixel (for all 3 channels) belongs to + bin_indices = floor(patch_array/bin_width) + 1; + + if grayscale_sequence + histogram = accumarray(bin_indices, mask(:), [n_bins 1])/sum(mask(:)); + else + % the histogram is a cube of side n_bins + histogram = accumarray(bin_indices, mask(:), [n_bins n_bins n_bins])/sum(mask(:)); + end + +end diff --git a/tracking/cropFilterResponse.m b/tracking/cropFilterResponse.m new file mode 100644 index 0000000..0d2e734 --- /dev/null +++ b/tracking/cropFilterResponse.m @@ -0,0 +1,26 @@ +function new_response = cropFilterResponse(response_cf, response_size) +%CROPFILTERRESPONSE makes RESPONSE_CF of size RESPONSE_SIZE (i.e. same size of colour response) + + [h,w] = size(response_cf); + b = response_size(1); + a = response_size(2); + + % a and b must be odd, as we want an exact center + if ~all_odd([a, b]) + error('dimensions must be odd'); + end + half_width = floor(a/2); + half_height = floor(b/2); + + new_response = response_cf(... + mod_one(-half_height:half_height, h), ... + mod_one(-half_width:half_width, w)); +end + +function y = mod_one(a, b) + y = mod(a-1, b)+1; +end + +function y = all_odd(x) + y = all(mod(x, 2) == 1); +end diff --git a/tracking/display_statistics.m b/tracking/display_statistics.m new file mode 100644 index 0000000..abfcd0f --- /dev/null +++ b/tracking/display_statistics.m @@ -0,0 +1,14 @@ +function display_statistics(name, precision, reinitializations, fps) + %print statistics to command window + str = sprintf('Overlap:% 1.3f', precision); + + if ~isnan(reinitializations), + if reinitializations == round(reinitializations), %prettier for integer values + str = [str, sprintf(', reinitializations:% 2i', reinitializations)]; + else + str = [str, sprintf(', reinitializations:% 1.2f', reinitializations)]; + end + end + + fprintf('%12s - %s, FPS:% 4.2f\n', name, str, fps) +end diff --git a/tracking/fhog.m b/tracking/fhog.m new file mode 100644 index 0000000..f96fc0f --- /dev/null +++ b/tracking/fhog.m @@ -0,0 +1,76 @@ +function H = fhog( I, binSize, nOrients, clip, crop ) +% Efficiently compute Felzenszwalb's HOG (FHOG) features. +% +% A fast implementation of the HOG variant used by Felzenszwalb et al. +% in their work on discriminatively trained deformable part models. +% http://www.cs.berkeley.edu/~rbg/latent/index.html +% Gives nearly identical results to features.cc in code release version 5 +% but runs 4x faster (over 125 fps on VGA color images). +% +% The computed HOG features are 3*nOrients+5 dimensional. There are +% 2*nOrients contrast sensitive orientation channels, nOrients contrast +% insensitive orientation channels, 4 texture channels and 1 all zeros +% channel (used as a 'truncation' feature). Using the standard value of +% nOrients=9 gives a 32 dimensional feature vector at each cell. This +% variant of HOG, refered to as FHOG, has been shown to achieve superior +% performance to the original HOG features. For details please refer to +% work by Felzenszwalb et al. (see link above). +% +% This function is essentially a wrapper for calls to gradientMag() +% and gradientHist(). Specifically, it is equivalent to the following: +% [M,O] = gradientMag( I,0,0,0,1 ); softBin = -1; useHog = 2; +% H = gradientHist(M,O,binSize,nOrients,softBin,useHog,clip); +% See gradientHist() for more general usage. +% +% This code requires SSE2 to compile and run (most modern Intel and AMD +% processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. +% +% USAGE +% H = fhog( I, [binSize], [nOrients], [clip], [crop] ) +% +% INPUTS +% I - [hxw] color or grayscale input image (must have type single) +% binSize - [8] spatial bin size +% nOrients - [9] number of orientation bins +% clip - [.2] value at which to clip histogram bins +% crop - [0] if true crop boundaries +% +% OUTPUTS +% H - [h/binSize w/binSize nOrients*3+5] computed hog features +% +% EXAMPLE +% I=imResample(single(imread('peppers.png'))/255,[480 640]); +% tic, for i=1:100, H=fhog(I,8,9); end; disp(100/toc) % >125 fps +% figure(1); im(I); V=hogDraw(H,25,1); figure(2); im(V) +% +% EXAMPLE +% % comparison to features.cc (requires DPM code release version 5) +% I=imResample(single(imread('peppers.png'))/255,[480 640]); Id=double(I); +% tic, for i=1:100, H1=features(Id,8); end; disp(100/toc) +% tic, for i=1:100, H2=fhog(I,8,9,.2,1); end; disp(100/toc) +% figure(1); montage2(H1); figure(2); montage2(H2); +% D=abs(H1-H2); mean(D(:)) +% +% See also hog, hogDraw, gradientHist +% +% Piotr's Image&Video Toolbox Version 3.23 +% Copyright 2013 Piotr Dollar. [pdollar-at-caltech.edu] +% Please email me if you find bugs, or have suggestions or questions! +% Licensed under the Simplified BSD License [see external/bsd.txt] + +%Note: modified to be more self-contained + +if( nargin<2 ), binSize=8; end +if( nargin<3 ), nOrients=9; end +if( nargin<4 ), clip=.2; end +if( nargin<5 ), crop=0; end + +softBin = -1; useHog = 2; b = binSize; + +[M,O]=gradientMex('gradientMag',I,0,1); + +H = gradientMex('gradientHist',M,O,binSize,nOrients,softBin,useHog,clip); + +if( crop ), e=mod(size(I),b)