1######################################################################## 2## 3## Copyright (C) 1994-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {@var{img} =} gray2ind (@var{I}) 28## @deftypefnx {} {@var{img} =} gray2ind (@var{I}, @var{n}) 29## @deftypefnx {} {@var{img} =} gray2ind (@var{BW}) 30## @deftypefnx {} {@var{img} =} gray2ind (@var{BW}, @var{n}) 31## @deftypefnx {} {[@var{img}, @var{map}] =} gray2ind (@dots{}) 32## Convert a grayscale or binary intensity image to an indexed image. 33## 34## The indexed image will consist of @var{n} different intensity values. 35## If not given @var{n} defaults to 64 for grayscale images or 2 for binary 36## black and white images. 37## 38## The output @var{img} is of class uint8 if @var{n} is less than or equal to 39## 256; Otherwise the return class is uint16. 40## @seealso{ind2gray, rgb2ind} 41## @end deftypefn 42 43function [I, map] = gray2ind (I, n = 64) 44 45 if (nargin < 1 || nargin > 2) 46 print_usage (); 47 elseif (! isreal (I) || issparse (I) || ! ismatrix(I)) 48 error ("gray2ind: I must be a grayscale or binary image"); 49 elseif (! isscalar (n) || n < 1 || n > 65536) 50 error ("gray2ind: N must be a positive integer in the range [1, 65536]"); 51 endif 52 53 ## default n is different if image is logical 54 if (nargin == 1 && islogical (I)) 55 n = 2; 56 endif 57 58 cls = class (I); 59 if (! any (strcmp (cls, {"logical", "uint8", "uint16", "int16", ... 60 "single", "double"}))) 61 error ("gray2ind: invalid data type '%s'", cls); 62 elseif (isfloat (I) && (min (I(:) < 0) || max (I(:) > 1))) 63 error ("gray2ind: floating point images may only contain values between 0 and 1"); 64 endif 65 66 map = gray (n); 67 68 ## Set up scale factor 69 if (isinteger (I)) 70 low = double (intmin (cls)); 71 scale = double (intmax (cls)) - low; 72 I = double (I) - low; 73 else 74 scale = 1; 75 endif 76 I *= (n-1)/scale; 77 78 ## Note: no separate call to round () necessary because 79 ## type conversion does that automatically. 80 if (n <= 256) 81 I = uint8 (I); 82 else 83 I = uint16 (I); 84 endif 85 86endfunction 87 88 89%!assert (gray2ind ([0 0.25 0.5 1]), uint8 ([0 16 32 63])) 90%!assert (gray2ind ([0 0.25 0.5 1], 400), uint16 ([0 100 200 399])) 91%!assert (gray2ind (logical ([1 0 0 1])), uint8 ([1 0 0 1])) 92%!assert (gray2ind (uint8 ([0 64 128 192 255])), uint8 ([0 16 32 47 63])) 93 94%!test 95%! i2g = ind2gray (1:100, gray (100)); 96%! g2i = gray2ind (i2g, 100); 97%! assert (g2i, uint8 (0:99)); 98 99%!assert (gray2ind ([0 0.25 0.5 1], 256), uint8 ([0 64 128 255])) 100%!assert (gray2ind ([0 (1/511) (1/510) 1-(1/509) 1-(1/510) 1], 256), 101%! uint8 ([0 0 1 254 255 255])) 102 103%!test 104%! assert (class (gray2ind ([0.0 0.5 1.0], 255)), "uint8"); 105%! assert (class (gray2ind ([0.0 0.5 1.0], 256)), "uint8"); 106%! assert (class (gray2ind ([0.0 0.5 1.0], 257)), "uint16"); 107 108## Test input validation 109%!error gray2ind () 110%!error gray2ind (1,2,3) 111%!error <I must be a grayscale or binary image> gray2ind ({1}) 112%!error <I must be a grayscale or binary image> gray2ind ([1+i]) 113%!error <I must be a grayscale or binary image> gray2ind (sparse ([1])) 114%!error <I must be a grayscale or binary image> gray2ind (ones (2,2,3)) 115%!error <N must be a positive integer> gray2ind (1, ones (2,2)) 116%!error <N must be a positive integer> gray2ind (1, 0) 117%!error <N must be a positive integer> gray2ind (1, 65537) 118%!error <invalid data type> gray2ind (uint32 (1)) 119%!error <values between 0 and 1> gray2ind (-1) 120%!error <values between 0 and 1> gray2ind (2) 121