%HISTO Histogram. % histogram = histo(x) bins each element of x into % the container for the nearest whole integer % and returns the number of elements in each container. % % h = histo( [ 9 9 9 9 2 2 3 3 4 5 9 ]' )' % returns h = [ 0 0 2 2 1 1 0 0 0 5 ] % meaning that % "0" (-inf to +0.5) never occurred, % "1" (0.5 to 1.5) never occurred, % "2" (1.5 to 2.5) occurred twice, % ... % "9" (8.5 to 9.5) occurred 5 times. % % If x is a matrix or 3D array, % histo(x) does every column independently. % Usage: % cameraman = imread('cameraman.tif'); % histogram = histo( cameraman(:) ); % figure; stem(histogram) % diff_cameraman = diff(double(cameraman)); % diff_cameraman = [ cameraman(1,:); diff_cameraman ]; % minimum = min(diff_cameraman(:)); % histogram2 = histo( diff_cameraman(:)-minimum ); % figure; stem( minimum + (1:length(histogram2)), histogram2 ) % % Does exactly the same thing as h=hist( x,0:max(x(:)) ), % but in about 1/5 the time, when x is a vector or 2D matrix. % % See also HIST, EQUALIZE, HUFFMANLENGTH. % See "hist.c" % http://www.mathworks.com/support/ftp/graphicsv4.shtml % ftp://ftp.mathworks.com/pub/contrib/v4/graphics/hist.c % for a C Mex file to speed up histograms even faster. % Change log: % 1999-06-29:DAV: completely changed; reduced time % a factor of 10 on cameraman % (from 21 seconds to 2.4 seconds on my machine). % 1999-06-29:DAV: factored "frequency" into 2 routines, % "frequency" and "histo". % 1999-06-24:DAV: David Cary added documentation % ???:JCK: John C. Kieffer wrote original "frequency.m" % http://www.ee.umn.edu/users/kieffer/programs.html function histogram = histo(raw_data) % Create a single column vector containing all the values of the object. % Round to nearest integer. x = round(double(raw_data)); % make sure all values less than 0 get collapsed to 0. x = x .* (0 < x); bins = 1+max(x(:)); % append "-1" (so we count bin 0 properly) and % 1 extra copy of each letter to every column, % (to make sure each bin holds at least 1) % then sort shape = size(x); rows = shape(1); shape(1) = 1; %x(rows+1:rows+bins+2,:) = 0; appendix = repmat( (-1:bins)', shape); %x(rows+1:rows+bins+2,:) = repmat( [zeros(rows,1); (-1:bins)'], ; % This works for ndims(x) < 6. % How to generalize for arbitrary dimentions ? x(rows+1:rows+bins+2,:,:,:,:) = appendix; %x = [ x; appendix ]; x = sort(x); % get the *locations* of each transition to the next letter x = diff(x); transitionshape = shape; transitionshape(1) = bins+1; transition = zeros( transitionshape ); for( columns = 1:shape(2) ), for( d3 = 1:size(x,3) ), for( d4 = 1:size(x,4) ), for( d5 = 1:size(x,5) ), transition(:, columns, d3, d4, d5) = ... find( x(:, columns, d3, d4, d5) ); end; end; end; end; % finally, get the frequency (the distance between transitions) % and subtract off the extra letters we added. histogram = diff(transition)-1; % This straightforward method % (according to profile) % is actually slower in MatLab: %x = round(double(raw_data(:))); %x = (x .* (0 < x)) + 1; %bins = max(x(:)); %histogram = zeros(bins,1); %for i = 1:length(x), % t = x(i); % histogram(t) = histogram(t) + 1; %end; % end histo.m