calc_colours

PURPOSE ^

[colours,scl_data]= calc_colours(img, set_value, do_colourbar)

SYNOPSIS ^

function [colours,scl_data]= calc_colours(img, set_value, do_colourbar)

DESCRIPTION ^

 [colours,scl_data]= calc_colours(img, set_value, do_colourbar)
 Calculate a colour for each image element 

 Conductive (positive) areas are shown in red
 Non-Conductive (negative) areas are shown in blue

 PARAMETERS: img
     - 1) an EIDORS image object, or a Ex1 vector
     - 2) a 2D image matrix

 Usage #1 (img is a Ex1 vector of element conductivities)

   Cs = calc_colours( img);
   patch(Xs,Ys,Zs,Cs);

 Cs is Ex1x1 colourmap entries (if mapped_colour>0)
       Ex1x3 colourmap entries (if mapped_colour==0)

 Usage #2 (rimg is a MxN image matrix of reconstructed pixels):
           img is an image structure with the image properties
  
   c_img = calc_colours( rimg, img);
   image( c_img );

 c_img is MxN colourmap entries (if mapped_colour>0)
          MxNx3 colourmap entries (if mapped_colour==0)

 Usage #3 (img is string parameter value)
  
   value = calc_colours( 'param' );
   calc_colours( 'param', value );
    eg. calc_colours('mapped_colour',127)
         Use this to allow printing vector eps files to get around
         a matlab bug with warning 'RGB color data not ...'

   The following parameters are accepted

   'greylev'    (DEFAULT -.01): the colour of the ref_level.
      Negative values indicate white background
      For almost white, greylev=-.01; Black=> greylev=.01
   'sat_adj'    (DEFAULT .9): max G,B when R=1
   'window_range' (DEFAULT .9); window colour range
      Colour slope outside range is 1/3 of centre slope
   'backgnd' ( DEFAULT [.5,.5,.15] ): image border colour 
   'ref_level' (DEFAULT 'auto') conductivity of centre of
      colour mapping. 'auto' tries to estimate a good level.
   'mapped_colour' (DEFAULT 127) number of colourmap entries
      using mapped_colour allows matlab to print vector graphics to eps
      setting mapped_colour=0 means to use RGB colours
   'npoints' (DEFAULT 64) number of points accross the image
   'clim'    (DEFAULT []) crop colour display of values above clim
           colour limit. values more different from ref_level are cropped.
           if not specified or clim==[] => no limit
   'cmap_type'  Specify special colours (Default 'blue_red')
           if 'draeger' use the Draegerwerk/Amato colourmap
           if 'jet' use the matlab jet colourmap
   'cb_shrink_move' shrink or move the colorbar. See eidors_colourbar
           help for details.

   'colourmap' Return the current EIDORS colormap. 
           Use as colormap(calc_colours('colourmap'))

 PARAMETERS CAN BE SPECIFIED IN TWO WAYS
   1. as an image parameter (ie clim in img.calc_colours.clim)
   2. a second parameter to ( calc_colours(data, param2 )
          where param2.calc_colours.clim= ... etc
   3. parameter to calc_colours('clim')

 Parameters specified as (1) will override (2)

 PARAMETERS: do_colourbar
    - show a Matlab colorbar with appropriate scaling

  usage: c_img= calc_colours( img, clim );
         image( c_img );
         calc_colours( img, clim, 1); %now do colorbar 

 PARAMETERS: ref_lev
     - if specified, override the global ref_level parameter

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [colours,scl_data]= calc_colours(img, set_value, do_colourbar)
0002 % [colours,scl_data]= calc_colours(img, set_value, do_colourbar)
0003 % Calculate a colour for each image element
0004 %
0005 % Conductive (positive) areas are shown in red
0006 % Non-Conductive (negative) areas are shown in blue
0007 %
0008 % PARAMETERS: img
0009 %     - 1) an EIDORS image object, or a Ex1 vector
0010 %     - 2) a 2D image matrix
0011 %
0012 % Usage #1 (img is a Ex1 vector of element conductivities)
0013 %
0014 %   Cs = calc_colours( img);
0015 %   patch(Xs,Ys,Zs,Cs);
0016 %
0017 % Cs is Ex1x1 colourmap entries (if mapped_colour>0)
0018 %       Ex1x3 colourmap entries (if mapped_colour==0)
0019 %
0020 % Usage #2 (rimg is a MxN image matrix of reconstructed pixels):
0021 %           img is an image structure with the image properties
0022 %
0023 %   c_img = calc_colours( rimg, img);
0024 %   image( c_img );
0025 %
0026 % c_img is MxN colourmap entries (if mapped_colour>0)
0027 %          MxNx3 colourmap entries (if mapped_colour==0)
0028 %
0029 % Usage #3 (img is string parameter value)
0030 %
0031 %   value = calc_colours( 'param' );
0032 %   calc_colours( 'param', value );
0033 %    eg. calc_colours('mapped_colour',127)
0034 %         Use this to allow printing vector eps files to get around
0035 %         a matlab bug with warning 'RGB color data not ...'
0036 %
0037 %   The following parameters are accepted
0038 %
0039 %   'greylev'    (DEFAULT -.01): the colour of the ref_level.
0040 %      Negative values indicate white background
0041 %      For almost white, greylev=-.01; Black=> greylev=.01
0042 %   'sat_adj'    (DEFAULT .9): max G,B when R=1
0043 %   'window_range' (DEFAULT .9); window colour range
0044 %      Colour slope outside range is 1/3 of centre slope
0045 %   'backgnd' ( DEFAULT [.5,.5,.15] ): image border colour
0046 %   'ref_level' (DEFAULT 'auto') conductivity of centre of
0047 %      colour mapping. 'auto' tries to estimate a good level.
0048 %   'mapped_colour' (DEFAULT 127) number of colourmap entries
0049 %      using mapped_colour allows matlab to print vector graphics to eps
0050 %      setting mapped_colour=0 means to use RGB colours
0051 %   'npoints' (DEFAULT 64) number of points accross the image
0052 %   'clim'    (DEFAULT []) crop colour display of values above clim
0053 %           colour limit. values more different from ref_level are cropped.
0054 %           if not specified or clim==[] => no limit
0055 %   'cmap_type'  Specify special colours (Default 'blue_red')
0056 %           if 'draeger' use the Draegerwerk/Amato colourmap
0057 %           if 'jet' use the matlab jet colourmap
0058 %   'cb_shrink_move' shrink or move the colorbar. See eidors_colourbar
0059 %           help for details.
0060 %
0061 %   'colourmap' Return the current EIDORS colormap.
0062 %           Use as colormap(calc_colours('colourmap'))
0063 %
0064 % PARAMETERS CAN BE SPECIFIED IN TWO WAYS
0065 %   1. as an image parameter (ie clim in img.calc_colours.clim)
0066 %   2. a second parameter to ( calc_colours(data, param2 )
0067 %          where param2.calc_colours.clim= ... etc
0068 %   3. parameter to calc_colours('clim')
0069 %
0070 % Parameters specified as (1) will override (2)
0071 %
0072 % PARAMETERS: do_colourbar
0073 %    - show a Matlab colorbar with appropriate scaling
0074 %
0075 %  usage: c_img= calc_colours( img, clim );
0076 %         image( c_img );
0077 %         calc_colours( img, clim, 1); %now do colorbar
0078 %
0079 % PARAMETERS: ref_lev
0080 %     - if specified, override the global ref_level parameter
0081 %
0082 
0083 % (C) 2005-2008 Andy Adler. License: GPL version 2 or version 3
0084 % $Id: calc_colours.html 2819 2011-09-07 16:43:11Z aadler $
0085 
0086 if nargin==0; error('calc_colours: expecting argument'); end
0087 if isstr(img) && strcmp(img,'UNIT_TEST'); do_unit_test; return; end
0088 
0089 if ischar(img)
0090     % called as calc_colours('parameter' ... )
0091     if nargin==1;
0092        colours= get_field(img);
0093     else
0094        colours= set_field(img, set_value);
0095     end
0096     return;
0097 
0098 elseif isfield(img,'type')
0099    img_data= get_img_data( img );
0100    pp=get_colours(img(1)) ;
0101 else
0102    img_data= img;
0103 
0104    if nargin==1
0105       pp=get_colours( [] ); 
0106    else
0107       pp=get_colours(set_value); 
0108    end
0109 end
0110 
0111 % Set default parameters
0112 if nargin < 3; do_colourbar = 0;       end
0113 ref_lev = 'use_global';
0114 
0115 
0116 if isempty(img_data)
0117     colours = 'k'; %black
0118     return;
0119 end
0120 
0121 m= size(img_data,1); n=size(img_data,2);
0122 
0123 % We can only plot the real part of data
0124 % Vectorize img_data here, it gets reshaped later
0125 [scl_data, ref_lev, max_scale] = ...
0126       scale_for_display( real(img_data(:)), pp.ref_level, pp.clim );
0127 
0128 backgnd= isnan(scl_data);
0129 scl_data(backgnd)= mean( scl_data(~backgnd));
0130 
0131 if pp.mapped_colour
0132    colours=set_mapped_colour(pp, backgnd, scl_data);
0133    colours= reshape( colours, m,n,[]);
0134 else
0135    [red,grn,blu] = blu_red_axis( pp, scl_data, backgnd );
0136    colours= reshape( [red,grn,blu],m,n,3);
0137 end
0138 
0139 % print colorbar if do_colourbar is specified
0140 if do_colourbar
0141    if ~pp.mapped_colour
0142        warning('Colorbar not available without mapped_colour option');
0143    else
0144        eidors_colourbar(max_scale,ref_lev,pp.cb_shrink_move)
0145    end
0146 end
0147 
0148 
0149 %scaled data must go from -1 to 1
0150 function [red,grn,blu] = blu_red_axis( pp, scale_data, backgnd )
0151    if ~isfield(pp,'cmap_type')
0152       pp.cmap_type = 'blue_red';
0153    end; 
0154 
0155    % window data such that slope above w is 1/3 of that below
0156    % thus w is mapped to k st k/w = 3(1-k)/(1-w) -> k=3w/(1+2w)
0157    W= pp.window_range; K= 3*W/(1+2*W);
0158    scale_data= sign(scale_data) .* ( ...
0159      (  K/W*   abs(scale_data)   ) .* (abs(scale_data)<=W) + ...
0160      (K+K/W/3*(abs(scale_data)-W)) .* (abs(scale_data)> W) );
0161 
0162    switch pp.cmap_type
0163      case {'blue_red',''}
0164       [red,grn,blu]= blue_red_colours(pp,scale_data);
0165      case 'draeger'
0166       [red,grn,blu]= draeger_colours(pp,scale_data);
0167      case 'jet'
0168       [red,grn,blu]= jet_colours(pp,scale_data);
0169      case 'jetair'
0170       % Make most of the range for air -ve
0171       scd = (scale_data + 0.5)/0.6;
0172       [red,grn,blu]= jet_colours(pp,scd);
0173      otherwise
0174       error(['specified cmap_type not understood:',pp.cmap_type]);
0175    end
0176 
0177    red(backgnd) = pp.backgnd(1);
0178    grn(backgnd) = pp.backgnd(2);
0179    blu(backgnd) = pp.backgnd(3);
0180 
0181 function [red,grn,blu]= blue_red_colours(pp,scale_data);
0182 if 0
0183    D= sign(pp.greylev+eps); %force 0 to 1
0184    glev= abs(pp.greylev);
0185    F= 3*pp.sat_adj;
0186 
0187    red= D*F*abs(scale_data+D/F) - D + (D==-1);
0188    red= red.*(red>0).*(red<1) + (red>=1);
0189    red= red*(1-glev) + glev;
0190 end
0191    ofs= (pp.greylev >= 0);   % 1 if greylev>=0
0192    glev= abs(pp.greylev);
0193 
0194    D= (2*ofs - 1);
0195    ofs= ofs - 2*(ofs==0);
0196    F= 3*pp.sat_adj;
0197    DF= D*F; D_F= D/F;
0198 
0199    red= DF*abs(scale_data+D_F) - ofs;
0200    red= red.*(red>0).*(red<1) + (red>=1);
0201 
0202    grn= DF*abs(scale_data    ) - ofs;
0203    grn= grn.*(grn>0).*(grn<1) + (grn>=1);
0204 
0205    blu= DF*abs(scale_data-D_F) - ofs;
0206    blu= blu.*(blu>0).*(blu<1) + (blu>=1);
0207 
0208    if pp.greylev >=0 % Black background
0209       red= red*(1-glev) + glev;
0210       grn= grn*(1-glev) + glev;
0211       blu= blu*(1-glev) + glev;
0212    else
0213       red= red*(1-glev);
0214       grn= grn*(1-glev);
0215       blu= blu*(1-glev);
0216    end
0217 
0218 function [red,grn,blu] = draeger_colours(pp,scale_data);
0219    grn=      (-scale_data>0.2) .* (-scale_data - 0.2)/0.8;
0220    red=grn + ( scale_data>0.2) .* ( scale_data - 0.2)/0.8*2/3;
0221 
0222    blu=      (-scale_data>0.1) .* (-scale_data - 0.1)/0.1;
0223    blu(-scale_data>0.2) = 1;
0224    blu=blu + ( scale_data>0.2) .* ( scale_data - 0.2)/0.8*2/3;
0225 
0226 % Sometimes this is just slightly > 1
0227    red(red>1) = 1;
0228    grn(grn>1) = 1;
0229    blu(blu>1) = 1;
0230 
0231 function [red,grn,blu] = jet_colours(pp,scale_data);
0232    grn = 2*(3/4 - abs(scale_data));
0233    grn(grn>1) = 1; grn(grn<0) = 0;
0234 
0235    red = 1.5 - 2*abs(scale_data + 0.5);
0236    red(red>1) = 1; red(red<0) = 0;
0237 
0238    blu = 1.5 - 2*abs(scale_data - 0.5);
0239    blu(blu>1) = 1; blu(blu<0) = 0;
0240 
0241 function pp=get_colours( img );
0242    global eidors_colours;
0243    pp= eidors_colours;
0244 
0245 % override global if calc.colours specified
0246    try
0247 % DAMN Matlab should have syntax for this loop
0248       fds= fieldnames(img(1).calc_colours);%assume all are the same!
0249       for fdn= fds(:)';
0250          fdn= fdn{1};
0251          pp.( fdn ) = img(1).calc_colours.(fdn);
0252       end
0253    end
0254 
0255 function BGI= backgndidx;
0256   BGI= 1;
0257 
0258 function colours=set_mapped_colour(pp, backgnd, img_data)
0259    % need to generate a colourmap with pp.mapped_colour+1 elements
0260    % background pixel will be at entry #1. Thus for
0261    % mapped_colour= 3. CMAP = [backgnd,[-1 -.5  0 .5 1]
0262    %
0263    % Note: ensure patch uses 'direct' CDataMapping
0264    ncol= pp.mapped_colour;
0265    [red,grn,blu] = blu_red_axis( pp, ...
0266           [-1,linspace(-1,1,2*ncol - 1)]', backgndidx );
0267    colormap([red,grn,blu]);
0268 % This is the line I wan't to write. However, matlab seems to waste
0269 %  lots of memory to do it. Instead we break it into pieces
0270 %  colours = fix( img_data * (ncol-1))' + ncol + 1;
0271    colours = img_data'; colours = colours * (ncol-1);
0272    colours = fix ( colours ); colours = colours + ncol + 1;
0273    colours(backgnd)= backgndidx;
0274 
0275 function value= get_field(param);
0276     global eidors_colours;
0277     if strcmp(param,'colourmap')
0278        ncol= eidors_colours.mapped_colour;
0279        [red,grn,blu] = blu_red_axis( eidors_colours, ...
0280               [-1,linspace(-1,1,2*ncol - 1)]', backgndidx );
0281        value= [red,grn,blu];
0282     else
0283        value = getfield(eidors_colours, param);
0284     end
0285 
0286 function value= set_field(param, value);
0287     global eidors_colours;
0288     eidors_colours = setfield(eidors_colours, param, value);
0289     value= eidors_colours;
0290 
0291 % TESTS:
0292 function do_unit_test
0293    img = eidors_obj('image','test'); 
0294 
0295    img.calc_colours.mapped_colour = 127;
0296    img.calc_colours.ref_level = 'auto';
0297    img.calc_colours.sat_adj = 0.9;
0298    img.calc_colours.window_range = 0.9;
0299    img.calc_colours.greylev = -0.01;
0300  
0301    img.elem_data = [-2;0;0;0;1;3];
0302    unit_test_cmp('cc01', calc_colours(img), [44; 128; 128; 128; 170; 254]);
0303 
0304    imgk(1) = img; imgk(2) = img;
0305    unit_test_cmp('cc01', calc_colours(imgk), [44; 128; 128; 128; 170; 254]*[1,1]);
0306 
0307    img.calc_colours.ref_level = 1;
0308    unit_test_cmp('cc02', calc_colours(img), [ 2;  86;  86;  86; 128; 212]);
0309 
0310    img.calc_colours.greylev = -.1;
0311    img.calc_colours.mapped_colour = 0;
0312    img.elem_data = [-2;1;3];
0313    cm= reshape([ 0, 0.9, 0.9; 0, 0.9, 0.0643; 0.27, 0.9, 0]',[3,1,3]);
0314    unit_test_cmp('cc03', calc_colours(img), cm,1e-3)
0315 
0316    img.calc_colours.greylev =  .1;
0317    cm= reshape([ 0.73, 1.0, 1.0; 0.1, 0.1, 0.1; 1.0, 0.9357, 0.1],[3,1,3]);
0318    unit_test_cmp('cc04', calc_colours(img), cm,1e-3)
0319 
0320    calc_colours('greylev',0);
0321    calc_colours('sat_adj',1);
0322    calc_colours('mapped_colour',4);
0323    calc_colours('backgnd',[0.5,0.5,0.5]);
0324    cc= calc_colours('colourmap');
0325    unit_test_cmp('cc05',cc, [2,2,2;4,4,4;2,4,4;0,1,4;0,0,0;4,1,0;4,4,2;4,4,4]/4,1e-4);
0326 
0327 % TESTS TO WRITE
0328 %   'greylev'    (DEFAULT -.01)
0329 %   'sat_adj'    (DEFAULT .9)
0330 %   'window_range' (DEFAULT .9)
0331 %   'backgnd' ( DEFAULT [.5,.5,.15] )
0332 %   'ref_level' (DEFAULT 'auto')
0333 %   'mapped_colour' (DEFAULT 127)
0334 %   'npoints' (DEFAULT 64)
0335 %   'clim'    (DEFAULT [])
0336 %   'cmap_type'  (Default blue-red)
0337

Generated on Tue 09-Aug-2011 11:38:31 by m2html © 2005