1## Copyright (C) 2015 Hartmut Gimpel 2## 3## This program is free software; you can redistribute it and/or 4## modify it under the terms of the GNU General Public License as 5## published by the Free Software Foundation; either version 3 of the 6## License, or (at your option) any later version. 7## 8## This program is distributed in the hope that it will be useful, but 9## WITHOUT ANY WARRANTY; without even the implied warranty of 10## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11## General Public License for more details. 12## 13## You should have received a copy of the GNU General Public License 14## along with this program; if not, see 15## <http:##www.gnu.org/licenses/>. 16 17## -*- texinfo -*- 18## @deftypefn {Function File} {@var{lab} =} rgb2lab (@var{rgb}) 19## @deftypefnx {Function File} {@var{lab_map} =} rgb2lab (@var{rgb_map}) 20## Transform a colormap or image from sRGB to CIE L*a*b* color space. 21## 22## A color in the RGB space consists of red, green, and blue intensities. 23## The input RGB values are interpreted as nonlinear sRGB values 24## with the white point D65. This means the input values are assumed to 25## be in the colorimetric (sRGB) colorspace. 26## 27## A color in the CIE L*a*b* (or CIE Lab) space consists of lightness L* and 28## two color-opponent dimensions a* and b*. The whitepoint is taken as D65. 29## The CIE L*a*b* colorspace is also a colorimetric colorspace. It is designed 30## to incorporate the human perception of color differences. 31## 32## Input values of class double, single, uint8 or uint16 are accepted. 33## Output class is generally of type double, only input type single will 34## result in an output type of single. The shape of the input is 35## conserved. 36## 37## note: This function returns slightly different values than the Matlab 38## version. But it has a better "round trip accuracy" (<2e-5) 39## for RGB -> Lab -> RGB. 40## 41## @seealso{lab2rgb, rgb2xyz, rgb2hsv, rgb2ind, rgb2ntsc} 42## @end deftypefn 43 44## Author: Hartmut Gimpel <hg_code@gmx.de> 45## algorithm taken from the following book: 46## Burger, Burge "Digitale Bildverarbeitung", 3rd edition (2015) 47 48function lab = rgb2lab (rgb) 49 50 if (nargin != 1) 51 print_usage (); 52 endif 53 54 [rgb, cls, sz, is_im, is_nd, is_int] ... 55 = colorspace_conversion_input_check ("rgb2lab", "RGB", rgb, 0); 56 57 ## transform from non-linear sRGB values to CIE XYZ values 58 xyz = rgb2xyz (rgb); 59 60 ## transform from CIE XYZ values to CIE L*a*b* values 61 lab = xyz2lab (xyz); 62 63 # always return values of type double for Matlab compatibility (exception: type single) 64 lab = colorspace_conversion_revert (lab, cls, sz, is_im, is_nd, is_int, 1); 65 66endfunction 67 68 69## Test pure colors, gray and some other colors 70## (This set of test values is taken from the book by Burger.) 71%!assert (rgb2lab ([0 0 0]), [0, 0, 0], 1e-2) 72%!assert (rgb2lab ([1 0 0]), [53.24, 80.09, 67.20], 1e-2) 73%!assert (rgb2lab ([1 1 0]), [97.14, -21.55, 94.48], 1e-2) 74%!assert (rgb2lab ([0 1 0]), [87.74, -86.18, 83.18], 1e-2) 75%!assert (rgb2lab ([0 1 1]), [91.11, -48.09, -14.13], 1e-2) 76%!assert (rgb2lab ([0 0 1]), [32.30, 79.19, -107.86], 1e-2) 77%!assert (rgb2lab ([1 0 1]), [60.32, 98.24, -60.83], 1e-2) 78%!assert (rgb2lab ([1 1 1]), [100, 0.00, 0.00], 1e-2) 79%!assert (rgb2lab ([0.5 0.5 0.5]), [53.39, 0.00, 0.00], 1e-2) 80%!assert (rgb2lab ([0.75 0 0]), [39.77, 64.51, 54.13], 1e-2) 81%!assert (rgb2lab ([0.5 0 0]), [25.42, 47.91, 37.91], 1e-2) 82%!assert (rgb2lab ([0.25 0 0]), [9.66, 29.68, 15.24], 1e-2) 83%!assert (rgb2lab ([1 0.5 0.5]), [68.11, 48.39, 22.83], 1e-2) 84 85## Test tolarant input checking on floats 86%!assert (rgb2lab ([1.5 1 1]), [111.47, 43.42, 17.98], 1e-2) 87 88%!test 89%! rgb_map = rand (64, 3); 90%! assert (lab2rgb (rgb2lab (rgb_map)), rgb_map, 2e-5); 91 92%!test 93%! rgb_img = rand (64, 64, 3); 94%! assert (lab2rgb (rgb2lab (rgb_img)), rgb_img, 2e-5); 95 96## support sparse input 97%!assert (rgb2lab (sparse ([0 0 1])), sparse ([32.30, 79.19, -107.86]), 1e-2) 98%!assert (rgb2lab (sparse ([0 1 1])), sparse ([91.11, -48.09, -14.13]), 1e-2) 99%!assert (rgb2lab (sparse ([1 1 1])), sparse ([100, 0.00, 0.00]), 1e-2) 100 101## support integer input (and double output) 102%!assert (rgb2lab (uint8([255 255 255])), [100, 0.00, 0.00], 1e-2) 103 104## conserve class of single input 105%!assert (class (rgb2lab (single([1 1 1]))), 'single') 106 107## Test input validation 108%!error rgb2lab () 109%!error rgb2lab (1,2) 110%!error <invalid data type 'cell'> rgb2lab ({1}) 111%!error <RGB must be a colormap or RGB image> rgb2lab (ones (2,2)) 112 113## Test ND input 114%!test 115%! rgb = rand (16, 16, 3, 5); 116%! lab = zeros (size (rgb)); 117%! for i = 1:5 118%! lab(:,:,:,i) = rgb2lab (rgb(:,:,:,i)); 119%! endfor 120%! assert (rgb2lab (rgb), lab) 121