forked from pz4kybsvg/Conception
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
5.9 KiB
170 lines
5.9 KiB
#pragma once
|
|
|
|
#include <limits>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "drake/common/drake_assert.h"
|
|
#include "drake/common/drake_copyable.h"
|
|
#include "drake/common/reset_after_move.h"
|
|
#include "drake/systems/sensors/pixel_types.h"
|
|
|
|
namespace drake {
|
|
namespace systems {
|
|
namespace sensors {
|
|
|
|
// Forward declaration of Image class.
|
|
template <PixelType kPixelType>
|
|
class Image;
|
|
|
|
/// The type for RGB image where the each channel has the type of uint8_t.
|
|
using ImageRgb8U = Image<PixelType::kRgb8U>;
|
|
|
|
/// The type for BGR image where the each channel has the type of uint8_t.
|
|
using ImageBgr8U = Image<PixelType::kBgr8U>;
|
|
|
|
/// The type for RGBA image where the each channel has the type of uint8_t.
|
|
using ImageRgba8U = Image<PixelType::kRgba8U>;
|
|
|
|
/// The type for BGRA image where the each channel has the type of uint8_t.
|
|
using ImageBgra8U = Image<PixelType::kBgra8U>;
|
|
|
|
/// The type for depth image where the channel has the type of float.
|
|
using ImageDepth32F = Image<PixelType::kDepth32F>;
|
|
|
|
/// The type for depth image where the channel has the type of uint16_t.
|
|
using ImageDepth16U = Image<PixelType::kDepth16U>;
|
|
|
|
/// The type for label image where the channel has the type of int16_t.
|
|
using ImageLabel16I = Image<PixelType::kLabel16I>;
|
|
|
|
/// The type for greyscale image where the channel has the type of uint8_t.
|
|
using ImageGrey8U = Image<PixelType::kGrey8U>;
|
|
|
|
/// The type for symbolic image where the channel has the type of
|
|
/// symbolic::Expression.
|
|
using ImageExpr = Image<PixelType::kExpr>;
|
|
|
|
/// Simple data format for Image. For the complex calculation with the image,
|
|
/// consider converting this to other libaries' Matrix data format, i.e.,
|
|
/// MatrixX in Eigen, Mat in OpenCV, and so on.
|
|
///
|
|
/// The origin of image coordinate system is on the left-upper corner.
|
|
///
|
|
/// @tparam kPixelType The pixel type enum that denotes the pixel format and the
|
|
/// data type of a channel.
|
|
/// TODO(zachfang): move most of the function definitions in this class to the
|
|
/// .cc file.
|
|
template <PixelType kPixelType>
|
|
class Image {
|
|
public:
|
|
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(Image)
|
|
|
|
/// This is used by generic helpers such as drake::Value to deduce a non-type
|
|
/// template argument.
|
|
using NonTypeTemplateParameter =
|
|
std::integral_constant<PixelType, kPixelType>;
|
|
|
|
/// An alias for ImageTraits that contains the data type for a channel,
|
|
/// the number of channels and the pixel format in it.
|
|
using Traits = ImageTraits<kPixelType>;
|
|
|
|
/// The data type for a channel.
|
|
using T = typename Traits::ChannelType;
|
|
|
|
/// The number of channels in a pixel.
|
|
static constexpr int kNumChannels = Traits::kNumChannels;
|
|
|
|
/// The size of a pixel in bytes.
|
|
static constexpr int kPixelSize = kNumChannels * sizeof(T);
|
|
|
|
/// The format for pixels.
|
|
static constexpr PixelFormat kPixelFormat = Traits::kPixelFormat;
|
|
|
|
/// Image size only constructor. Specifies a width and height for the image.
|
|
/// All the channel values in all the pixels are initialized with zero.
|
|
/// @param width Size of width for image which should be greater than zero
|
|
/// @param height Size of height for image which should be greater than zero
|
|
Image(int width, int height) : Image(width, height, 0) {}
|
|
|
|
/// Image size and initial value constructor. Specifies a
|
|
/// width, height and an initial value for all the channels in all the pixels.
|
|
/// @param width Size of width for image which should be greater than zero.
|
|
/// @param height Size of height for image which should be greater than zero.
|
|
/// @param initial_value A value set to all the channels in all the pixels
|
|
Image(int width, int height, T initial_value)
|
|
: width_(width),
|
|
height_(height),
|
|
data_(width * height * kNumChannels, initial_value) {
|
|
DRAKE_ASSERT(width > 0);
|
|
DRAKE_ASSERT(height > 0);
|
|
}
|
|
|
|
/// Constructs a zero-sized image.
|
|
Image() = default;
|
|
|
|
/// Returns the size of width for the image
|
|
int width() const { return width_; }
|
|
|
|
/// Returns the size of height for the image
|
|
int height() const { return height_; }
|
|
|
|
/// Returns the result of the number of pixels in a image by the number of
|
|
/// channels in a pixel
|
|
int size() const { return width_ * height_ * kNumChannels; }
|
|
|
|
/// Changes the sizes of the width and height for the image. The values for
|
|
/// them should be greater than zero. (To resize to zero, assign a default-
|
|
/// constructed Image into this; do not use this method.) All the values in
|
|
/// the pixels become zero after resize.
|
|
void resize(int width, int height) {
|
|
DRAKE_ASSERT(width > 0);
|
|
DRAKE_ASSERT(height > 0);
|
|
|
|
data_.resize(width * height * kNumChannels);
|
|
std::fill(data_.begin(), data_.end(), 0);
|
|
width_ = width;
|
|
height_ = height;
|
|
}
|
|
|
|
/// Access to the pixel located at (x, y) in image coordinate system where x
|
|
/// is the variable for horizontal direction and y is one for vertical
|
|
/// direction. To access to the each channel value in the pixel (x, y),
|
|
/// you can do:
|
|
///
|
|
/// ImageRgbaU8 image(640, 480, 255);
|
|
/// uint8_t red = image.at(x, y)[0];
|
|
/// uint8_t green = image.at(x, y)[1];
|
|
/// uint8_t blue = image.at(x, y)[2];
|
|
/// uint8_t alpha = image.at(x, y)[3];
|
|
T* at(int x, int y) {
|
|
DRAKE_ASSERT(x >= 0 && x < width_);
|
|
DRAKE_ASSERT(y >= 0 && y < height_);
|
|
return data_.data() + (x + y * width_) * kNumChannels;
|
|
}
|
|
|
|
/// Const version of at() method. See the document for the non-const version
|
|
/// for the detail.
|
|
const T* at(int x, int y) const {
|
|
DRAKE_ASSERT(x >= 0 && x < width_);
|
|
DRAKE_ASSERT(y >= 0 && y < height_);
|
|
return data_.data() + (x + y * width_) * kNumChannels;
|
|
}
|
|
|
|
/// Compares whether two images are exactly the same.
|
|
bool operator==(const Image& other) const {
|
|
return width_ == other.width_ &&
|
|
height_ == other.height_ &&
|
|
data_ == other.data_;
|
|
}
|
|
|
|
private:
|
|
reset_after_move<int> width_;
|
|
reset_after_move<int> height_;
|
|
std::vector<T> data_;
|
|
};
|
|
|
|
} // namespace sensors
|
|
} // namespace systems
|
|
} // namespace drake
|