-
Notifications
You must be signed in to change notification settings - Fork 9
ImageAccessor
An image accessor is a wrapper around some ImageProcessor
object that provides unified (read and write) access
to its pixels values. This abstract class defines uniform access to all 4 types of images available in
ImageJ:
-
ByteProcessor
(8-bit unsigned integer, scalar-valued), -
ShortProcessor
(16-bit signed integer, scalar-valued), -
FloatProcessor
(32-bit float, scalar-valued), -
ColorProcessor
(3x8-bit unsigned integer, vector-valued).
ImageAccessor
transfers pixel data for all read and write operations as values of type float[]
, either containing a
single element (on scalar-valued images) or 3 elements (on color images).
An ImageAccessor
is always linked to a particular image and duplicates no pixel data.
Upon instantiation, each ImageAccessor
is also assigned a specific OutOfBoundsStrategy
and InterpolationMethod
.
-
ImageAccessor
(abstract)-
ScalarAccessor
(abstract)ByteAccessor
ShortAccessor
FloatAccessor
-
VectorAccessor
(abstract)RgbAccessor
-
A generic ImageAccessor
is created, e.g., using the static method
ImageAccessor create(ImageProcessor ip)
which, depending upon the concrete type of ip
, returns an instance of
ByteAccessor
, ShortAccessor
, FloatAccessor
or RgbAccessor
, respectively.
In this case, the default OutOfBoundsStrategy
and InterpolationMethod
are
used. Both can be specified explicitly using method
ImageAccessor create(ImageProcessor ip, OutOfBoundsStrategy obs, InterpolationMethod ipm)
Independent of the underlying image type, ImageAccessor
can read pixels using method
float[] getPix(int u, int v)
The returned float[]
contains a single element for scalar-valued images and multiple elements
for vector-valued images. There is no restriction on the coordinates u
and v
; pixels outside
the image are handled according to the specified OutOfBoundsStrategy.
Reading pixels is not constrained to integer coordinates. Method
float[] getPix(double x, double y)
returns the interpolated pixel value for the continuous position x
and y
, using the
InterpolationMethod specified at creation.
Pixel values can be modified using method
void setPix(int u, int v, float[] val)
The supplied float
array val
must contain a single element for scalar-valued images or
3 elements for color images.
Pixel values are automatically clamped to the permissible range.
Writing to coordinates outside the image has no effect and also does not raise an error.
ScalarAccessor
is the abstract superclass to all accessors for scalar-valued images (i.e., ByteAccessor
, ShortAccessor
,
FloatAccessor
, see Class Hierarchy). It defines the static creator method
ScalarAccessor create(ImageProcessor ip, OutOfBoundsStrategy obs, InterpolationMethod ipm)
where ip
must be of type ByteProcessor
, ShortProcessor
, or FloatProcessor
(otherwise
an exception is thrown).
ScalarAccessor
also defines the following additional access methods:
-
float getVal(int u, int v)
, -
float getVal(double x, double y)
, void setVal(int u, int v, float)
to read and write pixels passing single float
values.
VectorAccessor
is the abstract superclass to vector-valued images (currently RgbAccessor
only,
see Class Hierarchy).
VectorAccessor
itself cannot be instatiated, but its (single) subclass RgbAccessor
can using the
static method
RgbAccessor create(ColorProcessor ip, OutOfBoundsStrategy obs, InterpolationMethod ipm)
VectorAccessor
also defines the following additional access methods:
-
float getVal(int u, int v, int k)
, -
float getVal(double x, double y, int k)
, void setVal(int u, int v, int k, float val)
to read and write the k-th component of pixel vectors passing single float
values.
This is the run()
method of ImageJ plugin Pixel_Interpolation_Demo
(package Ch22_Pixel_Interpolation
),
which translates the input image by some continuous distance (dx/dy) and performs interpolation
on any type of image:
import ij.ImagePlus;
import ij.process.ImageProcessor;
import imagingbook.common.image.OutOfBoundsStrategy;
import imagingbook.common.image.access.ImageAccessor;
import imagingbook.common.image.interpolation.InterpolationMethod;
public void run(ImageProcessor source) {
double dx = 10.50; // translation parameters
double dy = -3.25;
InterpolationMethod IPM = InterpolationMethod.Bicubic;
OutOfBoundsStrategy OBS = OutOfBoundsStrategy.DefaultValue;
final int w = source.getWidth();
final int h = source.getHeight();
// create the target image (same type as source):
ImageProcessor target = source.createProcessor(w, h);
// create ImageAccessor's for the source and target image:
ImageAccessor sa = ImageAccessor.create(source, OBS, IPM);
ImageAccessor ta = ImageAccessor.create(target);
// iterate over all pixels of the target image:
for (int u = 0; u < w; u++) { // discrete target position (u,v)
for (int v = 0; v < h; v++) {
double x = u + dx; // continuous source position (x,y)
double y = v + dy;
float[] val = sa.getPix(x, y);
ta.setPix(u, v, val); // update target pixel
}
}
// display the target image:
new ImagePlus("Result", target).show();
}
- A related concept for providing unified access to images is PixelPack, which copies all pixel data to
internal
float
arrays. In contrast toPixelPack
,ImageAccessor
does not duplicate any data but reads and writes the originalImageProcessor
pixel data directly. GridIndexer2D
OutOfBoundsStrategy
InterpolationMethod