Skip to content

Images

Images are rectangular grids of pixel values.

Sample: An image quantity of a majestic cat, shown here in the ImGui window display mode.

image example

Floating Quantities

Images are floating quantities, which means they can be added to the scene at the root level, or added to any kind of structure.

See the floating quantity introduction for more info.

Example:

#include "polyscope/image_quantity.h"
polyscope::init();

// Your image data, must be populated somehow
// Buffer layouts are assumed to be [rows, columns, components]
// As always, Polyscope's data adaptors allow it to directly read from many
// containers: std::vector<>, Eigen::MatrixXd, raw buffers, etc.
int width = 1024;
int height = 768;
std::vector<std::array<float, 3>> imageColor(width * height);
std::vector<std::array<float, 4>> imageColorAlpha(width * height);
std::vector<float> imageScalar(width * height);

// == Add images at the root level of the scene

polyscope::ColorImageQuanitity* colorImage =
polyscope::addColorImageQuantity("test color image", width, height, imageColor, 
                                  polyscope::ImageOrigin::UpperLeft);
polyscope::addColorAlphaImageQuantity("test color alpha image", width, height, imageColorAlpha,
                                      polyscope::ImageOrigin::UpperLeft);
polyscope::ColorImageQuanitity* scalarImage =
polyscope::addScalarImageQuantity("test scalar image", width, height, imageScalar,
                                  polyscope::ImageOrigin::UpperLeft);

// Set some options
colorImage->setEnabled(true);
colorImage->setShowFullscreen(false);
colorImage->setShowInImGuiWindow(true);
scalarImage->setColorMap("blues");
scalarImage->setMapRange({0.0, 10.0});

// == Add images associated with a structure
// Here, a camera view, you could also use a point cloud, or a mesh, etc
polyscope::CameraView* targetView = polyscope::getCameraView("my view"); // some structure you previously registered

polyscope::ColorImageQuanitity* colorImageView =
targetView->addColorImageQuantity("test color image", width, height, imageColor, 
                                  polyscope::ImageOrigin::UpperLeft);
targetView->addColorAlphaImageQuantity("test color alpha image", width, height, imageColorAlpha,
                                       polyscope::ImageOrigin::UpperLeft);
targetView->addScalarImageQuantity("test scalar image", width, height, imageScalar,
                                    polyscope::ImageOrigin::UpperLeft);

// When added to a camera view, images can be displayed in the camera frame
colorImageView->setShowInCameraBillboard(true);

polyscope::show();

Images vs. Render Images

If your image happens to represent a rendering of the scene from the user’s viewport (for example, from custom renderer code), check out the Render Image quantity, which offers additional functionality for view-rendered images such as depth-compositing them into the scene to layer and blend with other content.

Camera Views

Image quantities get special functionality when added to CameraView structures: they can additionally be displayed in the camera frame, aligned with the view of the scene.

Image Array Layout

Images are always passed as arrays of length width*height, flattened such that the rows are stored contiguously. For multi-channel image data like colors or normals, this becomes a width*height array of tuples, or a width*height x 3 matrix, etc. The ImageOrigin enum controls the row layout order; most commonly the first element is the upper-left of the image.

Remember that Polyscope’s data adaptors allow many container types to be used as input. For instance, an RGB color image could be stored as a such as std::vector<std::array<float,3>>, with .size() == width*height, or an Eigen::MatrixXd with dimensions width*height x 3, etc.

Image Origin

When registering an image quantity, you also need to specify whether the image should be interpreted such that the first row is the “top” row of the image (ImageOrigin::UpperLeft), or the first row is the “bottom” row of the image (ImageOrigin::LowerLeft). This is a confusing issue, as there are many overlapping conventions of coordinate systems and buffer layouts for images.

Most of the time, ImageOrigin::UpperLeft is the right choice.


Scalar Image Quantity

These can be called at the root level, like polyscope::addScalarImageQuantity(), or on a structure, like cameraView->addScalarImageQuantity().

ScalarImageQuantity* addScalarImageQuantity(std::string name, int width, int height, const T& values, ImageOrigin imageOrigin, DataType type = DataType::STANDARD)

Add an image of scalar values

  • width and height are dimensions in pixels
  • values is a flattened array of scalars values per pixel. The type should be adaptable to a float scalar array. See the note above about image array layouts.
  • imageOrigin is the row origin convention, see above
  • type is the scalar datatype as for other scalar quantities

Scalar Quantity Options

These options and behaviors are available for all types of scalar quantities on any structure.

Parameter Meaning Getter Setter Persistent?
enabled is the quantity enabled? bool isEnabled() setEnabled(bool newVal) yes
color map the color map to use std::string getColorMap() setColorMap(std::string newMap) yes
map range the lower and upper limits used when mapping the data in to the color map std::pair<double,double> getMapRange() setMapRange(std::pair<double,double>) and resetMapRange() no
isolines enabled are isolines shaded (default=false) bool getIsolinesEnabled() setIsolinesEnabled(bool newVal) yes
isoline width width of isoline stripes, in data units float getIsolineWidth() setIsolineWidth(float newVal) yes
isoline darkness darkness of isoline stripes (default=0.7) float getIsolineDarkness() setIsolineDarkness(float newVal) yes

(all setters return this to support chaining. setEnabled() returns generic quantity, so chain it last)


Color Image Quantity

These can be called at the root level, like polyscope::addColorImageQuantity(), or on a structure, like cameraView->addColorImageQuantity().

ColorImageQuantity* addColorImageQuantity(std::string name, int width, int height, const T& values_rgb, ImageOrigin imageOrigin)

Add an image of rgb color values

  • width and height are dimensions in pixels
  • values_rgb is a flattened array of rgb values per pixel. The type should be adaptable to a 3-vector array of floats. See the note above about image array layouts.
  • imageOrigin is the row origin convention, see above

RGB values are interpreted in the range [0,1].

ColorImageQuantiy* addColorAlphaImageQuantity(std::string name, int width, int height, const T& values_rgba, ImageOrigin imageOrigin)

Add an image of rgb color values

  • width and height are dimensions in pixels
  • values_rgba is a flattened array of rgba values per pixel. The type should be adaptable to a 4-vector array of floats. See the note above about image array layouts.
  • imageOrigin is the row origin convention, see above

RGB values are interpreted in the range [0,1].

By default, alpha values are interpreted to be non-premultiplied. Use colorAlphaImage->setIsPremultiplied(true); to directly pass premultiplied alpha images.

Color Quantity Options

These options and behaviors are available for all types of color quantities on any structure.

Parameter Meaning Getter Setter Persistent?
enabled is the quantity enabled? bool isEnabled() setEnabled(bool newVal) yes

(all setters return this to support chaining. setEnabled() returns generic quantity, so chain it last)


Image Options

These options are common to all images

Parameter Meaning Getter Setter Persistent?
transparency the image transparency float getTransparency() setTransparency(float val) yes
show fullscreen show in the full window, if enabled bool getShowFullscreen() setShowFullscreen(bool val) yes
show in ImGui show in an ImGui UI window, if enabled bool getShowInImGuiWindow() setShowInImGuiWindow(bool val) yes
show in camera billboard for CameraView structure only, if enabled bool getShowInCameraBillboard() setShowInCameraBillboard(bool val) yes