Display » DIPviewer module

Interactive image display.

Introduction

DIPlib includes an OpenGL-based image viewer to help in the visualization of intermediate results. Its main purpose is as a debugging tool. It exists in its own library, which must be linked separately if used. The viewer contains two main classes

  1. dip::viewer::ImageViewer, to visualize 2D 8-bit RGB images
  2. dip::viewer::SliceViewer, to visualize 2D slices of nD (tensor) images

More than one viewer can be active at the same time, and the separate windows are managed by a primitive window manager. Two libraries are supported for window management:

  1. GLUT (dip::viewer::GLUTManager): The venerable OpenGL Utility Toolkit, in the form of FreeGLUT.

  2. GLFW (dip::viewer::GLFWManager): GLFW is more modern than GLUT, and better supported by MacOS. Its disadvantage is that it requires the user to poll an event handler from the main thread of the program, something that is baked into the MacOS Cocoa framework.

To use the dip::viewer::ImageViewer, the image must first be converted to 8-bit RGB, for example using the dip::ImageDisplay class. It does not have a user interface, and just shows the image.

User interface

SliceViewer showing the chromo3d.ics test image

dip::viewer::SliceViewer is more elaborate. Its user interface consists of four main parts: The main visualization window, the control panel, the histogram, and the status bar.

Main visualization window

The main visualization window on the left shows three projections, nominally XY, XZ and YZ. The upper left corner visualizes the different tensor elements.

Control panel

The control panel allows the user to select different ways of visualizing the image. It consists of four lists of options:

  1. Color space, being

    • SPA: image color space; this disregards the mapping.
    • RGB: RGB color space, from any 3 tensor elements.
    • GRY: Single grey value.
    • SEQ: Single value mapped to a sequential blue-magenta-yellow colormap.
    • DIV: Single value mapped to a divergent blue-grey-yellow colormap. Use for symmetric mappings.
    • CYC: Single value mapped to a cyclic magenta-yellow-green-blue colormap. Use for angles.
    • LBL: Single value mapped to sequentially disparate colors. Use for labels.
  2. Mapping, being

    • 0-1: Unit values.
    • ANG: Data between [-π, π].
    • 255: 8-bit data.
    • LIN: Linear interpolation between the global minimum and maximum values.
    • SYM: Linear interpolation that is symmetric around 0.
    • LOG: Logarithmic mapping.
  3. Complex mapping, being

    • REA: Real part.
    • IMG: Imaginary part.
    • MAG: Magnitude.
    • PHA: Phase.
  4. Projection, being

    • SLC: Single slice around operating point.
    • MIN: Minimum over dimensions perpendicular to slice.
    • MEA: Mean over dimensions perpendicular to slice.
    • MAX: Maximum over dimensions perpendicular to slice.

Histogram

The histogram shows both the frequency of intensities (100 bins between global minimum and maximum values), as well as the minimum and maximum values themselves. The colorbar left of the histogram shows how these values are mapped in the main visualization window. Changing the mapping in the control panel does not change the histogram extents, but does change the colorbar.

The histogram also indicates the value of the operating point and the current mapping range.

Status bar

The status bar gives the current pixel value, and shows option values after you change them.

Interaction

Interaction occurs mainly within the main visualization window, and depends on where it occurs:

Tensor elements

Within the tensor visualization subwindow, left-clicking selects the tensor element to visualize. If the RGB color space is chosen, left-clicking allocates the next available color (R, G or B) until three elements have been selected. Left-clicking on an already selected element deselects it.

Slices

Left-clicking in a slice changes the operating point for the visualized dimension(s). If slice projection is used, this will also affect the slices that are being visualized in the other projections.

Shift-left-dragging sets the projection ROI. The ROI edge closest to the cursor is selected to be moved. This is only available when minimum, mean, or maximum projection is used.

Middle-dragging gives some limited control over the relative sizes of the three projections.

Right-dragging moves the slice, which is convenient when zooming in.

Scroll wheel zooms in and out, centering in the current cursor position. Zooming in on the ancillary windows (nominal XZ and YZ) only zooms the Z dimension relatively.

Slice labels

Right-clicking on a slice label changes the visualized dimension for that projection. In the special case of selecting ‘-‘, a 1D slice is shown. Note that the horizontal dimensions of the nominal XY and XZ slices are necessarily the same, as are the vertical dimensions of the nominal XY and YZ slices.

Zooming near the slice labels only zooms that dimension.

Histogram

Left-dragging in the histogram changes the mapping range limits.

Status bar

If the status bar is displaying the current operating point, using the scroll wheel on the coordinates will step through the appropriate dimension.

