===========
Image types
===========

: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`__).

.. __: writing_plugins.html

Image types are specified on two axes: 1] the type of pixels the
contain, and 2] the storage type:

Pixel types
===========

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`__.

.. __: gamera.core.RGBPixel.html

   ``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.

.. __: plugins.html#cc-analysis

The pixel type of an image can be retrieved in two ways.

.. code:: Python

  image.pixel_type_name

returns a string which is one of ``RGB``, ``GreyScale``, ``Grey16``,
``OneBit`` or ``Float``.

.. code:: Python

  image.data.pixel_type

returns an integer which will be one of the constants ``RGB``,
``GREYSCALE``, ``GREY16``, ``ONEBIT`` or ``FLOAT``. 

Storage formats
===============

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.

.. code:: Python

  image.storage_format_name()

returns a string which is either ``Dense`` or ``RLE``.

.. code:: Python

  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

Image methods
=============

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.

.. __: plugins.html

Constructors
------------

``Image.__init__``
''''''''''''''''''

.. docstring:: gamera.core Image __init__
   :no_title:

``SubImage.__init__``
'''''''''''''''''''''

.. docstring:: gamera.core SubImage __init__
   :no_title:

Pixel access
------------

.. docstring:: gamera.core Image get set


Informational
-------------

These methods provide information about the image.

.. docstring:: gamera.core ImageBase pixel_type_name storage_format_name memory_size
.. docstring:: gamera.core Image resolution white black
.. docstring:: gamera.core Cc label
.. docstring:: gamera.core Image data ncols nrows offset_x offset_y ul ur ll lr

Bounding box
------------

Bounding box operations on ``Image`` objects are inherited from the
Rect__ class.  

.. __: dimension_types.html#rect

Classification
--------------

See `Classification plugins`__.

.. __: classification.html


Special image views
===================

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
--------------------

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``:

.. code:: Python

  # 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:

.. code:: Python

  # 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))

.. docstring:: gamera.core Cc __init__


Multi-Label Connected Components
--------------------------------

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.

.. docstring:: gamera.core MlCc __init__

.. docstring:: gamera.core MlCc has_label get_labels add_label remove_label relabel
.. docstring:: gamera.core MlCc convert_to_cc convert_to_cc_list
.. docstring:: gamera.core MlCc get_neighbors add_neighbors


Image functions
===============

There are a number of free functions for dealing with images.

File
----

.. docstring:: gamera core load_image image_info

GUI
---

.. docstring:: gamera core display_multi

