diff scripts/image/rgb2ntsc.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/rgb2ntsc.m	Mon Nov 26 12:09:09 2012 -0500
+++ b/scripts/image/rgb2ntsc.m	Tue Nov 27 16:38:13 2012 -0800
@@ -19,8 +19,24 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{yiq_map} =} rgb2ntsc (@var{rgb_map})
 ## @deftypefnx {Function File} {@var{yiq_img} =} rgb2ntsc (@var{rgb_img})
-## Transform a colormap or image from red-green-blue (RGB) space to
+## Transform a colormap or image from red-green-blue (RGB) color space to
 ## luminance-chrominance (NTSC) space.
+##
+## Implementation Note:
+## The reference matrix for the transformation is
+##
+## @example
+## @group
+## /Y\     0.299  0.587  0.114  /R\ 
+## |I|  =  0.596 -0.274 -0.322  |G| 
+## \Q/     0.211 -0.523  0.312  \B/ 
+## @end group
+## @end example
+##
+## @noindent
+## as documented in @url{http://en.wikipedia.org/wiki/YIQ} and truncated to 3
+## significant figures.  Note: The FCC version of NTSC uses only 2
+## significant digits and is slightly different.
 ## @seealso{ntsc2rgb, rgb2hsv, rgb2ind}
 ## @end deftypefn
 
@@ -34,36 +50,64 @@
     print_usage ();
   endif
 
+  cls = class (rgb);
+  if (! any (isa (rgb, {"uint8", "uint16", "single", "double"})))
+    error ("rgb2ntsc: invalid data type '%s'", cls);
+  elseif (isfloat (rgb) && (any (rgb(:) < 0) || any (rgb(:) > 1)))
+    error ("rgb2ntsc: 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));
+      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)
+  if (! ismatrix (rgb) || columns (rgb) != 3 || issparse (rgb))
     error ("rgb2ntsc: argument must be a matrix of size Nx3 or NxMx3");
   endif
 
-  ## Convert data
+  ## Reference matrix for transformation from http://en.wikipedia.org/wiki/YIQ
+  ## and truncated to 3 significant figures.  Matlab uses this matrix for their
+  ## conversion.
   trans = [ 0.299,  0.596,  0.211;
             0.587, -0.274, -0.523;
             0.114, -0.322,  0.312 ];
 
+  ## Convert data. 
   yiq = rgb * trans;
 
   ## If input was an image, convert it back into one.
   if (is_image)
-    yiq = reshape (yiq, Sz);
+    yiq = reshape (yiq, sz);
   endif
 
 endfunction
+
+
+%% Test RED conversion
+%assert (rgb2ntsc ([1 0 0]), [0.299 0.587 0.114])
+
+%!test
+%! rgb_map = rand (64, 3);
+%! assert (ntsc2rgb (rgb2ntsc (rgb_map)), rgb_map, 1e-3);
+
+%!test
+%! rgb_img = rand (64, 64, 3);
+%! assert (ntsc2rgb (rgb2ntsc (rgb_img)), rgb_img, 1e-3);
+
+%% Test input validation
+%!error rgb2ntsc ()
+%!error rgb2ntsc (1,2)
+%!error <invalid data type 'cell'> rgb2ntsc ({1})
+%!error <must be a matrix of size Nx3 or NxMx3> rgb2ntsc (ones (2,2))
+