Last modified: September 16, 2022
Editors: | Michael Droettboom, Christoph Dalitz |
---|
There are a number of different image types in Gamera that serve different purposes. Fortunately, they all share a common interface, which allows many operations on images to be compiled for different image types from the same source code using C++ templates. This is why all Gamera plugin methods are templatized (see Writing Gamera Plugins).
Image types are specified on two axes: 1] the type of pixels the contain, and 2] the storage type:
The pixels in an image can be one of the following types:
- RGB
- 24-bit color pixels (8-bits per pixel), representing 2 ^ 24 (16,777,216) different colors. RGBPixel objects have some special properties and methods.
- GREYSCALE
- 8-bit greyscale, representing 256 different levels of grey.
- GREY16
- 16-bit greyscale, representing 65,536 different levels of grey.
- ONEBIT
- For black-and-white images. The underlying representation is actually 16 bits-per-pixel, since connected component labelling stores information with each pixel. This seems like wasted space, but since connected component labelling is so common in Gamera, it more often is a space savings from the fact that the image data can be "shared."
- FLOAT
- Double-precision floating point greyscale. This is useful for images that need a really wide dynamic range.
Warning
Unfortunately, at this time FLOAT images cannot be saved or loaded.
Note
When FLOAT images are displayed in the GUI, the output is automatically "normalized" so that the total range in the image is equal to the range of brightnesses your monitor can display.
The pixel type of an image can be retrieved in two ways.
image.pixel_type_name
returns a string which is one of RGB, GreyScale, Grey16, OneBit or Float.
image.data.pixel_type
returns an integer which will be one of the constants RGB, GREYSCALE, GREY16, ONEBIT or FLOAT.
Gamera has two ways of storing the image data in memory behind the scenes:
- DENSE
- Uncompressed. The image data is a contiguous chunk of memory that is addressed in row-major order (left-to-right, top-to-bottom).
- RLE
- Run-length encoded. For certain kinds of images, run-length-encoding can be a performance improvement since less data needs to be transferred between main memory and the CPU.
Warning
At present, RLE is only available for ONEBIT images.
The storage format of an image can be determined in two ways.
image.storage_format_name()
returns a string which is either Dense or RLE.
image.data.storage_format
returns an integer corresponding to the constants DENSE and RLE.
Note
Any performance improvement should be justified only by profiling on real-world data
The methods on images include all of the plugin methods in the current environment. These are documented in the plugin reference. In addition, there are number of core properties and methods.
The Image constructor creates a new image with newly allocated underlying data.
There are multiple ways to create an Image:
- Image (Point upper_left, Point lower_right, Choice pixel_type = ONEBIT, Choice format = DENSE)
- Image (Point upper_left, Size size, Choice pixel_type = ONEBIT, Choice format = DENSE)
- Image (Point upper_left, Dim dim, Choice pixel_type = ONEBIT, Choice format = DENSE)
- Image (Rect rectangle, Choice pixel_type = ONEBIT, Choice format = DENSE)
- Image (Image image, Choice pixel_type = ONEBIT, Choice format = DENSE)
Deprecated forms:
- Image (Point upper_left, Dimensions dimensions, Choice pixel_type = ONEBIT, Choice format = DENSE)
- Image (Int offset_y, Int offset_x, Int nrows, Int ncols, Choice pixel_type = ONEBIT, Choice format = DENSE)
Note that the constructor taking an Image creates a new image with the same position and dimensions as the passed in image, but does not copy the data. (For that, use image_copy).
Creates a new view on existing data.
There are a number of ways to create a subimage:
- SubImage (Image image, Point upper_left, Point lower_right)
- SubImage (Image image, Point upper_left, Size size)
- SubImage (Image image, Point upper_left, Dim dim)
- SubImage (Image image, Rect rectangle)
Deprecated forms:
- SubImage (Image image, Point upper_left, Dimensions dimensions)
- SubImage (Image image, Int offset_y, Int offset_x, Int nrows, Int ncols)
Changes to subimages will affect all other subimages viewing the same data.
Warning
The upper_left and lower_right coordinates are absolute and not relative to the image origin. Hence, for all practical use cases, you must add the image offset to the coordinates, e.g.:
subimg = SubImage(image, Point(p.x + image.offset_x, p.y + image.offset_y), dim)
get (Point p)
Gets a pixel value at the given (x, y) coordinate.
A 2-element sequence may be used in place of the Point argument. For instance, the following are all equivalent:
px = image.get(Point(5, 2))
px = image.get((5, 2))
px = image.get([5, 2])
This coordinate is relative to the image view, not the absolute coordinates.
set (Point p, Pixel value)
Sets a pixel value at the given (x, y) coordinate.
A 2-element sequence may be used in place of the Point argument. For instance, the following are all equivalent:
image.set(Point(5, 2), value)
image.set((5, 2), value)
image.set([5, 2], value)
This coordinate is relative to the image view, not the absolute coordinates.
These methods provide information about the image.
String pixel_type_name ()
Returns a string representing the pixel type of the image. Intended primarily for display (GUI) purposes, since using the integer values in Image.data.pixel_type is more efficient.
See pixel types for more information.
String storage_format_name ()
Returns a string representing the storage format of the image. Intended primarily for display (GUI) purposes, since using the integer values in Image.data.storage_format is more efficient.
See storage formats for more information.
Int memory_size ()
Returns the memory used by the underlying data of the image (in bytes). Note that this memory may be shared with other image views on the same data.
Bounding box operations on Image objects are inherited from the Rect class.
There are two special image views on ONEBIT images that only consider specific pixel values to be black: connected components and multilabel connected components. In most cases, you will need connected components; multilabel connected components are only meant for very special use cases.
Connected components (Cc) are a special kind of view on ONEBIT image data. The implementation (ab)uses the fact that ONEBIT images are actually stored as 16-bits-per-pixel data. Therefore all pixels belonging to the same Cc are set to the same pixel value (the "connected component label") and pixels belonging to different Cc's have different pixel values.
Each Cc object defines a bounding box and a label value which indicates the pixel value that the Cc object corresponds to. Pixels with that value will appear to be black, and pixels without that value will appear to be white.
As a programmer using a Cc object, this detail should not matter most of the time: it will behave as a standalone ONEBIT image. However, care should be taken when setting the values of a Cc object: it may be possible to make pixels "disappear" by setting them to a value other than Cc.label.
Cc's behave like image views with the additional property label. You can remove a particular Cc with fill_white:
# remove all CCs with an aspect ration > 3
ccs = onebit.cc_analysis()
for c in ccs:
if float(c.nrows) / c.ncols > 3.0:
c.fill_white()
You can even take a CC from one image and highlight its black pixels on a different image:
# mark all CCs with an aspect ration > 3 in red
# without changing the original image
ccs = onebit.cc_analysis()
rgb = onebit.to_rgb()
for c in ccs:
if float(c.nrows) / c.ncols > 3.0:
rgb.highlight(c, RGBPixel(255,0,0))
Creates a connected component representing part of a OneBit image.
It is rare to create one of these objects directly: most often you will just use cc_analysis to create connected components.
There are a number of ways to create a Cc:
- Cc (Image image, Int label, Point upper_left, Point lower_right)
- Cc (Image image, Int label, Point upper_left, Size size)
- Cc (Image image, Int label, Point upper_left, Dim dim)
- Cc (Image image, Int label, Rect rectangle)
Deprecated forms:
- Cc (Image image, Int label, Point upper_left, Dimensions dimensions)
- Cc (Image image, Int label, Int offset_y, Int offset_x, Int nrows, Int ncols)
MultiLabelCCs (MlCc on the python side, and MultiLabelCC on the C++ side) basically work in the same way as 'regular' Connected Components. The difference between those two is the ability of MlCcs to have multiple labels. Each label has an associated Rect representing its bounding box; the bounding box of the entire MlCc is the closure of all label bounding boxes.
This special feature allows for building connected components which actually consist of different parts, thus making it fast and easy to create different variants of an MlCcs with some parts excluded. To make this even more useful, each MlCc has an additional (optional) property, the subpart neighborship relations. Note that these relationships need to be provided by the user, in case he needs them.
Apart from the basic image methods, MlCcs offer a number of additional functions as listed below.
Creates a multi label connected component (MultiLabelCC) representing part of a OneBit image.
Most often you will create a MultiLabelCCs from a list of Cc's.
There are a number of ways to create a MultiLabelCC:
- MlCc (Image image, int label, Point upper_left, Point lower_right)
- MlCc (Image image, int label, Point upper_left, Size size)
- MlCc (Image image, int label, Point upper_left, Dim dim)
- MlCc (Image image, int label, Rect rectangle)
- MlCc (CcList ccs)
Deprecated forms:
- MlCc (Image image, int label, Point upper_left, Dimensions dimensions)
- MlCc (Image image, int label, Int offset_y, Int offset_x, Int nrows, Int ncols)
add_label (int label, Rect rect)
Adds a label and a bounding box (for the label) to a MultiLabelCC. The bounding box of the MlCc is extended by the given rect.
remove_label (int label)
Removes a label from a MultiLabelCC. The bounding box of the MlCc is shrunk by the bounding box associated with the removed label as far as possible with respect to the other bounding boxes.
Returns a new MlCc containing only the given labels. For computing the new bounding boxes, the bounding box information stored for each label are utilized. The neighborship information is lost in the returned MlCc.
This function is overloaded to return either a single or several new MlCc's:
relabel (List<int> l)
Creates a single MultiLabelCC based on the current one.
new_mlcc = mlcc.relabel([2,3,4])
This returns a single MultiLabelCC which contains the labels 2,3,4.
relabel (List<List<int>> l)
Creates a list of MultiLabelCC based on the current one.
new_mlcc_list = mlcc.relabel([[2,3],[4]])
This returns a list of two MultiLabelCCs. The first one contains the labels 2,3; the second one contains the label 4.
convert_to_cc ()
Converts the MultiLabelCC into a ConnectedComponent. All labels belonging to the MultiLabelCc are set to the value of the first label. After calling this method, the MultiLabelCc only has one label.
convert_to_cc_list ()
Converts the MultiLabelCC into a list of ConnectedComponent.Each ConnectedComponent in the List represents one label of the MultiLabelCC. For example: You have a MultiLabelCC with the labels 2, 3, 4. Therefore it would be transformed into a list of 3 ConnectedComponent, one for each label.
get_neighbors ()
Returns all pairs of neighbors that have been previously added with add_neighbors().
add_neighbors (int i, int j)
Adds a neighborhood relation to the MultiLabelCC.
This is entirely optional: neighborship relations are only stored, and can be returned with get_neighbors(), but are not used internally by MlCc.
There are a number of free functions for dealing with images.
load_image (FileOpen filename, Choice storage_format = DENSE)
Load an image from the given filename. At present, TIFF and PNG files are supported.
ImageInfo image_info (FileOpen filename)
Retrieve information about an image file without loading it.
The result is an ImageInfo object about a given filename. The ImageInfo object gives information such as the type (color, greyscale, onebit), the bit-depth, resolution, size, etc.
display_multi (ImageList list)
Displays a list of images in a grid-like window. This function has no effect if the Gamera GUI is not running.