www.pudn.com > colorseg.zip > createPyramid.m, change:2003-03-10,size:3401b


function M = createPyramid(im, distances, perceptual)

% M = CREATEPYRAMID(IM,DISTANCE) creates a multiscale pyramid of
% images based on spatial blurring in the luminance and opposing
% color planes (SCIELAB).  
%  
% Input: 
%       IM - must be an RGB color image (with values in [0,1])
%       DISTANCES - a vector that specifies the viewing distances 
%                   in inches that are the basis for the multiscale decomposition.  
%       PERCEPTUAL - A flag, which if set to 1, uses the regular
%       SCIELAB filters in the opponent color space.  If set to 0,
%       uses an average filter in all color planes.
%  
% Output:
%       M - an (m,n,3,N) matrix, where images are (m by n) and color, and there
%           are N levels of decomposition.  N is the length of DISTANCES.
%
% Jeff Walters & Angi Chau
% Feb 2003
  
MONITOR_DPI = 72;       % monitor dots per inch
RGB_WHITE = [1 1 1]';   % we need whitepoint for LAB conversions

disp(sprintf('createPyramid: perceptual = %d',perceptual));
N = length(distances);
[m,n,l] = size(im);
if (l ~= 3)
    warning('createPyramid: Input image must be color (RGB).');
    return;
end

% create the placeholder for the resulting series of images
M = zeros(m,n,3,N);

% make sure that we have access to the scielab toolbox
% $$$     p = genpath('../../');
% $$$     if (~exist('p'))
% $$$       warning('createPyramid: Unable to find main project path!');
% $$$       return;
% $$$     end
% $$$     path(path,p);
% $$$   

% create samples per degree for all of the distances  
sampPerDeg = round(visualAngle(-1,distances,MONITOR_DPI,1));

% load default color cone and monitor information
%load displaySPD;
%load SmithPokornyCones;

%rgb2lms = cones'*displaySPD;   
% *** MAYBE WE should use the above matrix instead of cmatrix...but 
% leaving it for now 

% calculate the XYZ for the white point (Y=100)
whiteXYZ = changeColorSpace(RGB_WHITE, cmatrix('rgb2xyz'));
whiteXYZ = whiteXYZ./whiteXYZ(2)*100;

% load default monitor gamma information
load displayGamma;

% convert the image from frame buffer RGB values to LMS after gamma correction
imgRGB = dac2rgb(im,gammaTable);
imgLMS = changeColorSpace(imgRGB, cmatrix('rgb2lms'));
imageformat = 'lms';

% finally, run the scielab function for all of the distances
for i=1:N
    disp(sprintf('Creating image %d of %d.',i,N));
    if (perceptual)
      outputOPP = scielab(sampPerDeg(i),imgLMS,imageformat);
    else
      outputOPP = scielab2(sampPerDeg(i),imgLMS,imageformat);
    end
    % convert back to XYZ then LAB (which is perceptually uniform)
    outputXYZ = changeColorSpace(outputOPP,cmatrix('opp2xyz'));
    
    % because scielab can return values out of valid range of xyz (and thus,
    % rgb and lms), let's clip off values outside of range
    numClipped = 0;
    outputLinearRGB = changeColorSpace(outputXYZ, cmatrix('xyz2rgb'));
    indices = find(outputLinearRGB  0);
    outputLinearRGB(indices) = 0;
    numClipped = length(indices);
    indices = find(outputLinearRGB>1);
    outputLinearRGB(indices) = 1;
    numClipped = length(indices)+numClipped;
    outputXYZ = changeColorSpace(outputLinearRGB, cmatrix('rgb2xyz'));
    
    disp(sprintf('Total number of values clipped = %d (%d percent)',numClipped, round(numClipped/numel(outputLinearRGB)*100)));
    
    % output in LAB space
    outLAB = xyz2lab(outputXYZ, whiteXYZ);
    M(:,:,:,i) = outLAB;
    
end