To the right of the status bar is the Link indicator, which can be used to link to other windows. Simply click the indicator in the source window, and then in the destination window. Operating point, zoom and offset will then be shared between the windows. Right-click to unlink.

There are also a few keyboard shortcuts:

  • D and A: Step through the first image dimension.

  • S and W: Step through the second image dimension.

  • N and P: Step through the third image dimension.

  • F and B: Step through the fourth image dimension.

  • 1 through 0: Select tensor element (first element is leftmost).

  • Ctrl + 1: Sets a 1:1 image pixel to screen pixel zoom for all dimensions.

  • Ctrl + F: Sets the image to fill the screen area, but maintaining the XY aspect ratio. The zoom of non-visualized dimensions is reset to 1.

  • Ctrl + L: Sets linear mapping between global minimum and maximum values.

  • Ctrl + N: Creates a linked clone of the current viewer. Convenient when wanting to display different tensor elements, mappings, etc.

  • Ctrl + R: Resets the projection ROI.

  • Ctrl + W: Closes the current window.

  • Ctrl + Shift + W: Closes all windows.

Usage example

The viewer is most easily used through the dip::viewer namespace. Simply call

dip::viewer::Show( image );

after including dipviewer.h to show an image in the slice viewer. After all images have been shown this way, you can call

dip::viewer::Spin();

to enable mouse interaction. If you wish to continue your program, you must instead call

dip::viewer::Draw();

periodically. Make sure to call dip::viewer::Spin when you’re done to ensure a clean exit.

See examples/cpp/viewer.cpp for a usage example of the full interface.

Namespaces

namespace dip::viewer
Contains all functionality for DIPviewer.

Classes

class dip::viewer::ControlViewPort
Allows the user to control how the image is displayed.
class dip::viewer::GLFWManager
Simple GLFW window manager.
class dip::viewer::GLUTManager
Simple GLUT window manager.
class dip::viewer::HistogramViewPort
Controls grey-value mapping range and shows color mapping.
class dip::viewer::ImageView
class dip::viewer::ImageViewer
Non-interactive 2D RGB image viewer.
class dip::viewer::LinkViewPort
Handles viewer linking.
class dip::viewer::Window
Simple GL window
class dip::viewer::Manager abstract
Simple window manager.
class dip::viewer::SliceView
class dip::viewer::SliceViewer
Interactive nD tensor image viewer.
class dip::viewer::StatusViewPort
Displays the dip::viewer::Viewer’s status.
class dip::viewer::TensorViewPort
Allows the user to control which tensor elements are visualized.
struct dip::viewer::ViewingOptions
Model that determines the dip::viewer::SliceViewer’s behavior
class dip::viewer::View
Displays a view of the dip::viewer::ViewingOptions model
class dip::viewer::ViewPort
Handles interaction in a certain display area to control the dip::viewer::ViewingOptions model
class dip::viewer::Viewer abstract
A Window for viewing a dip::Image

Aliases

using dip::viewer::WindowPtr = std::shared_ptr<Window>
Shared pointer to a Window
using dip::viewer::FloatRange = std::pair<dip::dfloat, dip::dfloat>
Specifies a range of values between a lower and upper limit
using dip::viewer::FloatRangeArray = std::vector<FloatRange>
Specifies an array of ranges (typically one per tensor element)

Functions

auto dip::viewer::Show(dip::Image const& image, dip::String const& title = "", dip::uint width = 0, dip::uint height = 0) -> std::shared_ptr<SliceViewer>
Show an image in the slice viewer.
auto dip::viewer::ShowSimple(dip::Image const& image, dip::String const& title = "", dip::uint width = 0, dip::uint height = 0) -> std::shared_ptr<ImageViewer>
Show a 2D grey-value or RGB image, of type dip::DT_UINT8.
void dip::viewer::Spin()
Wait until all windows are closed.
void dip::viewer::Draw()
Process user event queue.
void dip::viewer::CloseAll()
Close all open windows.
template<typename T>
auto dip::viewer::rangeMap(T val, double offset, double scale, dip::viewer::ViewingOptions::Mapping mapping) -> dip::dfloat
Maps an image grey-value onto [0,255]
template<typename T>
auto dip::viewer::rangeMap(T val, dip::viewer::ViewingOptions const& options) -> dip::dfloat
Maps an image grey-value onto [0,255]
template<typename T>
auto dip::viewer::to_string(dip::DimensionArray array) -> std::string
String conversion for dip::DimensionArray
void dip::viewer::ApplyViewerColorMap(dip::Image& in, dip::Image& out, dip::viewer::ViewingOptions& options)
Applies the colormap defined by the dip::viewer::ViewingOptions

Macros

