There are different ways to implement algorithms that need random image access.
One way is to use the "explicit image data request" concept to request arbitrary tiles from the input image and to manage them as data chunks This is often useful when explicit data needs to be passed to function calls or direct pointer access is needed. See Section 3.1.12, “Explicit Image Data Requests from Module Inputs” for more information.
Another way is to use the "virtual volume" concept. This concept
is especially useful for accessing very large images where no direct
pointer or memory access and
set
/getValue
methods are
sufficient. See Section 4.3.3, “VirtualVolume
Concept” for more
information and Section 2.3.7, “
VirtualVolume
” for examples.
There are different approaches to processing one or more input images sequentially. In order to process very large images that may not fit into memory, it is crucial to perform the processes step by step. Some algorithms can simply do this page-wise, and other algorithms need random access.
The most common approach is to use the
processAllPages
command available as a function in the
class Module
to force the processing of all
pages via calculateOutputSubImage()
calls. This concept
is discussed in detail in Section 3.1.17, “Processing Input Images Sequentially” and is very similar to
the implementation of a normal page-based module. The example
calculates a masked average of all image voxels in a page-based
manner.
The "virtual volume" concept is another concept often used. This
concept provides random access to the managed image. Then it is easy
to implement a normal loop to traverse all voxels or to use the
moveCursorXWrapAround()
function on a typed virtual
volume to move a cursor over each voxel of the image, comparable to an
iterator. See Section 4.3.3, “VirtualVolume
Concept” for more
information and Section 2.3.7, “
VirtualVolume
” for examples.
The VirtualVolume
and the
TVirtualVolume
classes manage an efficient
voxel access to the output image of an input module or to a
'standalone' image. See Section 2.3.7, “
VirtualVolume
” for example
code.
So it is possible to implement random access to a paged input
image or to a pure virtual image without mapping more than a limited
number of bytes. Pages of the input volume are mapped temporarily into
memory when needed. If no input volume is specified, the pages are
created and filled with a fill value. When the permitted memory size
is exceeded, older mapped pages are removed. When pages are written,
they are mapped until the virtual volume instance is removed or until
they are explicitly cleared by the application. Virtual volumes can
easily be accessed by using setVoxel
and
getValue
. These kind of accesses are
well-optimized code that might need between 9 (1D), 18 (3D) and 36
(6D) instructions per voxel if the page at the position is already
mapped.
A cursor manager for moving the cursor with
moveCursor*
(forward) and reverseMoveCursor*
(backward) is also available. About 5-9 instructions might be executed
for these move methods. setCursorValue
and
getCursorValue
provide voxel access. Good
compilers and already mapped images might require about 5-7
instructions. So the cursor approach will probably be faster for data
volumes with more than two dimensions.
All the virtual volume access calls can be executed with or
without error handling (see last and default parameter of
constructors). If areExceptionsOn
is
true,
every access to the virtual volume is
tested and if necessary, exceptions are thrown which can be caught by
the code calling the virtual volume methods. Otherwise, most functions
do not perform error handling.
Note | |
---|---|
Exception handling versions are slower than versions with disabled exceptions. However, this is the only way to handle accesses safely. |
Tip | |
---|---|
This class is the recommended alternative for global image
processing algorithms to using an actual global image
( |
© 2024 MeVis Medical Solutions AG