/usr/share/octave/packages/image-2.6.1/impixel.m is in octave-image 2.6.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | ## Copyright (C) 2013 Carnë Draug <carandraug@octave.org>
##
## 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 3 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 <http://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} {} impixel ()
## @deftypefnx {Function File} {} impixel (@var{img}, @var{x}, @var{y})
## @deftypefnx {Function File} {} impixel (@var{ind}, @var{map}, @var{x}, @var{y})
## @deftypefnx {Function File} {} impixel (@var{xdata}, @var{ydata}, @var{img}, @var{x}, @var{y})
## @deftypefnx {Function File} {} impixel (@var{xdata}, @var{ydata}, @var{ind}, @var{map}, @var{x}, @var{y})
## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{p}] =} impixel (@dots{})
## Get pixel values.
##
## For any image @var{img}, or indexed image @var{ind} with colormap @var{map},
## returns the pixel values at the image coordinates @var{x} and @var{y}.
##
## The 2 element vectors @var{xdata} and @var{ydata} can be used to set an
## alternative coordinate system.
##
## If more than one output argument is requested, also returns the @var{x} and
## @var{y} coordinates for the image.
##
## @itemize @bullet
## @item
## The pixel values are always returned in RGB style triples, even when
## @var{img} is a grayscale image.
##
## @item
## The value for pixel coordinates outside the image limits is NaN.
##
## @item
## Because a floating-point is required to represent a NaN, the pixel
## values will be of class double if input is double, and single otherwise.
## @end itemize
##
## @end deftypefn
function varargout = impixel (varargin)
if (nargin > 6)
print_usage ();
## interactive usage
elseif (nargin <= 2)
## FIXME not yet implemented
print_usage ();
if (nargin == 0)
## If using the current image, it is possible that xData and yData
## were changed? We will confirm later is they were tampered with.
xData = get (gcf (), "xData");
yData = get (gcf (), "yData");
else
## with given image, otherwise we will use current image
[img, map, is_indexed] = get_image (varargin{:});
endif
## If only 2 output arguments are requested in interactive mode, then
## only the coordinates are required, no need to do anything else.
if (nargout <= 2)
varargout(1:2) = {x y};
return
endif
## non-interactive usage
else
x = varargin{end-1};
y = varargin{end};
if (! isnumeric (x) || ! isreal (x) || ! isnumeric (y) || ! isreal (y))
error ("impixel: X and Y must be real numbers");
endif
x = x(:);
y = y(:);
if (nargin >= 5)
[img, map, is_indexed] = get_image (varargin{3:end-2});
xData = varargin{1};
yData = varargin{2};
if (! isnumeric (xData) || ! isnumeric (yData))
## For Matlab compatibility we do not check if there's
## only 2 elements, or if they are real numbers
error ("impixel: XDATA and YDATA must be numeric");
endif
else
[img, map, is_indexed] = get_image (varargin{1:end-2});
xData = 1:columns (img);
yData = 1:rows (img);
endif
endif
## We need to return NaN if the requested pixels are outside the image
## limits. interp2() will respect the input class, which means it will
## return a 0 instead of NaN if the image is an integer class. Because
## of that, we convert it to single. If the input image was double, then
## we let it be.
if (isinteger (img))
img = single (img);
if (is_indexed)
## There's an offset in indexed images depending on their class. An
## indexed image from integer class, matches the value 0 to row 1 of the
## colormap. An indexed image from a float class, matches value 1 to
## row 1. Since we are changing the class, we need to readjust it.
img++;
endif
endif
xx = linspace (min (xData), max (xData), columns (img));
yy = linspace (min (yData), max (yData), rows (img));
data = interp2 (xx, yy, img(:,:,1), x, y, "nearest");
if (ndims (img) == 3 && size (img, 3) == 3)
## We can't use interp3() because XI and YI will be used to select entire
## columns and vectors instead of matched coordinates
for ch = 2:3
data(:,ch) = interp2 (xx, yy, img(:,:,ch), x, y, "nearest");
endfor
endif
if (is_indexed)
bad = isnan (data);
data(bad) = 1;
data = map(data(:),:);
data([bad bad bad]) = NA;
elseif (isvector (data))
## If we have a vector but the image was not indexed, it must have
## been a grayscale image. We need to repeat the values into a Nx3
## matrix as if they were RGB values.
data = [data(:) data(:) data(:)];
endif
if (nargout > 1)
varargout(1:3) = {x y data}
else
varargout(1) = {data};
endif
endfunction
function [img, map, is_indexed] = get_image (img, map = [])
if (! isimage (img))
error ("impixel: invalid image");
endif
is_indexed = false;
if (nargin > 2)
error ("impixel: too many input arguments");
elseif (nargin == 2)
is_indexed = true;
if (! iscolormap (map))
error ("impixel: invalid colormap");
elseif (! isind (img))
error ("impixel: invalid indexed image");
endif
endif
endfunction
%!shared img2d, img3d
%! img2d = uint8 (magic (10));
%! img3d(:,:,1) = img2d;
%! img3d(:,:,2) = img2d + 1;
%! img3d(:,:,3) = img2d + 2;
%! img3d = uint8 (img3d);
%!
%!assert (impixel (img2d, 2, 2), single ([80 80 80]));
%!assert (impixel (img2d, -2, 2), single ([NA NA NA]));
%!
%!assert (impixel (img2d, [1 10], [1 10]), single ([92 92 92; 59 59 59]));
%!assert (impixel (img3d, [1 10], [1 10]), single ([92 93 94; 59 60 61]));
%!assert (impixel (double (img2d), [1 10], [1 10]), [92 92 92; 59 59 59]);
%!
%!assert (impixel ([1 10], [1 10], img2d, [1 10], [1 10]), single ([92 92 92; 59 59 59]));
%!assert (impixel ([3 12], [-4 12], img2d, [1 10], [1 10]), single ([NA NA NA; 44 44 44]));
%!assert (impixel ([3 5], [-4 3], img2d, [1 10], [1 10]), single ([NA NA NA; NA NA NA]));
%!
%! ## the following returns double because it's an indexed image
%!assert (impixel ([3 12], [-4 12], img2d, gray (100), [1 10], [1 10]), [NA NA NA; 4/9 4/9 4/9]);
|