#define DIPVIEWER_EXPORT
Indicates that the function or class is exported from the shared library.
#define DIPVIEWER_NO_EXPORT
Indicates that the function or class is not exported from the shared library.
#define DIPVIEWER_CLASS_EXPORT
Specifically for classes in a inheritance hierarchy and that must be passed across the executable/shared library interface. See DIP_CLASS_EXPORT for more details.

Alias documentation

using dip::viewer::WindowPtr = std::shared_ptr<Window>

Shared pointer to a Window

using dip::viewer::FloatRange = std::pair<dip::dfloat, dip::dfloat>

Specifies a range of values between a lower and upper limit

using dip::viewer::FloatRangeArray = std::vector<FloatRange>

Specifies an array of ranges (typically one per tensor element)

Function documentation

std::shared_ptr<SliceViewer> dip::viewer::Show(dip::Image const& image, dip::String const& title = "", dip::uint width = 0, dip::uint height = 0)
#include "dipviewer.h"

Show an image in the slice viewer.

A new interactive dip::viewer::SliceViewer window is created for the image. title sets the window title. If both width and height are larger than zero, they specify the size of the window created.

Call dip::viewer::Draw or dip::viewer::Spin to enable user interaction.

Calling dip::viewer::Show or dip::viewer::ShowSimple creates an internal dip::viewer::Manager object, which needs to be freed before exiting the application to prevent memory leaks. dip::viewer::Spin and dip::viewer::CloseAll will free the internal manager object. You need to call one of these two functions at an appropriate time after calling dip::viewer::Show or dip::viewer::ShowSimple.

std::shared_ptr<ImageViewer> dip::viewer::ShowSimple(dip::Image const& image, dip::String const& title = "", dip::uint width = 0, dip::uint height = 0)
#include "dipviewer.h"

Show a 2D grey-value or RGB image, of type dip::DT_UINT8.

A new non-interactive dip::viewer::ImageViewer window is created for the image. title sets the window title. width and height specify the size of the window created.

If either width or height is 0, it is computed from the other value so as to preserve the image’s aspect ratio. If both are 0 (the default), the image is displayed in its natural size (one image pixel to one screen pixel) but scaled down if otherwise the window would exceed 512 pixels along either dimension.

A scalar (grey-value) image will be replicated across three channels to form an RGB image (meaning that data will be copied).

Calling dip::viewer::Show or dip::viewer::ShowSimple creates an internal dip::viewer::Manager object, which needs to be freed before exiting the application to prevent memory leaks. dip::viewer::Spin and dip::viewer::CloseAll will free the internal manager object. You need to call one of these two functions at an appropriate time after calling dip::viewer::Show or dip::viewer::ShowSimple.

void dip::viewer::Spin()
#include "dipviewer.h"

Wait until all windows are closed.

This function allows user interaction in all slice viewer windows created. Returns when all windows are closed. It also frees the internal window manager object.

Calling dip::viewer::Show or dip::viewer::ShowSimple creates an internal dip::viewer::Manager object, which needs to be freed before exiting the application to prevent memory leaks. dip::viewer::Spin and dip::viewer::CloseAll will free the internal manager object. You need to call one of these two functions at an appropriate time after calling dip::viewer::Show or dip::viewer::ShowSimple.

void dip::viewer::Draw()
#include "dipviewer.h"

Process user event queue.

This function allows user interaction in all slice viewer windows created. Returns immediately, and needs to be called repeatedly for continuous interaction.

void dip::viewer::CloseAll()
#include "dipviewer.h"

Close all open windows.

Closes all open windows and frees the internal window manager object.

Calling dip::viewer::Show or dip::viewer::ShowSimple creates an internal dip::viewer::Manager object, which needs to be freed before exiting the application to prevent memory leaks. dip::viewer::Spin and dip::viewer::CloseAll will free the internal manager object. You need to call one of these two functions at an appropriate time after calling dip::viewer::Show or dip::viewer::ShowSimple.

template<typename T>
dip::dfloat dip::viewer::rangeMap(T val, double offset, double scale, dip::viewer::ViewingOptions::Mapping mapping)

Maps an image grey-value onto [0,255]

template<typename T>
dip::dfloat dip::viewer::rangeMap(T val, dip::viewer::ViewingOptions const& options)

Maps an image grey-value onto [0,255]

template<typename T>
std::string dip::viewer::to_string(dip::DimensionArray array)

String conversion for dip::DimensionArray

Macro documentation

#define DIPVIEWER_EXPORT

Indicates that the function or class is exported from the shared library.

#define DIPVIEWER_NO_EXPORT

Indicates that the function or class is not exported from the shared library.

#define DIPVIEWER_CLASS_EXPORT

Specifically for classes in a inheritance hierarchy and that must be passed across the executable/shared library interface. See DIP_CLASS_EXPORT for more details.