changeset 885:40269ff6760d

imcast: new function to convert image between arbitrary classes. * imcast.m: new function acting as wrapper for im2double, im2single, im2uint8, im2uint16, and im2int16. * imcast.m, imnoise.m, imrotate.m: replace ugly hack using feval with call to imcast. * COPYING: specify license of new function. * INDEX: add new function. * NEWS: add note about new function for release 2.4.0.
author Carnë Draug <carandraug@octave.org>
date Tue, 18 Mar 2014 00:51:13 +0000
parents 0ed283edee13
children a0c42a32c6c4
files COPYING INDEX NEWS inst/imcast.m inst/imnoise.m inst/imrotate.m
diffstat 6 files changed, 100 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/COPYING
+++ b/COPYING
@@ -73,6 +73,7 @@
 inst/imadd.m                            GPLv3+
 inst/imadjust.m                         GPLv3+
 inst/imbothat.m                         GPLv3+
+inst/imcast.m                           GPLv3+
 inst/imclose.m                          GPLv3+
 inst/imcomplement.m                     GPLv3+
 inst/imcrop.m                           GPLv3+
--- a/INDEX
+++ b/INDEX
@@ -133,6 +133,7 @@
  im2single
  im2uint8
  im2uint16
+ imcast
  imdither
  isbw
  isgray
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
  Summary of important user-visible changes for image 2.4.0 (yyyy/mm/dd):
 -------------------------------------------------------------------------
 
+ ** The following functions are new:
+
+      imcast
+
  ** The implementation of normxcorr2 has been changed. The new method is
     Matlab compatible and will return values in the range [-1 1].
 
new file mode 100644
--- /dev/null
+++ b/inst/imcast.m
@@ -0,0 +1,90 @@
+## Copyright (C) 2014 Carnë Draug <carandraug+dev@gmail.com>
+##
+## This program is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free Software
+## Foundation; either version 3 of the License, or (at your option) any later
+## version.
+##
+## This program is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public License along with
+## this program; if not, see <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} imcast (@var{img}, @var{type})
+## @deftypefnx {Function File} {} imcast (@var{img}, @var{type}, "indexed")
+## Convert image to specific data type @var{type}.
+##
+## This is the same as calling one of the following
+##
+## @itemize @bullet
+## @item im2double
+## @item im2int16
+## @item im2single
+## @item im2uint8
+## @item im2uint16
+## @end itemize
+##
+## @seealso{im2uint8, im2double, im2int16, im2single, im2uint16}
+## @end deftypefn
+
+function img = imcast (img, itype, varargin)
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  elseif (nargin == 3 && ! strcmpi (varargin{1}, "indexed"))
+    error ("imcast: third argument must be the string \"indexed\"");
+  endif
+
+  ## We could confirm that the image really is an indexed image in
+  ## case the user says so, but the functions im2xxx already do it.
+
+  switch itype
+    case "double",  img = im2double (img, varargin{:});
+    case "uint8",   img = im2uint8  (img, varargin{:});
+    case "uint16",  img = im2uint16 (img, varargin{:});
+    case "single",  img = im2single (img, varargin{:});
+    case "int16",   img = im2int16  (img, varargin{:});
+    otherwise
+      error ("imcast: unsupported TYPE \"%s\"", itype);
+  endswitch
+
+endfunction
+
+%!test
+%! im = randi ([0 255], 40, "uint8");
+%! assert (imcast (im, "uint8"), im2uint8 (im))
+%! assert (imcast (im, "uint16"), im2uint16 (im))
+%! assert (imcast (im, "single"), im2single (im))
+%! assert (imcast (im, "uint8", "indexed"), im2uint8 (im, "indexed"))
+%! assert (imcast (im, "uint16", "indexed"), im2uint16 (im, "indexed"))
+%! assert (imcast (im, "single", "indexed"), im2single (im, "indexed"))
+
+%!test
+%! im = randi ([1 256], 40, "double");
+%! assert (imcast (im, "uint8"), im2uint8 (im))
+%! assert (imcast (im, "uint8", "indexed"), im2uint8 (im, "indexed"))
+%! assert (imcast (im, "single", "indexed"), im2single (im, "indexed"))
+
+%!test
+%! im = randi ([0 65535], 40, "uint16");
+%! assert (imcast (im, "uint8"), im2uint8 (im))
+%! assert (imcast (im, "single"), im2single (im))
+%! assert (imcast (im, "uint8", "indexed"), im2uint8 (im, "indexed"))
+%! assert (imcast (im, "single", "indexed"), im2single (im, "indexed"))
+
+%!test
+%! im = randi ([1 255], 40, "double");
+%! assert (imcast (im, "uint8", "indexed"), im2uint8 (im, "indexed"))
+%! assert (imcast (im, "single", "indexed"), im2single (im, "indexed"))
+
+%!test
+%! im = rand (40);
+%! assert (imcast (im, "uint8"), im2uint8 (im))
+
+%!error <unsupported TYPE> imcast (randi (255, 40, "uint8"), "uint32")
+%!error <unsupported TYPE> imcast (randi (255, 40, "uint8"), "not a class")
+
--- a/inst/imnoise.m
+++ b/inst/imnoise.m
@@ -105,16 +105,13 @@
   endswitch
 
   if (fix_class)
-    ## we probably should do this in a safer way... but hardcoding the list of
-    ## im2xxxx functions might not be a good idea since it then it requires to
-    ## be added here if a new im2xxx function is implemented
-    A = feval (["im2" in_class], A);
+    A = imcast (A, in_class);
   elseif (isfloat (A))
     ## this includes not even cases where the noise made it go outside of the
     ## [0 1] range, but also images that were already originally outside that
     ## range. This is by design and matlab compatibility. And we do this after
-    ## fixing class because the im2XX functions already take care of such
-    ## adjustemt
+    ## fixing class because the imcast functions already take care of such
+    ## adjustment
     A(A < 0) = cast (0, class (A));
     A(A > 1) = cast (1, class (A));
   endif
--- a/inst/imrotate.m
+++ b/inst/imrotate.m
@@ -154,10 +154,7 @@
     endif
     valid = NA;
 
-    ## we probably should do this in a safer way... but hardcoding the list of
-    ## im2xxxx functions might not be a good idea since it then it requires to
-    ## be added here if a new im2xxx function is implemented
-    imgPost = feval (["im2" in_class], imgPost);
+    imgPost = imcast (imgPost, in_class);
   else
     [imgPost, valid] = imperspectivewarp(imgPre, H, interp, bbox, extrapval);
   endif