Mercurial > hg > octave-image
changeset 609:ea8f2e7d270a
rgb2gray: perform weighted conversion based on luminance values
author | carandraug |
---|---|
date | Mon, 24 Sep 2012 16:59:13 +0000 |
parents | 1b8b83d01211 |
children | 4c92bffbf4cc |
files | NEWS inst/rgb2gray.m |
diffstat | 2 files changed, 55 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS +++ b/NEWS @@ -59,6 +59,11 @@ isrgb isind mat2gray + rgb2gray + + ** `rgb2gray' now also supports images of the class single and performs a + weighted conversion to keep the image luminance instead of a the mean + through each color. ** `imhist' is much more compatible with matlab and among other changes, it now uses the whole range of the class for the histogram rather than
--- a/inst/rgb2gray.m +++ b/inst/rgb2gray.m @@ -1,4 +1,5 @@ ## Copyright (C) 2000, 2001 Kai Habel <kai.habel@gmx.de> +## Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com> ## ## 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 @@ -17,13 +18,14 @@ ## @deftypefn {Function File} @var{gray}= rgb2gray (@var{rgb}) ## Convert RGB image or colormap to grayscale. ## -## If the input is an RGB image, the conversion to a gray image is computed as -## the mean value of the color channels. Supported classes are single, double, -## uint8 and uint16. +## If @var{rgb} is an RGB image, the conversion to grayscale is weighted based +## on the luminance values (see @code{rgb2ntsc}). Supported classes are single, +## double, uint8 and uint16. ## -## If the input is a color map it is converted into the YIQ space -## of ntsc. The luminance value (Y) is taken to create a gray color map. -## R = G = B = Y +## If @var{rgb} is a colormap it is converted into the YIQ space of ntsc. The +## luminance value (Y) is taken to create a gray colormap. +## +## @seealso{mat2gray, ntsc2rgb, rgb2ind, rgb2ntsc, rgb2ycbcr} ## @end deftypefn function gray = rgb2gray (rgb) @@ -33,20 +35,48 @@ endif if (iscolormap (rgb)) - ntscmap = rgb2ntsc (rgb); - gray = ntscmap (:, 1) * ones (1, 3); - elseif (isimage (rgb) && ndims(rgb) == 3) - switch(class(rgb)) - case {"single", "double"} - gray = mean(rgb,3); - case "uint8" - gray = uint8(mean(rgb,3)); - case "uint16" - gray = uint16(mean(rgb,3)); - otherwise - error("rgb2gray: unsupported class %s", class(rgb)); - endswitch + gray = rgb2ntsc (rgb) (:, 1) * ones (1, 3); + elseif (isimage (rgb) && ndims (rgb) == 3) + + ## FIXME when warning for broadcasting is turned off by default, this + ## unwind_protect block could be removed + + ## we are using broadcasting on the code below so we turn off the + ## warnings but will restore to previous state at the end + bc_warn = warning ("query", "Octave:broadcast"); + unwind_protect + warning ("off", "Octave:broadcast"); + + ## mutiply each color by the luminance factor (this is also matlab compatible) + ## 0.29894 * red + 0.58704 * green + 0.11402 * blue + gray = im2double (rgb) .* permute ([0.29894, 0.58704, 0.11402], [1, 3, 2]); + gray = sum (gray, 3); + + switch (class (rgb)) + case {"single", "double"} + ## do nothing. All is good + case "uint8" + gray = im2uint8 (gray); + case "uint16" + gray = im2uint16 (gray); + otherwise + error ("rgb2gray: unsupported class %s", class(rgb)); + endswitch + + unwind_protect_cleanup + ## restore broadcats warning status + warning (bc_warn.state, "Octave:broadcast"); + end_unwind_protect else - error("rgb2gray: the input must either be an RGB image or a colormap"); + error ("rgb2gray: the input must either be an RGB image or a colormap"); endif endfunction + +# simplest test, double image, each channel on its own and then all maxed +%!shared img +%! img = zeros (2, 2, 3); +%! img(:,:,1) = [1 0; 0 1]; +%! img(:,:,2) = [0 1; 0 1]; +%! img(:,:,3) = [0 0; 1 1]; +%! img = rgb2gray (img); +%!assert ([img(1,1) img(1,2) img(2,1) img(2,2)], [0.29894 0.58704 0.11402 1]);