comparison scripts/image/gray2ind.m @ 15693:a1b634240352

maint: merge default into image-overhaul head, specially changeset 806ea52. Resolving many conflicts and fixing bugs related to correctly indexing on image class (float vs integer have different offset)
author Carnë Draug <carandraug+dev@gmail.com>
date Wed, 28 Nov 2012 06:01:09 +0100
parents dffb28f47ea8 806ea52af230
children b1cd65881592
comparison
equal deleted inserted replaced
15692:37a21f615d67 15693:a1b634240352
15 ## You should have received a copy of the GNU General Public License 15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see 16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>. 17 ## <http://www.gnu.org/licenses/>.
18 18
19 ## -*- texinfo -*- 19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {[@var{img} =} gray2ind (@var{I}) 20 ## @deftypefn {Function File} {@var{img} =} gray2ind (@var{I})
21 ## @deftypefnx {Function File} {[@var{img} =} gray2ind (@var{I}, @var{n}) 21 ## @deftypefnx {Function File} {@var{img} =} gray2ind (@var{I}, @var{n})
22 ## @deftypefnx {Function File} {[@var{img}, @var{map} =} gray2ind (@dots{}) 22 ## @deftypefnx {Function File} {@var{img} =} gray2ind (@var{BW})
23 ## Convert a gray scale or binary image to an indexed image. 23 ## @deftypefnx {Function File} {@var{img} =} gray2ind (@var{BW}, @var{n})
24 ## @deftypefnx {Function File} {[@var{img}, @var{map}] =} gray2ind (@dots{})
25 ## Convert a grayscale or binary intensity image to an indexed image.
26 ##
27 ## The indexed image will consist of @var{n} different intensity values.
28 ## If not given @var{n} defaults to 64 for grayscale images or 2 for
29 ## binary black and white images.
24 ## 30 ##
25 ## The indexed image will consist of @var{n} different intensity values. 31 ## The output @var{img} is of class uint8 or uint 16 if @var{n} is less than or
26 ## If not given @var{n} defaults to 64 and 2 for gray scale and binary images 32 ## equal to 256 or 65536 respectively. Otherwise, the output is of class double.
27 ## respectively. Its class will be uint8, uint16 or double in order of which 33 ## @seealso{ind2gray, rgb2ind}
28 ## one is necessary to fit @var{n} different intensities.
29 ##
30 ## @seealso{ind2gray, rgb2ind}
31 ## @end deftypefn 34 ## @end deftypefn
32 35
33 ## Author: Tony Richardson <arichard@stark.cc.oh.us> 36 ## Author: Tony Richardson <arichard@stark.cc.oh.us>
34 ## Created: July 1994 37 ## Created: July 1994
35 ## Adapted-By: jwe 38 ## Adapted-By: jwe
36 39
37 function [X, map] = gray2ind (I, n = 64) 40 function [I, map] = gray2ind (I, n = 64)
38 ## Check input 41
39 if (nargin < 1 || nargin > 2) 42 if (nargin < 1 || nargin > 2)
40 print_usage (); 43 print_usage ();
44 elseif (! isreal (I) || issparse (I))
45 error ("gray2ind: I must be a grayscale or binary image");
46 elseif (! isscalar (n) || n < 1 || n > 65536)
47 error ("gray2ind: N must be a positive integer in the range [1, 65536]");
48 elseif (! ismatrix (I) || ndims (I) != 2)
49 error ("gray2ind: first input argument must be a gray scale image");
41 endif 50 endif
42 51
43 ## default n is different if image is logical 52 ## default n is different if image is logical
44 if (nargin < 2 && isa (I, "logical")) 53 if (nargin == 1 && islogical (I))
45 n = 2; 54 n = 2;
46 endif 55 endif
47 56
48 C = class (I);
49 if (! ismatrix (I) || ndims (I) != 2)
50 error ("gray2ind: first input argument must be a gray scale image");
51 endif
52 if (! isscalar (n) || n < 0) 57 if (! isscalar (n) || n < 0)
53 error ("gray2ind: second input argument must be a positive integer"); 58 error ("gray2ind: second input argument must be a positive integer");
54 endif 59 endif
55 ints = {"uint8", "uint16", "int8", "int16"}; 60
56 floats = {"double", "single"}; 61 cls = class (I);
57 if (! ismember (C, {ints{:}, floats{:}, "logical"})) 62 if (! any (isa (I, {"logical", "uint8", "uint16", "int16", "single", "double"})))
58 error ("gray2ind: invalid data type '%s'", C); 63 error ("gray2ind: invalid data type '%s'", cls);
59 endif 64 elseif (isfloat (I) && (min (I(:) < 0) || max (I(:) > 1)))
60 if (ismember (C, floats) && (min (I(:)) < 0 || max (I(:)) > 1))
61 error ("gray2ind: floating point images may only contain values between 0 and 1"); 65 error ("gray2ind: floating point images may only contain values between 0 and 1");
62 endif 66 endif
63 67
64 ## Convert data
65 map = gray (n); 68 map = gray (n);
66 ## If @var{I} is an integer matrix convert it to a double matrix with values in [0, 1] 69
67 if (ismember (C, ints)) 70 ## Set up scale factor
68 low = double (intmin (C)); 71 if (isinteger (I))
69 high = double (intmax (C)); 72 low = double (intmin (cls));
70 I = (double (I) - low) / (high - low); 73 scale = double (intmax (cls)) - low;
74 I = double (I) - low;
75 else
76 scale = 1;
71 endif 77 endif
72 X = round (I*(n-1)); 78 ## Note: no separate call to round () necessary because
79 ## type conversion does that automatically.
80 I = I * ((n-1)/scale);
73 if (n < 256) 81 if (n < 256)
74 X = uint8 (X); 82 I = uint8 (I);
75 elseif (n < 65536) 83 elseif (n < 65536)
76 X = uint16 (X); 84 I = uint16 (I);
77 else 85 else
78 ## if uint16 is not enough, we return double in which case there's no 0 86 ## if uint16 is not enough, we return double in which case index
79 X += 1; 87 ## values should start at 1.
88 I = round (I) + 1;
80 endif 89 endif
81 endfunction 90 endfunction
91
92 %!assert (gray2ind ([0 0.25 0.5 1]), uint8 ([0 16 32 63]))
93 %!assert (gray2ind ([0 0.25 0.5 1], 400), uint16 ([0 100 200 399]))
94 %!assert (gray2ind (logical ([1 0 0 1])), uint8 ([1 0 0 1]))
95 %!assert (gray2ind (uint8 ([0 64 128 192 255])), uint8 ([0 16 32 47 63]))
96
97 %!test
98 %! i2g = ind2gray (1:100, gray (100));
99 %! g2i = gray2ind (i2g, 100);
100 %! assert (g2i, uint8 (0:99));
101
102 %% Test input validation
103 %!error gray2ind ()
104 %!error gray2ind (1,2,3)
105 %!error <I must be a grayscale or binary image> gray2ind ({1})
106 %!error <I must be a grayscale or binary image> gray2ind ([1+i])
107 %!error <I must be a grayscale or binary image> gray2ind (sparse ([1]))
108 %!error <N must be a positive integer> gray2ind (1, ones (2,2))
109 %!error <N must be a positive integer> gray2ind (1, 0)
110 %!error <N must be a positive integer> gray2ind (1, 65537)
111 %!error <invalid data type> gray2ind (uint32 (1))
112 %!error <values between 0 and 1> gray2ind (-1)
113 %!error <values between 0 and 1> gray2ind (2)
114