Interfaces » DIPlib-OpenCV interface module

Functions to convert images to and from OpenCV.

Contents

The dip_opencv namespace defines the functions needed to convert between OpenCV cv::Mat objects and DIPlib dip::Image objects.

We define a class dip_opencv::ExternalInterface so that output images from DIPlib can yield an OpenCV image. The function dip_opencv::MatToDip encapsulates (maps) an OpenCV image in a DIPlib image; dip_opencv::DipToMat does the opposite, mapping a DIPlib image as an OpenCV image.

Note: OpenCV is more limited in how the pixel data is stored, and consequently not all DIPlib images can be mapped as an OpenCV image. These are the limitations:

  • The maximum number of channels in OpenCV is CV_CN_MAX (equal to 512 in my copy). DIPlib tensor elements are mapped to channels, but the tensor shape is lost. The tensor stride must be 1.
  • OpenCV recognizes the following types (depths): 8-bit and 16-bit signed and unsigned ints, 32-bit signed ints, and 32-bit and 64-bit floats. Thus, dip::DT_UINT32 cannot be mapped. We choose to map it to 32-bit signed ints, with the potential problem that the upper half of the unsigned range is mapped to negative values (all modern systems use two's complement). dip::DT_BIN is mapped to an 8-bit unsigned integer, see the note below. 64-bit integer images cannot be mapped and throw an exception.
  • Complex pixel values are mapped to CV_32FC2 or CV_64FC2 – a 2-channel float cv::Mat array. Consequently, complex-valued tensor images cannot be mapped.
  • cv::Mat objects can store arrays of any dimensionality larger than 2, but OpenCV functionality is mostly limited to 2D images. Therefore, we only map 2D dip::Image objects in a cv::Mat array. 0D or 1D images will have singleton dimensions appended to force them to be 2D.
  • In OpenCV, the image rows must be contiguous (i.e. the x-stride must be equal to the number of tensor elements), and the y-stride must be positive. This matches DIPlib's default, but if the dip::Image object has strides that don't match OpenCV's requirement (e.g. after extracting a non-contiguous subset of pixels, or calling dip::Image::Mirror or dip::Image::Rotation90), an exception will be thrown. Use dip::Image::ForceNormalStrides to copy the image into a suitable order for mapping. Alternatively, use dip_opencv::CopyDipToMat.

Note: OpenCV does not know a binary image type, and uses an 8-bit unsigned integer with values 0 and 255 where a binary image is intended. This clashes with DIPlib's binary type, which is of the same size but is expected to contain only 0 and 1 values. The functions dip_opencv::FixBinaryImageForDip and dip_opencv::FixBinaryImageForOpenCv fix up binary images for processing in either library.

Classes

class dip_opencv::ExternalInterface
This class is the dip::ExternalInterface for the OpenCV interface.

Functions

auto MatToDip(cv::Mat const& mat, bool forceUnsigned = false) -> dip::Image
Creates a DIPlib image around an OpenCV cv::Mat, without taking ownership of the data.
auto DipToMat(dip::Image const& img) -> cv::Mat
Creates an OpenCV cv::Mat object around a DIPlib image, without taking ownership of the data.
auto CopyDipToMat(dip::Image const& img) -> cv::Mat
Creates an OpenCV cv::Mat object from a DIPlib image by copy.
void FixBinaryImageForDip(dip::Image& img)
Fixes the binary image img to match expectations of DIPlib (i.e. only the bottom bit is used).
void FixBinaryImageForOpenCv(dip::Image& img)
Fixes the binary image img to match expectations of OpenCV (i.e. all bits have the same value).

Function documentation

dip::Image MatToDip(cv::Mat const& mat, bool forceUnsigned = false)

Creates a DIPlib image around an OpenCV cv::Mat, without taking ownership of the data.

This function maps a cv::Mat object to a dip::Image object. The dip::Image object will point to the data in the cv::Mat, which must continue existing until the dip::Image is deleted or Stripped. The output dip::Image is protected to prevent accidental reforging, unprotect it using dip::Image::Protect.

An empty cv::Mat produces a non-forged dip::Image.

If the OpenCV image mat has depth CV_32S (32-bit signed integer), and forceUnsigned is true, then the output dip::Image will be of type dip::DT_UINT32, instead of dip::DT_SINT32.

cv::Mat DipToMat(dip::Image const& img)

Creates an OpenCV cv::Mat object around a DIPlib image, without taking ownership of the data.

This function maps a dip::Image object to a cv::Mat object. The cv::Mat object will point to the data in the dip::Image, which must continue existing until the cv::Mat is deleted.

A non-forged dip::Image produces an empty cv::Mat.

There are many limitations to the images that can be mapped by a cv::Mat, see the description in the documentation to the module: DIPlib-OpenCV interface. You can also use dip_opencv::CopyDipToMat instead.

cv::Mat CopyDipToMat(dip::Image const& img)

Creates an OpenCV cv::Mat object from a DIPlib image by copy.

A non-forged dip::Image produces an empty cv::Mat.

If the image has more than two dimensions, or is a complex-valued tensor image, no copy can be made; an exception will be thrown.