changeset 1684:c33e02c85731 octave-forge

Support for uint8 and uint16 types added.
author jmones
date Fri, 03 Sep 2004 17:07:26 +0000
parents 6b33b21b5f59
children 4c185446f79e
files main/image/cmunique.m
diffstat 1 files changed, 103 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/main/image/cmunique.m	Fri Sep 03 14:25:39 2004 +0000
+++ b/main/image/cmunique.m	Fri Sep 03 17:07:26 2004 +0000
@@ -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
 %