changeset 514:5ba4d5438dfe

imadd: new function
author carandraug
date Fri, 09 Dec 2011 05:15:25 +0000
parents f228616f62ef
children a3b4ab8a60d3
files inst/imadd.m
diffstat 1 files changed, 89 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/inst/imadd.m
@@ -0,0 +1,89 @@
+## Copyright (C) 2011 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} {@var{out} =} imadd (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{out} =} imadd (@var{a}, @var{b}, @var{class})
+## Add image or constant to an image.
+##
+## If @var{a} and @var{b} are two images of same size and class, the images are
+## added. Alternatively, if @var{b} is a floating-point scalar, its value is added
+## to the image @var{a}.
+##
+## The class of @var{out} will be the same as @var{a} unless @var{a} is logical
+## in which case @var{out} will be double. Alternatively, the class can be
+## specified with @var{class}.
+##
+## Note that the values are truncated to the maximum value of the output class.
+## @end deftypefn
+
+function img = imadd (img, val, out_class = class (img))
+
+  if (nargin < 2 || nargin > 3)
+    print_usage;
+  elseif ((!isnumeric (img) && !islogical (img)) || isempty (img) || issparse (img) || !isreal (img))
+    error ("first argument must be a numeric or logical, non-empty, non-sparse real matrix")
+  elseif ((!isnumeric (val) && !islogical (val)) || isempty (val) || issparse (val) || !isreal (val))
+    error ("second argument must be a numeric, non-empty, non-sparse real matrix")
+  elseif (!ischar (out_class))
+    error ("third argument must be a string that specifies the output class")
+  endif
+
+  img_class = class (img);
+  if (all (size (img) == size (val)) && strcmpi (img_class, class (val)))
+    [img, val] = convert (out_class, img, val);
+  elseif (isscalar (val) && isfloat (val))
+    ## according to matlab's documentation, if val is not an image of same size
+    ## and class as img, then it must be a double scalar. But why not also support
+    ## a single scalar and use isfloat?
+    img = convert (out_class, img);
+  else
+    error ("second argument must either be of same class and size of the first or a floating point scalar")
+  end
+
+  ## output class is the same as input img, unless img is logical in which case
+  ## it should be double. In that case, I'm assuming that if both images are
+  ## logical, the addition is made as if they were doubles.
+  ## should ask someone to test the following in matlab:
+  ## a = logical([1 0 1 1]); b = logical([1 0 0 0]); c = imadd (a, b);
+  ## a = logical([1 0 1 1]); b = logical([1 0 1 1]); c = imadd (a, b, "logical");
+  ## what's important to check is:
+  ##    (1) is c(1) == 2 on the first example? Then addition is done img + val.
+  ##    (2) output class. If it is logical on the second example
+  ## also the following
+  ## a = uint16(round(rand(5)*300)); b = uint16(round(rand(5)*300)); c = imadd (a, b, "uint8")
+  ##  what happens when the request output class does not take even the values
+  ## of the input image? Is the requested for the class also honored?
+  img = img + val;
+
+endfunction
+
+function [a, b] = convert (out_class, a, b = 0)
+  ## in the case that we only want to convert one matrix, this subfunction is called
+  ## with 2 arguments only. Then, b takes the value of zero so that the call to the
+  ## functions that change the class is insignificant
+  if (!strcmpi (class (a), out_class))
+    switch tolower (out_class)
+      case {"logical"}  a = logical (a); b = logical (b);
+      case {"uint8"}    a = uint8   (a); b = uint8   (b);
+      case {"uint16"}   a = uint16  (a); b = uint16  (b);
+      case {"uint32"}   a = uint32  (a); b = uint32  (b);
+      case {"double"}   a = double  (a); b = double  (b);
+      case {"single"}   a = single  (a); b = single  (b);
+      otherwise
+        error ("requested class '%s' for output is not supported")
+    endswitch
+  endif
+endfunction