From: Josep M. i T. <jm...@us...> - 2004-09-03 17:07:35
|
Update of /cvsroot/octave/octave-forge/main/image In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24308 Modified Files: cmunique.m Log Message: Support for uint8 and uint16 types added. Index: cmunique.m =================================================================== RCS file: /cvsroot/octave/octave-forge/main/image/cmunique.m,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- cmunique.m 17 Aug 2004 15:48:03 -0000 1.2 +++ cmunique.m 3 Sep 2004 17:07:26 -0000 1.3 @@ -38,11 +38,16 @@ ## colormap possible (alhough it could be as long as number of pixels ## in image). ## -## @strong{Compatibility notes:} +## @strong{Notes:} ## -## @var{Y} and @var{newmap} are always of class double, since support -## for uint types isn't available yet. This will change from Octave -## version 2.1.58 on. +## @var{newmap} is always a @var{m}-by-3 matrix, even if input image is +## a intensity grey-scale image @var{I} (all three RGB planes are +## assigned the same value). +## +## @var{newmap} is always of class double. If we use a RGB or intensity +## image of class uint8 or uint16, the colors in the colormap will be of +## class double in the range [0,1] (they are divided by intmax("uint8") +## and intmax("uint16") respectively. ## ## @end deftypefn @@ -58,21 +63,39 @@ if(nargin==2) ## (X, map) case [newmap,i,j]=unique(P2,'rows'); ## calculate unique colormap - Y=j(P1); ## find new indices - elseif(length(size(P1))==2) ## workaround for size(P1,3)==1 - ## I case - [newmap,i,j]=unique(P1); ## calculate unique colormap - Y=reshape(j,rows(P1),columns(P1)); ## Y is j reshaped - elseif(size(P1,3)==3) - ## RGB case - map=[P1(:,:,1)(:), P1(:,:,2)(:), P1(:,:,3)(:)]; ## build a map with all values - [newmap,i,j]=unique(map, 'rows'); ## calculate unique colormap - Y=reshape(j,rows(P1),columns(P1)); ## Y is j reshaped + if(isa(P1,"uint8") || isa(P1,"uint16")) ## old indices are 0-based + Y=j(P1+1); ## find new indices + else + Y=j(P1); ## find new indices + endif else - error("cmunique: first parameter is invalid."); + switch(size(P1,3)) + case(1) + ## I case + [newmap,i,j]=unique(P1); ## calculate unique colormap + newmap=repmat(newmap,1,3); ## get a RGB colormap + Y=reshape(j,rows(P1),columns(P1)); ## Y is j reshaped + case(3) + ## RGB case + map=[P1(:,:,1)(:), P1(:,:,2)(:), P1(:,:,3)(:)]; ## build a map with all values + [newmap,i,j]=unique(map, 'rows'); ## calculate unique colormap + Y=reshape(j,rows(P1),columns(P1)); ## Y is j reshaped + otherwise + error("cmunique: first parameter is invalid."); + endswitch + + ## if image was uint8 or uint16 we have to convert newmap to [0,1] range + if(isa(P1,"uint8") || isa(P1,"uint16")) + newmap=double(newmap)/double(intmax(class(P1))); + endif endif - ## TODO: handle uint types when available + if(rows(newmap)<=256) + ## convert Y to uint8 (0-based indices then) + Y=uint8(Y-1); + endif + + endfunction @@ -85,28 +108,87 @@ %!# This triggers invalid first parameter %!error(cmunique(zeros(3,3,2))); +%!# Check that output is uint8 in short colormaps %!test %! [Y,newmap]=cmunique([1:4;5:8], [hot(4);hot(4)]); -%! assert(Y,[1:4;1:4]); +%! assert(Y,uint8([0:3;0:3])); %! assert(newmap,hot(4)); +%!# Check that output is double in bigger +%!test +%! [Y,newmap]=cmunique([1:300;301:600], [hot(300);hot(300)]); +%! assert(Y,[1:300;1:300]); +%! assert(newmap,hot(300)); + +%!# Check boundary case 256 +%!test +%! [Y,newmap]=cmunique([1:256;257:512], [hot(256);hot(256)]); +%! assert(Y,uint8([0:255;0:255])); +%! assert(newmap,hot(256)); + +%!# Check boundary case 257 +%!test +%! [Y,newmap]=cmunique([1:257;258:514], [hot(257);hot(257)]); +%! assert(Y,[1:257;1:257]); +%! assert(newmap,hot(257)); + %!# Random RGB image %!test %! RGB=rand(10,10,3); %! [Y,newmap]=cmunique(RGB); -%! assert(RGB(:,:,1),newmap(:,1)(Y)); -%! assert(RGB(:,:,2),newmap(:,2)(Y)); -%! assert(RGB(:,:,3),newmap(:,3)(Y)); +%! assert(RGB(:,:,1),newmap(:,1)(Y+1)); +%! assert(RGB(:,:,2),newmap(:,2)(Y+1)); +%! assert(RGB(:,:,3),newmap(:,3)(Y+1)); + +%!# Random uint8 RGB image +%!test +%! RGB=uint8(rand(10,10,3)*255); +%! RGBd=double(RGB)/255; +%! [Y,newmap]=cmunique(RGB); +%! assert(RGBd(:,:,1),newmap(:,1)(Y+1)); +%! assert(RGBd(:,:,2),newmap(:,2)(Y+1)); +%! assert(RGBd(:,:,3),newmap(:,3)(Y+1)); + +%!# Random uint16 RGB image +%!test +%! RGB=uint16(rand(10,10,3)*65535); +%! RGBd=double(RGB)/65535; +%! [Y,newmap]=cmunique(RGB); +%! assert(RGBd(:,:,1),newmap(:,1)(Y+1)); +%! assert(RGBd(:,:,2),newmap(:,2)(Y+1)); +%! assert(RGBd(:,:,3),newmap(:,3)(Y+1)); %!# Random I image %!test %! I=rand(10,10); %! [Y,newmap]=cmunique(I); -%! assert(I,newmap(Y)); +%! assert(I,newmap(:,1)(Y+1)); +%! assert(I,newmap(:,2)(Y+1)); +%! assert(I,newmap(:,3)(Y+1)); +%!# Random uint8 I image +%!test +%! I=uint8(rand(10,10)*255); +%! Id=double(I)/255; +%! [Y,newmap]=cmunique(I); +%! assert(Id,newmap(:,1)(Y+1)); +%! assert(Id,newmap(:,2)(Y+1)); +%! assert(Id,newmap(:,3)(Y+1)); + +%!# Random uint16 I image +%!test +%! I=uint16(rand(10,10)*65535); +%! Id=double(I)/65535; +%! [Y,newmap]=cmunique(I); +%! assert(Id,newmap(:,1)(Y+1)); +%! assert(Id,newmap(:,2)(Y+1)); +%! assert(Id,newmap(:,3)(Y+1)); % % $Log$ +% Revision 1.3 2004/09/03 17:07:26 jmones +% Support for uint8 and uint16 types added. +% % Revision 1.2 2004/08/17 15:48:03 jmones % Clarified expected data for RGB images in doc % |