function f = makeimagestack(m,wantnorm,addborder,csize,bordersize) <m> is a 3D matrix. if more than 3D, we reshape to be 3D. we automatically convert to double format for the purposes of this function. <wantnorm> (optional) is 0 means no normalization [A B] means normalize and threshold values such that A and B map to 0 and 1. X means normalize and threshold values such that X percentile from lower and upper end map to 0 and 1. if the X percentile from the two ends are the same, then map everything to 0. -1 means normalize to 0 and 1 using -max(abs(m(:))) and max(abs(m(:))) -2 means normalize to 0 and 1 using 0 and max(m(:)) -3 means normalize to 0 and 1 using min(m(:)) and max(m(:)) default: 0. <addborder> (optional) is 0 means do not add border 1 means add border at the right and bottom of each image. the border is assigned the maximum value. 2 means like 1 but remove the final borders at the right and bottom. -1 means like 1 but assign the border the middle value instead of the max. -2 means like 2 but assign the border the middle value instead of the max. j means like 1 but assign the border a value of 0. 2*j means like 2 but assign the border a value of 0. NaN means plot images into figure windows instead of returning a matrix. each image is separated by one matrix element from surrounding images. in this case, <wantnorm> should not be 0. default: 1. <csize> (optional) is [X Y], a 2D matrix size according to which we concatenate the images (row then column). default is [], which means try to make as square as possible (e.g. for 16 images, we would use [4 4]). special case is -1 which means use [1 size(m,3)]. another special case is [A 0] or [0 A] in which case we set 0 to be the minimum possible to fit all the images in. <bordersize> (optional) is number of pixels in the border in the case that <addborder> is not NaN. default: 1. if <addborder> is not NaN, then return a 3D matrix. the first two dimensions contain images concatenated together, with any extra slots getting filled with the minimum value. the third dimension contains additional sets of images (if necessary). if <addborder> is NaN, then make a separate figure window for each set of images. (actually, we create new figure windows only for sets after the first set. so the we attempt to draw the first set in the current figure window.) in each figure window, we plot individual images using imagesc scaled to the range [0,1]. we return <f> as []. example: a = randn(10,10,12); imagesc(makeimagestack(a,-1)); imagesc(makeimagestack(a,-1,NaN));
0001 function f = makeimagestack(m,wantnorm,addborder,csize,bordersize) 0002 0003 % function f = makeimagestack(m,wantnorm,addborder,csize,bordersize) 0004 % 0005 % <m> is a 3D matrix. if more than 3D, we reshape to be 3D. 0006 % we automatically convert to double format for the purposes of this function. 0007 % <wantnorm> (optional) is 0008 % 0 means no normalization 0009 % [A B] means normalize and threshold values such that A and B map to 0 and 1. 0010 % X means normalize and threshold values such that X percentile 0011 % from lower and upper end map to 0 and 1. if the X percentile 0012 % from the two ends are the same, then map everything to 0. 0013 % -1 means normalize to 0 and 1 using -max(abs(m(:))) and max(abs(m(:))) 0014 % -2 means normalize to 0 and 1 using 0 and max(m(:)) 0015 % -3 means normalize to 0 and 1 using min(m(:)) and max(m(:)) 0016 % default: 0. 0017 % <addborder> (optional) is 0018 % 0 means do not add border 0019 % 1 means add border at the right and bottom of each image. 0020 % the border is assigned the maximum value. 0021 % 2 means like 1 but remove the final borders at the right and bottom. 0022 % -1 means like 1 but assign the border the middle value instead of the max. 0023 % -2 means like 2 but assign the border the middle value instead of the max. 0024 % j means like 1 but assign the border a value of 0. 0025 % 2*j means like 2 but assign the border a value of 0. 0026 % NaN means plot images into figure windows instead of returning a matrix. 0027 % each image is separated by one matrix element from surrounding images. 0028 % in this case, <wantnorm> should not be 0. 0029 % default: 1. 0030 % <csize> (optional) is [X Y], a 2D matrix size according 0031 % to which we concatenate the images (row then column). 0032 % default is [], which means try to make as square as possible 0033 % (e.g. for 16 images, we would use [4 4]). 0034 % special case is -1 which means use [1 size(m,3)]. 0035 % another special case is [A 0] or [0 A] in which case we 0036 % set 0 to be the minimum possible to fit all the images in. 0037 % <bordersize> (optional) is number of pixels in the border in the case that 0038 % <addborder> is not NaN. default: 1. 0039 % 0040 % if <addborder> is not NaN, then return a 3D matrix. the first two dimensions 0041 % contain images concatenated together, with any extra slots getting filled 0042 % with the minimum value. the third dimension contains additional sets of images 0043 % (if necessary). 0044 % 0045 % if <addborder> is NaN, then make a separate figure window for each set of images. 0046 % (actually, we create new figure windows only for sets after the first set. so the 0047 % we attempt to draw the first set in the current figure window.) in each figure window, 0048 % we plot individual images using imagesc scaled to the range [0,1]. 0049 % we return <f> as []. 0050 % 0051 % example: 0052 % a = randn(10,10,12); 0053 % imagesc(makeimagestack(a,-1)); 0054 % imagesc(makeimagestack(a,-1,NaN)); 0055 0056 % input 0057 if ~exist('wantnorm','var') || isempty(wantnorm) 0058 wantnorm = 0; 0059 end 0060 if ~exist('addborder','var') || isempty(addborder) 0061 addborder = 1; 0062 end 0063 if ~exist('csize','var') || isempty(csize) 0064 csize = []; 0065 end 0066 if ~exist('bordersize','var') || isempty(bordersize) 0067 bordersize = 1; 0068 end 0069 0070 % calc 0071 nrows = size(m,1); 0072 ncols = size(m,2); 0073 0074 % make double if necessary 0075 m = double(m); 0076 wantnorm = double(wantnorm); 0077 0078 % make <m> 3D if necessary 0079 m = reshape(m,size(m,1),size(m,2),[]); 0080 0081 % find range, normalize 0082 if length(wantnorm)==2 0083 m = normalizerange(m,0,1,wantnorm(1),wantnorm(2)); 0084 mn = 0; 0085 mx = 1; 0086 elseif wantnorm==0 0087 mn = nanmin(m(:)); 0088 mx = nanmax(m(:)); 0089 elseif wantnorm==-1 0090 m = normalizerange(m,0,1,-max(abs(m(:))),max(abs(m(:)))); 0091 mn = 0; 0092 mx = 1; 0093 elseif wantnorm==-2 0094 m = normalizerange(m,0,1,0,max(m(:))); 0095 mn = 0; 0096 mx = 1; 0097 elseif wantnorm==-3 0098 m = normalizerange(m,0,1,min(m(:)),max(m(:))); 0099 mn = 0; 0100 mx = 1; 0101 else 0102 rng = prctile(m(:),[wantnorm 100-wantnorm]); 0103 if rng(2)==rng(1) 0104 m = zeros(size(m)); % avoid error from normalizerange.m 0105 else 0106 m = normalizerange(m,0,1,rng(1),rng(2)); 0107 end 0108 mn = 0; 0109 mx = 1; 0110 end 0111 md = (mn+mx)/2; 0112 0113 % number of images 0114 numim = size(m,3); 0115 0116 % calculate csize if necessary 0117 if isempty(csize) 0118 rows = floor(sqrt(numim)); % MAKE INTO FUNCTION? 0119 cols = ceil(numim/rows); 0120 csize = [rows cols]; 0121 elseif isequal(csize,-1) 0122 csize = [1 numim]; 0123 elseif csize(1)==0 0124 csize(1) = ceil(numim/csize(2)); 0125 elseif csize(2)==0 0126 csize(2) = ceil(numim/csize(1)); 0127 end 0128 0129 % calc 0130 chunksize = prod(csize); 0131 numchunks = ceil(numim/chunksize); 0132 0133 % convert to cell vector, add some extra matrices if necessary 0134 m = splitmatrix(m,3); 0135 m = [m repmat({repmat(mn,size(m{1}))},1,numchunks*chunksize-numim)]; 0136 0137 % figure case 0138 if isnan(addborder) 0139 0140 for p=1:numchunks 0141 if p ~= 1 0142 drawnow; figure; 0143 end 0144 hold on; 0145 for q=1:chunksize 0146 xx = linspace(1+(ceil(q/csize(1))-1)*(ncols+1),ncols+(ceil(q/csize(1))-1)*(ncols+1),ncols); 0147 yy = linspace(1+(mod2(q,csize(1))-1)*(nrows+1),nrows+(mod2(q,csize(1))-1)*(nrows+1),nrows); 0148 imagesc(xx,yy,m{(p-1)*chunksize+q},[0 1]); 0149 end 0150 axis equal; 0151 set(gca,'YDir','reverse'); 0152 end 0153 f = []; 0154 0155 % matrix case 0156 else 0157 0158 % add border? 0159 if imag(addborder) || addborder 0160 for p=1:length(m) 0161 m{p}(end+(1:bordersize),:) = choose(imag(addborder),0,choose(addborder > 0,mx,md)); 0162 m{p}(:,end+(1:bordersize)) = choose(imag(addborder),0,choose(addborder > 0,mx,md)); 0163 end 0164 end 0165 0166 % combine images 0167 f = []; 0168 for p=1:numchunks 0169 temp = m((p-1)*chunksize + (1:chunksize)); 0170 f = cat(3,f,cell2mat(reshape(temp,csize))); 0171 end 0172 0173 % remove final? 0174 if abs(addborder)==2 0175 f(end-bordersize+1:end,:,:) = []; 0176 f(:,end-bordersize+1:end,:) = []; 0177 end 0178 0179 end