diff scripts/image/rgb2hsv.m @ 15683:806ea52af230

Overhaul m-files in image directory to provide better support for images stored as integers. * NEWS: Add note about overhaul of image scripts to support integer classes. * brighten.m: Add demo. * colormap.m: Better input validation. * contrast.m: Re-position window in demo. * gray2ind.m: Redo docstring. Match variables in docstring to function prototype. Better input validation. Return integer class outputs as Matlab does. Add %!tests. * hsv2rgb.m: Add to docstring. Better input validation. Redo algorithm to get rido of obsolete matrix-fill methods like kron(). Add %!tests. * image.m: Redo docstring. Match variables in docstring to function prototype. Better input validation without using for loops. * imagesc.m: Redo docstring. Match variables in docstring to function prototype. Remove DEPRECATEDZOOM functionality. Add demos. * imfinfo.m: Redo docstring. * ind2gray.m: Redo docstring. Match variables in docstring to function prototype. Redo algorithm to directly calculate luminance value rather than getting it from rgb2ntsc. Add %!tests. * ind2rgb.m: Redo docstring. Better input validation. Add some %!tests. * ntsc2rgb.m: Redo docstring. Better input validation. Add %!tests. * rgb2hsv.m: Better input validation. Add %!tests. * rgb2ind.m: Better input validation. Code algorithm in cleaner method for ease of understanding. * rgb2ntsc.m: Redo docstring: Better input validation. Add some %!tests.
author Rik <rik@octave.org>
date Tue, 27 Nov 2012 16:38:13 -0800
parents 1f911333ed3d
children b1cd65881592
line wrap: on
line diff
--- a/scripts/image/rgb2hsv.m	Mon Nov 26 12:09:09 2012 -0500
+++ b/scripts/image/rgb2hsv.m	Tue Nov 27 16:38:13 2012 -0800
@@ -40,32 +40,39 @@
     print_usage ();
   endif
 
+  cls = class (rgb);
+  if (! any (isa (rgb, {"uint8", "uint16", "single", "double"})))
+    error ("rgb2hsv: invalid data type '%s'", cls);
+  elseif (isfloat (rgb) && (any (rgb(:) < 0) || any (rgb(:) > 1)))
+    error ("rgb2hsv: floating point images may only contain values between 0 and 1");
+  endif
+
   ## If we have an image convert it into a color map.
-  if (ismatrix (rgb) && ndims (rgb) == 3)
+  if (isreal (rgb) && ndims (rgb) == 3)
     is_image = true;
-    Sz = size (rgb);
+    sz = size (rgb);
     rgb = [rgb(:,:,1)(:), rgb(:,:,2)(:), rgb(:,:,3)(:)];
     ## Convert to a double image.
     if (isinteger (rgb))
-      C = class (rgb);
-      low = double (intmin (C));
-      high = double (intmax (C));
+      cls = class (rgb);
+      low = double (intmin (cls));
+      high = double (intmax (cls));
       rgb = (double (rgb) - low) / (high - low);
     endif
   else
     is_image = false;
   endif
 
-  if (! ismatrix (rgb) || columns (rgb) != 3)
-    error ("rgb2hsv: RGB_MAP must be a matrix of size n x 3");
+  if (! ismatrix (rgb) || columns (rgb) != 3 || issparse (rgb))
+    error ("rgb2hsv: input must be a matrix of size Nx3");
   endif
 
-  ## get the max and min
-  s = min (rgb')';
-  v = max (rgb')';
+  ## get the max and min for each row
+  s = min (rgb, [], 2);
+  v = max (rgb, [], 2);
 
   ## set hue to zero for undefined values (gray has no hue)
-  h = zeros (size (v));
+  h = zeros (rows (rgb), 1);
   notgray = (s != v);
 
   ## blue hue
@@ -85,10 +92,7 @@
   if (any (idx))
     h(idx) =       1/6 * (rgb(idx,2) - rgb(idx,3)) ./ (v(idx) - s(idx));
   endif
-
-  ## correct for negative red
-  idx = (h < 0);
-  h(idx) = 1+h(idx);
+  h(h < 0) += 1;   # correct for negative red
 
   ## set the saturation
   s(! notgray) = 0;
@@ -98,7 +102,29 @@
 
   ## If input was an image, convert it back into one.
   if (is_image)
-    hsv_map = reshape (hsv_map, Sz);
+    hsv_map = reshape (hsv_map, sz);
   endif
 
 endfunction
+
+
+%% Test pure colors and gray
+%!assert (rgb2hsv ([1 0 0]), [0 1 1])
+%!assert (rgb2hsv ([0 1 0]), [1/3 1 1])
+%!assert (rgb2hsv ([0 0 1]), [2/3 1 1])
+%!assert (rgb2hsv ([0.5 0.5 0.5]), [0 0 0.5])
+
+%!test
+%! rgb_map = rand (64, 3);
+%! assert (hsv2rgb (rgb2hsv (rgb_map)), rgb_map, 1e-6);
+
+%!test
+%! rgb_img = rand (64, 64, 3);
+%! assert (hsv2rgb (rgb2hsv (rgb_img)), rgb_img, 1e-6);
+
+%% Test input validation
+%!error rgb2hsv ()
+%!error rgb2hsv (1,2)
+%!error <invalid data type 'cell'> rgb2hsv ({1})
+%!error <must be a matrix of size Nx3> rgb2hsv (ones (2,2))
+