demo version
This commit is contained in:
parent
fbb282a801
commit
672d6daa8e
125 changed files with 17918 additions and 1481 deletions
|
@ -0,0 +1,548 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2021 Nerian Vision GmbH
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef VISIONTRANSFER_IMAGESET_H
|
||||
#define VISIONTRANSFER_IMAGESET_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include "visiontransfer/common.h"
|
||||
|
||||
namespace visiontransfer {
|
||||
|
||||
/**
|
||||
* \brief A set of one to three images, but usually two (the left camera image
|
||||
* and the disparity map). One- and three-image modes can be enabled
|
||||
* in the device configuration interface.
|
||||
*
|
||||
* For backwards compatibility, for sets of at least two images the image at
|
||||
* index 0 is always the left camera image, while the one at index 1 is either the
|
||||
* disparity map if in disparity processing mode, or the right image otherwise.
|
||||
*
|
||||
* All images must be of equal width and height, but are allowed to have
|
||||
* different pixel formats. Please note that the class does not manage the
|
||||
* pixel data but only keeps pointers. You thus need to ensure that the pixel
|
||||
* data remains valid for as long as this object persists.
|
||||
*/
|
||||
class VT_EXPORT ImageSet {
|
||||
public:
|
||||
static const int MAX_SUPPORTED_IMAGES = 3;
|
||||
/**
|
||||
* \brief Image formats that can be transferred.
|
||||
*/
|
||||
enum ImageFormat {
|
||||
/// 8-bit greyscale format
|
||||
FORMAT_8_BIT_MONO,
|
||||
|
||||
/// 8-bit RGB format
|
||||
FORMAT_8_BIT_RGB,
|
||||
|
||||
/// 12-bit greyscale format plus 4 bits of padding
|
||||
/// (hence a total of 16 bits).
|
||||
FORMAT_12_BIT_MONO
|
||||
};
|
||||
|
||||
/**
|
||||
* \deprecated Please use the new format constants in \c ImageFormat.
|
||||
*/
|
||||
enum ImageFormat_Deprecated {
|
||||
FORMAT_8_BIT = FORMAT_8_BIT_MONO,
|
||||
FORMAT_12_BIT = FORMAT_12_BIT_MONO
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Supported image types
|
||||
*/
|
||||
enum ImageType {
|
||||
IMAGE_UNDEFINED,
|
||||
IMAGE_LEFT,
|
||||
IMAGE_DISPARITY,
|
||||
IMAGE_RIGHT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Default constructor creating an image set with no pixel data.
|
||||
*/
|
||||
ImageSet();
|
||||
|
||||
/**
|
||||
* \brief Copy constructor creating a shallow copy of the image set.
|
||||
*/
|
||||
ImageSet(const ImageSet& other);
|
||||
|
||||
~ImageSet();
|
||||
ImageSet& operator= (ImageSet const& other);
|
||||
|
||||
/**
|
||||
* \brief Sets a new width for both images.
|
||||
*/
|
||||
void setWidth(int w) {width = w;}
|
||||
|
||||
/**
|
||||
* \brief Sets a new width for both images.
|
||||
*/
|
||||
void setHeight(int h) {height = h;}
|
||||
|
||||
/**
|
||||
* \brief Sets a new row stride for the pixel data of one image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to set the
|
||||
* row stride (0 ... getNumberOfImages()-1).
|
||||
* \param stride The row stride that shall be set.
|
||||
*/
|
||||
void setRowStride(int imageNumber, int stride) {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
rowStride[imageNumber] = stride;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the pixel format for the given image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to set the
|
||||
* pixel format (0 ... getNumberOfImages()-1).
|
||||
* \param format The pixel format that shall be set.
|
||||
*/
|
||||
void setPixelFormat(int imageNumber, ImageFormat format) {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
formats[imageNumber] = format;
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
DEPRECATED("Use setPixelFormat(int, ImageFormat) instead") void setPixelFormat(int imageNumber, ImageFormat_Deprecated format) {
|
||||
setPixelFormat(imageNumber, static_cast<ImageFormat>(format));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Sets the pixel data for the given image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to set the
|
||||
* pixel data (0 ... getNumberOfImages()-1).
|
||||
* \param pixelData The pixel data that shall be set.
|
||||
*/
|
||||
void setPixelData(int imageNumber, unsigned char* pixelData) {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
data[imageNumber] = pixelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the pointer to the disparity-to-depth mapping matrix q.
|
||||
*
|
||||
* No data is copied. The data which q is pointing to has to remain valid
|
||||
* for as long as this object exists.
|
||||
*/
|
||||
void setQMatrix(const float* q) {
|
||||
qMatrix = q;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the sequence number for this image set.
|
||||
*/
|
||||
void setSequenceNumber(unsigned int num) {
|
||||
seqNum = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the time at which this image set has been captured.
|
||||
*
|
||||
* \param seconds The time stamp with a resolution of one second.
|
||||
* \param microsec The fractional seconds part of the time stamp with
|
||||
* a resolution of 1 microsecond.
|
||||
*/
|
||||
void setTimestamp(int seconds, int microsec) {
|
||||
timeSec = seconds;
|
||||
timeMicrosec = microsec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the value range for the disparity map contained in this
|
||||
* image set.
|
||||
*
|
||||
* \param minimum Minimum disparity value.
|
||||
* \param maximum Maximum disparity value.
|
||||
*/
|
||||
void setDisparityRange(int minimum, int maximum) {
|
||||
minDisparity = minimum;
|
||||
maxDisparity = maximum;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the subpixel factor for this image set.
|
||||
*/
|
||||
void setSubpixelFactor(int subpixFact) {
|
||||
subpixelFactor = subpixFact;
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
/**
|
||||
* \brief Sets whether this is a left camera image and disparity
|
||||
* map set, or two raw camera images.
|
||||
*
|
||||
* DEPRECATION NOTICE: Please use setNumberOfImages() and setIndexOf()
|
||||
* for more comprehensive control of the images in the image set.
|
||||
*/
|
||||
DEPRECATED("Only compatible with two-image sets: use setNumberOfImages() and setIndexOf() instead")
|
||||
void setImageDisparityPair(bool dispPair);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Returns the width of each image.
|
||||
*/
|
||||
int getWidth() const {return width;}
|
||||
|
||||
/**
|
||||
* \brief Returns the height of each image.
|
||||
*/
|
||||
int getHeight() const {return height;}
|
||||
|
||||
/**
|
||||
* \brief Returns the row stride for the pixel data of one image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to obtain the
|
||||
* row stride (0 ... getNumberOfImages()-1).
|
||||
*
|
||||
* Please use getRowStride(ImageSet::ImageType) to access the
|
||||
* data by their abstract role in lieu of their index in the set.
|
||||
*/
|
||||
int getRowStride(int imageNumber) const {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
return rowStride[imageNumber];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the row stride for the pixel data of one image.
|
||||
*
|
||||
* \param what ImageType of the desired channel.
|
||||
*
|
||||
* This function will throw an exception when the ImageType
|
||||
* is not present in this set (use hasImageType(what) to check).
|
||||
*/
|
||||
int getRowStride(ImageType what) const {
|
||||
int idx = getIndexOf(what, true);
|
||||
return getRowStride(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the pixel format for the given image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to receive the
|
||||
* pixel format (0 ... getNumberOfImages()-1).
|
||||
*
|
||||
* Please use getPixelFormat(ImageSet::ImageType) to access the
|
||||
* data by their abstract role in lieu of their index in the set.
|
||||
*/
|
||||
ImageFormat getPixelFormat(int imageNumber) const {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
return formats[imageNumber];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the pixel format for the given image.
|
||||
*
|
||||
* \param what ImageType of the desired channel.
|
||||
*
|
||||
* This function will throw an exception when the ImageType
|
||||
* is not present in this set (use hasImageType(what) to check).
|
||||
*/
|
||||
ImageFormat getPixelFormat(ImageType what) const {
|
||||
int idx = getIndexOf(what, true);
|
||||
return getPixelFormat(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the pixel data for the given image.
|
||||
*
|
||||
* \param imageNumber Number of the image for which to receive the
|
||||
* pixel data (0 ... getNumberOfImages()-1).
|
||||
*
|
||||
* Please use getPixelData(ImageSet::ImageType) to access the
|
||||
* data by their abstract role in lieu of their index in the set.
|
||||
*/
|
||||
unsigned char* getPixelData(int imageNumber) const {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
return data[imageNumber];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the pixel data for the given image.
|
||||
*
|
||||
* \param what ImageType of the desired channel.
|
||||
*
|
||||
* This function will throw an exception when the ImageType
|
||||
* is not present in this set (use hasImageType(what) to check).
|
||||
*/
|
||||
unsigned char* getPixelData(ImageType what) const {
|
||||
int idx = getIndexOf(what, true);
|
||||
return getPixelData(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a pointer to the disparity-to-depth mapping matrix q.
|
||||
*/
|
||||
const float* getQMatrix() const {
|
||||
return qMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the sequence number for this image set.
|
||||
*/
|
||||
unsigned int getSequenceNumber() const {return seqNum;}
|
||||
|
||||
/**
|
||||
* \brief Returns the time at which this image set has been captured.
|
||||
*
|
||||
* \param seconds The time stamp with a resolution of one second.
|
||||
* \param microsec The fractional seconds part of the time stamp with
|
||||
* a resolution of 1 microsecond.
|
||||
*/
|
||||
void getTimestamp(int& seconds, int& microsec) const {
|
||||
seconds = timeSec;
|
||||
microsec = timeMicrosec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the value range for the disparity map contained in this
|
||||
* image set. If the image set does not contain any disparity data
|
||||
* then the disparity range is undefined.
|
||||
*
|
||||
* \param minimum Minimum disparity value.
|
||||
* \param maximum Maximum disparity value.
|
||||
*/
|
||||
void getDisparityRange(int& minimum, int& maximum) const {
|
||||
minimum = minDisparity;
|
||||
maximum = maxDisparity;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the subpixel factor for this image set.
|
||||
*/
|
||||
int getSubpixelFactor() const {
|
||||
return subpixelFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes one image of the set to a PGM or PPM file.
|
||||
*
|
||||
* \param imageNumber The number of the image that shall be written.
|
||||
* \param File name of the PGM or PPM file that shall be created.
|
||||
*/
|
||||
void writePgmFile(int imageNumber, const char* fileName) const;
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
/**
|
||||
* \brief Returns true if this is a left camera image and disparity
|
||||
* map pair.
|
||||
*
|
||||
* DEPRECATION NOTICE: this is a legacy function; in case of image sets
|
||||
* with one or three images, the result may not be as expected
|
||||
* (this functions returns true only for the case of exactly two images:
|
||||
* left image plus disparity image).
|
||||
*
|
||||
* The new function hasImageType(ImageSet::ImageType) provides better
|
||||
* granularity of what data are enabled and present.
|
||||
*/
|
||||
DEPRECATED("Only compatible with two-image sets: use hasImageType(ImageSet::IMAGE_DISPARITY) instead")
|
||||
bool isImageDisparityPair() const {
|
||||
return (getNumberOfImages()==2) && hasImageType(IMAGE_DISPARITY);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Makes a deep copy of this image set.
|
||||
*/
|
||||
void copyTo(ImageSet& dest);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of bytes that are required to store one
|
||||
* image pixel.
|
||||
*
|
||||
* \param imageNumber The number of the image (0 ... getNumberOfImages()-1).
|
||||
*/
|
||||
int getBytesPerPixel(int imageNumber) const {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
return getBytesPerPixel(formats[imageNumber]);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the number of bits that are required to store one
|
||||
* image pixel.
|
||||
*
|
||||
* \param imageNumber The number of the image (0 ... getNumberOfImages()-1).
|
||||
*/
|
||||
int getBitsPerPixel(int imageNumber) const {
|
||||
assert(imageNumber >= 0 && imageNumber < getNumberOfImages());
|
||||
return getBitsPerPixel(formats[imageNumber]);
|
||||
}
|
||||
|
||||
int getBitsPerPixel(ImageType what) const {
|
||||
int idx = getIndexOf(what, true);
|
||||
return getBitsPerPixel(idx);
|
||||
}
|
||||
|
||||
static int getBitsPerPixel(ImageFormat format);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of bytes that are required to store one
|
||||
* image pixel with the given pixel format.
|
||||
*/
|
||||
static int getBytesPerPixel(ImageFormat format);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of images in this set
|
||||
*/
|
||||
int getNumberOfImages() const {
|
||||
return numberOfImages;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the number of valid images in this set
|
||||
*/
|
||||
void setNumberOfImages(int number) {
|
||||
assert(number >= 1 && number <= MAX_SUPPORTED_IMAGES);
|
||||
numberOfImages = number;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the ImageType of the specified channel
|
||||
*/
|
||||
ImageType getImageType(int imageNumber) const;
|
||||
|
||||
/**
|
||||
* \brief Returns the index of a specific image type
|
||||
*
|
||||
* \param what ImageType of the desired channel.
|
||||
* \param throwIfNotFound Throw a runtime error instead of returning -1.
|
||||
*
|
||||
* \return Returns the index of the specified type, or -1 if not found.
|
||||
*/
|
||||
int getIndexOf(ImageType what, bool throwIfNotFound=false) const;
|
||||
|
||||
/**
|
||||
* \brief Returns whether a left camera image is included in the enabled data
|
||||
*/
|
||||
bool hasImageType(ImageType what) const {
|
||||
return getIndexOf(what) >= 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Assign an image index to a specified ImageType, -1 to disable
|
||||
*
|
||||
* \param what The ImageType to assign a new image index to.
|
||||
* \param idx The index of the specified ImageType inside the data of
|
||||
* this ImageSet (-1 to disable).
|
||||
*/
|
||||
void setIndexOf(ImageType what, int idx);
|
||||
|
||||
|
||||
#ifdef CV_MAJOR_VERSION
|
||||
/**
|
||||
* \brief Converts one image of the set to an OpenCV image.
|
||||
*
|
||||
* \param imageNumber The number of the image that shall be converted
|
||||
* (0 ... getNumberOfImages()-1).
|
||||
* \param convertRgbToBgr If true, then color images will converted from
|
||||
* RGB to BGR in order to comply to OpenCV's convention.
|
||||
*
|
||||
* For this method to be available, the OpenCV headers need to be
|
||||
* included before including headers for libvisiontransfer.
|
||||
*
|
||||
* Please note that only a shallow copy is performed. The ImageSet object
|
||||
* must be kept alive for as long as the OpenCV image is in use.
|
||||
*/
|
||||
inline void toOpenCVImage(int imageNumber, cv::Mat& dest, bool convertRgbToBgr = true);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Sets the exposure time that was used for capturing the image set
|
||||
*
|
||||
* \param timeMicrosec Exposure time measured in microseconds
|
||||
*/
|
||||
void setExposureTime(int timeMicrosec) {
|
||||
exposureTime = timeMicrosec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the exposure time in microseconds that was used for
|
||||
* capturing the image set.
|
||||
*
|
||||
* \return Exposure time in microseconds
|
||||
*/
|
||||
int getExposureTime() const {
|
||||
return exposureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the timestamp of the last received sync pulse
|
||||
|
||||
* \param seconds The time stamp with a resolution of one second.
|
||||
* \param microsec The fractional seconds part of the time stamp with
|
||||
* a resolution of 1 microsecond.
|
||||
*/
|
||||
void setLastSyncPulse(int seconds, int microsec) {
|
||||
lastSyncPulseSec = seconds;
|
||||
lastSyncPulseMicrosec = microsec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the timestamp of the last received sync pulse
|
||||
*
|
||||
* \param seconds The time stamp with a resolution of one second.
|
||||
* \param microsec The fractional seconds part of the time stamp with
|
||||
* a resolution of 1 microsecond.
|
||||
*/
|
||||
void getLastSyncPulse(int& seconds, int& microsec) const {
|
||||
seconds = lastSyncPulseSec;
|
||||
microsec = lastSyncPulseMicrosec;
|
||||
}
|
||||
|
||||
private:
|
||||
// No pimpl idiom here as almost everything is inlined.
|
||||
int width;
|
||||
int height;
|
||||
int rowStride[MAX_SUPPORTED_IMAGES];
|
||||
ImageFormat formats[MAX_SUPPORTED_IMAGES];
|
||||
unsigned char* data[MAX_SUPPORTED_IMAGES];
|
||||
const float* qMatrix;
|
||||
int timeSec;
|
||||
int timeMicrosec;
|
||||
unsigned int seqNum;
|
||||
int minDisparity;
|
||||
int maxDisparity;
|
||||
int subpixelFactor;
|
||||
int* referenceCounter;
|
||||
int numberOfImages;
|
||||
|
||||
int indexLeftImage;
|
||||
int indexRightImage;
|
||||
int indexDisparityImage;
|
||||
|
||||
int exposureTime;
|
||||
int lastSyncPulseSec;
|
||||
int lastSyncPulseMicrosec;
|
||||
|
||||
void copyData(ImageSet& dest, const ImageSet& src, bool countRef);
|
||||
void decrementReference();
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
// For source compatibility
|
||||
class DEPRECATED("Use ImageSet instead.") ImagePair: public ImageSet {
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "visiontransfer/imageset-opencv.h"
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue