changeset 15687:89c8d8f8f87b

rgb2ind: find unique RGB values for indexed image and scale colormap for correct range
author Carnë Draug <carandraug+dev@gmail.com>
date Sun, 11 Nov 2012 04:48:36 +0000
parents fb9dffe5fbfb
children 4db08f52a6ed
files scripts/image/rgb2ind.m
diffstat 1 files changed, 29 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/image/rgb2ind.m	Fri Nov 09 20:29:21 2012 -0700
+++ b/scripts/image/rgb2ind.m	Sun Nov 11 04:48:36 2012 +0000
@@ -1,4 +1,5 @@
 ## Copyright (C) 1994-2012 John W. Eaton
+## Copyright (C) 2012 Carnë Draug
 ##
 ## This file is part of Octave.
 ##
@@ -50,16 +51,34 @@
     error ("rgb2ind: arguments must all have the same size");
   endif
 
-  [hi, wi] = size (R);
-
-  x = zeros (hi, wi);
-
-  map = zeros (hi*wi, 3);
+  map = unique([R(:) G(:) B(:)], "rows");
+  ## RGB values for each point of the image are listed and expanded to compare
+  ## with the colormap values. We then find the indexes when all 3 match and
+  ## rebuild the image to its original size
+  [x, ~] = find (squeeze (all (bsxfun (@eq, reshape(map', [1 3 rows(map)]), [R(:) G(:) B(:)]), 2))');
+  x = reshape (x, size (R));
 
-  map(:,1) = R(:);
-  map(:,2) = G(:);
-  map(:,3) = B(:);
+  ## a colormap is of class double and values between 0 and 1
+  switch class (R)
+    case {"single", "double", "logical"}
+      ## do nothing, return the same
+    case {"uint8", "uint16"}
+      map = double (map) / double (intmax (class (R)));
+    case "int16"
+      map = (double (im) + 32768) / 65535;
+    otherwise
+      error ("unsupported image class %s", im_class);
+  endswitch
 
-  x(:) = 1:(hi*wi);
-
+  ## we convert to the smallest class necessary to encode the image. Matlab
+  ## documentation does not mention what it does when uint16 is not enough...
+  ## When an indexed image is of integer class, there's a -1 offset to the
+  ## colormap, hence the adjustment
+  if (rows (map) < 256)
+    x = uint8 (x - 1);
+  elseif (rows (map) < 65536)
+    x = uint16 (x - 1);
+  else
+    ## leave it as double
+  endif
 endfunction