Digital Image Processing Lecture10: MATLAB Example – Utility M-functions for Intensity Transformations Handling a variable number of inputs and/or outputs • To check the number of arguments into an M-function we use function nargin. n = nargin which returns the actual number of arguments input into the M-function. Similarly, function nargout is used in connection with the outputs of an Mfunction. The syntax is: n = nargout Handling a variable number of inputs and/or outputs • For example, suppose that we execute the following M-function at the prompt: >> T = testhv(4,5); Use of nargin within the body of this function would return a 2, while use of nargout would return 1. Handling a variable number of inputs and/or outputs • Function nargchk can be used in the body of an M-function to check if the correct number of arguments were passed. The syntax is: msg = nargchk (low, high, number) This function returns the message “Not enough input parameters” if number is less than low, or “Two many input parameters” if number is greater than high. If number is between low and high, nargchk returns an empty matrix. Handling a variable number of inputs and/or outputs • A frequent use of function nargchk is to stop execution via the error function if the incorrect number of arguments is input. The number of actual arguments is determined by the nargin function. • For example, consider the following code fragment: function G = test (x, y, z) …. error (nargchk (2,3, nargin) … now, when typing: >> test (6); Which has only one input argument would produce the error. “Not enough input arguments” and execution would terminate. Handling a variable number of inputs and/or outputs • Often it is useful to be able to write functions in which the number of input and/or output arguments is variable. For this we use the variables varargin and varargout. For example: function [m, n] = test (varargin) accepts a variable number of inputs into function test, and function [varargout] = test (m, n, p) returns a variable number of outputs from function test. If function test had, say, one fixed input argument, x, followed by a variable number of input arguments, then function [m, n] = test (x, varargin) would cause varargin to start with the second input argument supplied by the user when the function is called. Handling a variable number of inputs and/or outputs • It is acceptable to have a function in which both the number of input and output arguments is variable. • When varargin is used as the input argument of a function, MATLAB sets it to a cell array (def. A cell array is a datatype with index data containers called cells. Each cell can contain any type of data. Cell array commonly contain lists of text strings, combination of text and numbers or numeric arrays of different sizes) that accepts a variable number of inputs by the user. • Because varargin is a cell array, an important aspect of this arrangement is that the call to the function can contain a mixed set of inputs. For example, we can call test function as follows: >> [m, n] = test (f, [0 0.5 1.5], A, ‘label’); Handling a variable number of inputs and/or outputs • where f is an image, the next argument is a row vector of length 3, A is a matrix, and ‘label’ is a character string. This is indeed a powerful feature that can be used to simplify the structure of functions requiring a variety of different inputs. Similar comments apply to varargout. An M-function for intensity transformation • In this section, we develop a function that computes the following transformation functions: negative, log, gamma and contrast stretching. • In writing this function we use function changeclass, which has the syntax g = changeclass (newclass, f) This function converts image f to the class specified in parameter newclass and outputs it as g. Valid values for newclass are ‘uint8’, ‘uin16’ and ‘double’ An M-function for intensity transformation function image = changeclass (class, varargin) %CHANGECLASS changes the storage class of an image % I2 = CHANGECLASS(CLASS, I); % RGB2 = CHANGECLASS(CLASS, RGB); % BW2 = CHANGECLASS(CLASS, BW); % X2 = CHANGECLASS(CLASS, X, 'indexed'); % Copyright 1993-2002 The MathWorks, Inc. Used with permission. switch class case 'uint8' image = im2uint8 (varargin{:}); case 'uint16' image = im2uint16 (varargin {:}); case 'double' image = im2double(varargin {:}); otherwise error ('Unsupported IPT data class'); end An M-function for intensity transformation • Note in the following M-function, which we call intrans, how function operations are formatted in the Help section of the code, how a variable number of inputs is handled, how error checking is interleaved in the code, and how the class of the output image is matched to the class of the input. Keep in mind when studying the following code that varargin is a cell array, so its elements are selected by using curly brackets {}. An M-function for intensity transformation • • • • • • • • • • • • function g = intrans (f, varargin) %INTRANS performs intensity (gray-level) transformations. % G = INTRANS (F, 'neg') computes the negative of input image F. % % G = INTRANS(F, 'log', C, CLASS) computes C*log(1+F) and multiplies % the result by (positive) constant C. If the last two parameters are % omitted, C defaults to 1. Parameter CLASS offers the option to specify % the class of the output as 'uint8' or 'uint16'. if parameter CLASS is % omitted, the output is of the same class as the input. % % G = INTRANS(F, 'gamma', GAM) performs a gamma transformation on the % input image using parameter GAM (a required input). An M-function for intensity transformation • • • • • • • • • • • • • • % % % % % % % % % G = INTRANS(F, 'stretch', M, E) computes a contrast-stretching transformation using the expression 1./(1+ (M./(F + eps)).^E). Parameter M must be in the range [0 1]. the default value for M is mean2 (im2double(F)), and the default value for E is 4 For the 'neg', 'gamma' and 'stretch' transformations, double input images whose maximum value is greater than 1 are scaled first using MAT2GRAY. Other images are converted to double first using IM2DOUBLE. % for the 'log' transformation, double images are transfortmed without % being scaled; % % the output is of the same class as the input, except if a different % class is specified for the 'log' option. An M-function for intensity transformation • • % Verify the correct number of inputs error (nargchk (2, 4, nargin) • • % Store the class of the input for use later. classin = class (f); • • • • • • • • • % If the input is of class double, and it is outside the range % [0 1], and the specified transformation is not 'log', convert the % input to the range [0 1]. if strcmp(class(f), 'double') & max(f(:)) > 1 & ... - strcmp(varargin{1}, 'log') f = mat2gray(f); else % Convert to double, regardless of class (f) f = im2double(f); end An M-function for intensity transformation • • % Determine the type of transformation specified. method = varargin {1}; • • • • % Perform the intensity transformation specified. switch method case 'neg' g = imcompelment (f); An M-function for intensity transformation • • • • • • • • • • • • case 'log' if length(varargin) == 1 c = 1; elseif length(varargin) == 2 c = varargin{2}; elseif length(varargin) == 3 c = varargin {2}; classin = varargin{3}; else error ('Incorrect number of inputs for the log option') end g = c*(log(1 + double(f))); An M-function for intensity transformation • • • • • • • • case 'gamma' if length(varargin) < 2 error ('Not enough inputs for the gamma option') end gam = varargin {2}; g = imadjust (f, [ ], [ ], gam); An M-function for intensity transformation • • • • • • • • • • • • • • • case 'stretch' if length(varargin) == 1 % Use defaults. m = mean2(f); E = 4.0; elseif length(varargin) == 3 m = varargin {2}; E = varargin {3}; else error ('Incorrect number of inputs for the stretch option.') end g = 1./(1 + (m./(f + eps)).^E); otherwise error ('Unknown enhancement method') end An M-function for intensity transformation • • % Convert to the class of the input image. g = changeclass (classin, g);