X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fimage-1.0.15%2Fimadjust.m;fp=octave_packages%2Fimage-1.0.15%2Fimadjust.m;h=f4b7d3a33fd50d3d2800222b2e2611b471b1e6e2;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/image-1.0.15/imadjust.m b/octave_packages/image-1.0.15/imadjust.m new file mode 100644 index 0000000..f4b7d3a --- /dev/null +++ b/octave_packages/image-1.0.15/imadjust.m @@ -0,0 +1,361 @@ +## Copyright (C) 2004 Josep Mones i Teixidor +## +## 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 2 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 . +## +## +## Based on old imadjust.m (GPL): +## Copyright (C) 1999,2000 Kai Habel + + +## -*- texinfo -*- +## @deftypefn {Function File} @var{J}= imadjust (@var{I}) +## @deftypefnx {Function File} @var{J}= imadjust (@var{I},[@var{low_in};@var{high_in}]) +## @deftypefnx {Function File} @var{J}= imadjust (@var{I},[@var{low_in};@var{high_in}],[@var{low_out};@var{high_out}]) +## @deftypefnx {Function File} @var{J}= imadjust (..., @var{gamma}) +## @deftypefnx {Function File} @var{newmap}= imadjust (@var{map}, ...) +## @deftypefnx {Function File} @var{RGB_out}= imadjust (@var{RGB}, ...) +## Adjust image or colormap values to a specified range. +## +## @code{J=imadjust(I)} adjusts intensity image @var{I} values so that +## 1% of data on lower and higher values (2% in total) of the image is +## saturated; choosing for that the corresponding lower and higher +## bounds (using @code{stretchlim}) and mapping them to 0 and 1. @var{J} +## is an image of the same size as @var{I} which contains mapped values. +## This is equivalent to @code{imadjust(I,stretchlim(I))}. +## +## @code{J=imadjust(I,[low_in;high_in])} behaves as described but uses +## @var{low_in} and @var{high_in} values instead of calculating them. It +## maps those values to 0 and 1; saturates values lower than first limit +## to 0 and values higher than second to 1; and finally maps all values +## between limits linearly to a value between 0 and 1. If @code{[]} is +## passes as @code{[low_in;high_in]} value, then @code{[0;1]} is taken +## as a default value. +## +## @code{J=imadjust(I,[low_in;high_in],[low_out;high_out])} behaves as +## described but maps output values between @var{low_out} and +## @var{high_out} instead of 0 and 1. A default value @code{[]} can also +## be used for this parameter, which is taken as @code{[0;1]}. +## +## @code{J=imadjust(...,gamma)} takes, in addition of 3 parameters +## explained above, an extra parameter @var{gamma}, which specifies the +## shape of the mapping curve between input elements and output +## elements, which is linear (as taken if this parameter is omitted). If +## @var{gamma} is above 1, then function is weighted towards lower +## values, and if below 1, towards higher values. +## +## @code{newmap=imadjust(map,...)} applies a transformation to a +## colormap @var{map}, which output is @var{newmap}. This transformation +## is the same as explained above, just using a map instead of an image. +## @var{low_in}, @var{high_in}, @var{low_out}, @var{high_out} and +## @var{gamma} can be scalars, in which case the same values are applied +## for all three color components of a map; or it can be 1-by-3 +## vectors, to define unique mappings for each component. +## +## @code{RGB_out=imadjust(RGB,...)} adjust RGB image @var{RGB} (a +## M-by-N-by-3 array) the same way as specified in images and colormaps. +## Here too @var{low_in}, @var{high_in}, @var{low_out}, @var{high_out} and +## @var{gamma} can be scalars or 1-by-3 matrices, to specify the same +## mapping for all planes, or unique mappings for each. +## +## The formula used to realize the mapping (if we omit saturation) is: +## +## @code{J = low_out + (high_out - low_out) .* ((I - low_in) / (high_in - low_in)) .^ gamma;} +## +## @strong{Compatibility notes:} +## +## @itemize @bullet +## @item +## Prior versions of imadjust allowed @code{[low_in; high_in]} and +## @code{[low_out; high_out]} to be row vectors. Compatibility with this +## behaviour has been keeped, although preferred form is vertical vector +## (since it extends nicely to 2-by-3 matrices for RGB images and +## colormaps). +## @item +## Previous version of imadjust, if @code{low_in>high_in} it "negated" output. +## Now it is negated if @code{low_out>high_out}, for compatibility with +## MATLAB. +## @item +## Class of @var{I} is not considered, so limit values are not +## modified depending on class of the image, just treated "as is". When +## Octave 2.1.58 is out, limits will be multiplied by 255 for uint8 +## images and by 65535 for uint16 as in MATLAB. +## @end itemize +## +## @seealso{stretchlim, brighten} +## @end deftypefn + +## Author: Josep Mones i Teixidor + +## TODO: When Octave 2.1.58 is out multiply indices if input argument is +## TODO: of class int* or uint*. + +function ret = imadjust (image, in, out, gamma) + + if (nargin < 1 || nargin > 4) + usage ("imadjust(...) number of arguments must be between 1 and 4"); + endif + + if (nargin < 4) + gamma = 1; ## default gamma + endif + + if !(ismatrix(image)) + error ("imadjust(image,...) first parameter must be a image matrix or colormap"); + endif + + if (nargin==1) + in=stretchlim(image); ## this saturates 1% on lower and 1% on + out=[0;1]; ## higher values + endif + + if (nargin==2) + out=[0;1]; ## default out + endif + + if !((ismatrix(in) || isempty(in)) && (ismatrix(out) || isempty(out)) ) + usage("imadjust(image,[low high],[bottom top],gamma)"); + endif + + if (isempty(in)) + in=[0;1]; ## default in + endif + + if (isempty(out)) + out=[0;1]; ## default out + endif + + simage=size(image); + if (length(simage)==3 && simage(3)==3) + ## image is rgb + [in, out, gamma]=__imadjust_check_3d_args__(in, out, gamma); + + ## make room + ret=zeros(size(image)); + + ## process each plane + for i=1:3 + ret(:,:,i)=__imadjust_plane__(image(:,:,i),in(1,i),in(2,i),out(1,i),out(2,i),gamma(1,i)); + endfor + + elseif (length(simage)==2) + if(simage(2)==3 && \ + (size(in)==[2,3] || size(out)==[2,3] || size(gamma)==[1,3]) ) + ## image is a colormap + [in, out, gamma]=__imadjust_check_3d_args__(in, out, gamma); + + ret=[]; + ## process each color + for i=1:3 + ret=horzcat(ret,__imadjust_plane__(image(:,i),in(1,i),in(2,i),out(1,i),out(2,i),gamma(i))); + endfor + + else + ## image is a intensity image + if( !isvector(in) || length(in)!=2 || !isvector(out) || length(out)!=2 || !isscalar(gamma) || (gamma<0) || (gamma==Inf) ) + error("imadjust: on an intensity image, in and out must be 2-by-1 and gamma a positive scalar."); + endif + ret=__imadjust_plane__(image,in(1),in(2),out(1),out(2),gamma); + endif + + else + error("imadjust: first parameter must be a colormap, an intensity image or a RGB image"); + endif +endfunction + + +## This does all the work. I has a plane; li and hi input low and high +## values; and lo and ho, output bottom and top values. +## Image negative is computed if ho= li & I < hi) .* (lo + (ho - lo) .* ((I - li) / (hi - li)) .^ gamma); + ret = ret + (I >= hi) .* ho; +endfunction + + +## Checks in, out and gamma to see if they are ok for colormap and RGB +## cases. +function [in, out, gamma]=__imadjust_check_3d_args__(in, out, gamma) + switch(size(in)) + case([2,3]) + ## ok! + case([2,1]) + in=repmat(in,1,3); + case([1,2]) ## Compatibility behaviour! + in=repmat(in',1,3); + otherwise + error("imadjust: in must be 2-by-3 or 2-by-1."); + endswitch + + switch(size(out)) + case([2,3]) + ## ok! + case([2,1]) + out=repmat(out,1,3); + case([1,2]) ## Compatibility behaviour! + out=repmat(out',1,3); + otherwise + error("imadjust: out must be 2-by-3 or 2-by-1."); + endswitch + + switch(size(gamma)) + case([1,3]) + ## ok! + case([1,1]) + gamma=repmat(gamma,1,3); + otherwise + error("imadjust: gamma must be a scalar or a 1-by-3 matrix."); + endswitch + + ## check gamma allowed range + if(!all((gamma>=0)&(gamma