Ocean
OpenCVUtilities.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_OPENCV_UTILITIES_H
9 #define META_OCEAN_CV_OPENCV_UTILITIES_H
10 
11 #include "ocean/base/Frame.h"
12 
13 #include "ocean/cv/CV.h"
14 
16 
17 #include <climits>
18 
19 #include <opencv2/core.hpp>
20 
21 namespace Ocean
22 {
23 
24 namespace CV
25 {
26 
27 /**
28  * This class implements utility functions for the migration from OpenCV to Ocean.
29  * @ingroup cv
30  */
31 class OCEAN_CV_EXPORT OpenCVUtilities
32 {
33  public:
34 
35  /**
36  * Convert an Ocean Frame image to an OpenCV image
37  * @param frame An image instance of the Ocean framework
38  * @param copy If true, the data will be copied to (and owned by) to OpenCV Mat.
39  * @return An OpenCV-based version of the input image, will be empty on failure
40  */
41  static inline cv::Mat toCvMat(const Frame& frame, const bool copy = false);
42 
43  /**
44  * Convert an OpenCV image to an Ocean Frame image object.
45  * @param frame The OpenCV image to be converted
46  * @param pixelFormat OpenCV image types do not store the pixel format. For images with 2 or more channels, specify the pixel format.
47  * @param copy If true, the data will be copied to (and owned by) to Ocean frame
48  * @return An Ocean-based version of the input image, will be invalid on failure
49  */
50  static inline Frame toOceanFrame(const cv::Mat& frame, const bool copy = false, const FrameType::PixelFormat pixelFormat = FrameType::FORMAT_UNDEFINED);
51 
52  /**
53  * Convert an OpenCV 3-by-3 matrix (row-major) to an Ocean SquareMatrix3 (column-wise order)
54  * @param matrix An OpenCV instance of a 3-by-3 matrix
55  * @tparam T Type of the matrix elements (usually float or double)
56  * @return The corresponding Ocean matrix
57  */
58  template <typename T>
59  static inline SquareMatrixT3<T> toOceanSquareMatrix3(const cv::Matx<T, 3, 3>& matrix);
60 
61  /**
62  * Convert an OpenCV 2-by-3 matrix (row-major) to an Ocean SquareMatrix3 (column-major)
63  * @param affineTransformation An OpenCV instance of a 2-by-3 matrix (OpenCV assumes the third row to be [0, 0, 1])
64  * @tparam T Type of the matrix elements (usually float or double)
65  * @return The corresponding affine transformation Ocean matrix (third row is [0, 0, 1])
66  */
67  template <typename T>
68  static inline SquareMatrixT3<T> toOceanSquareMatrix3Affine(const cv::Matx<T, 2, 3>& affineTransformation);
69 
70  /**
71  * Convert an Ocean SquareMatrix3 (column-major) to an OpenCV 3-by-3 matrix (row-major)
72  * @param matrix An Ocean SquareMatrix3
73  * @tparam T Type of the matrix elements (usually float or double)
74  * @return OpenCV instance of a 3-by-3 matrix
75  */
76  template <typename T>
77  static inline cv::Matx<T, 3, 3> toCvMatx33(const SquareMatrixT3<T>& matrix);
78 
79  /**
80  * Convert an Ocean SquareMatrix3 (column-major) to an OpenCV 2-by-3 matrix (row-major)
81  * @param affineTransformation An Ocean SquareMatrix3, must be an affine transformation
82  * @tparam T Type of the matrix elements (usually float or double)
83  * @return The corresponding affine transformation as a 2-by-3 OpenCV matrix
84  */
85  template <typename T>
86  static inline cv::Matx<T, 2, 3> toCvMatx23Affine(const SquareMatrixT3<T>& affineTransformation);
87 
88  /**
89  * Converts an Ocean frame data type to a corresponding depth type in OpenCV
90  * @param dataType The Ocean data type that will be converted
91  * @param cvDepth The corresponding OpenCV depth type
92  * @return True if a correspondence has been found, otherwise false
93  */
94  static inline bool toCvDepth(const FrameType::DataType dataType, int& cvDepth);
95 
96  /**
97  * Converts an OpenCV depth type to a corresponding Ocean frame data type
98  * @param cvDepth The OpenCV depth type that will be converted
99  * @param dataType The corresponding Ocean data type
100  * @return True if a correspondence has been found, otherwise false
101  */
102  static inline bool toOceanFrameTypeDataType(const int cvDepth, FrameType::DataType& dataType);
103 };
104 
105 inline cv::Mat OpenCVUtilities::toCvMat(const Frame& frame, const bool copy)
106 {
107  ocean_assert(frame.isValid());
108 
109  const unsigned int channels = frame.channels();
110  const FrameType::DataType dataType = frame.dataType();
111 
112  int cvDepth = CV_8U;
113  if (toCvDepth(dataType, cvDepth) == false)
114  {
115  ocean_assert(false && "Ocean data type not supported by OpenCV");
116  return cv::Mat();
117  }
118 
119  cv::Mat cvMat(frame.height(), frame.width(), CV_MAKETYPE(cvDepth, channels), const_cast<uint8_t*>(frame.constdata<uint8_t>()), frame.strideBytes());
120 
121  if (copy)
122  {
123  cvMat = cvMat.clone();
124  }
125 
126  return cvMat;
127 }
128 
129 inline Frame OpenCVUtilities::toOceanFrame(const cv::Mat& mat, const bool copy, const FrameType::PixelFormat explicitPixelFormat)
130 {
131  const unsigned int width = (unsigned int)(mat.size().width);
132  const unsigned int height = (unsigned int)(mat.size().height);
133 
134  const unsigned int channels = (unsigned int)(mat.channels());
135  ocean_assert(channels > 0u);
136 
137  const int cvDepth = mat.depth();
138 
139  FrameType::PixelFormat pixelFormat = explicitPixelFormat;
140 
141  if (pixelFormat == FrameType::FORMAT_UNDEFINED)
142  {
144 
145  if (toOceanFrameTypeDataType(cvDepth, dataType) == false)
146  {
147  ocean_assert(false && "OpenCV depth type not supported by Ocean");
148  return Frame();
149  }
150 
151  ocean_assert(dataType != FrameType::DT_UNDEFINED);
152  pixelFormat = FrameType::genericPixelFormat(dataType, channels);
153 
154  switch ((std::underlying_type<FrameType::PixelFormat>::type)(pixelFormat))
155  {
156  case FrameType::genericPixelFormat<FrameType::DT_UNSIGNED_INTEGER_8, 1u>():
157  pixelFormat = FrameType::FORMAT_Y8;
158  break;
159 
160  case FrameType::genericPixelFormat<FrameType::DT_UNSIGNED_INTEGER_8, 3u>():
161  pixelFormat = FrameType::FORMAT_BGR24;
162  break;
163 
164  case FrameType::genericPixelFormat<FrameType::DT_UNSIGNED_INTEGER_8, 4u>():
165  pixelFormat = FrameType::FORMAT_BGRA32;
166  break;
167 
168  case FrameType::genericPixelFormat<FrameType::DT_SIGNED_FLOAT_32, 1u>():
169  pixelFormat = FrameType::FORMAT_F32;
170  break;
171 
172  case FrameType::genericPixelFormat<FrameType::DT_SIGNED_FLOAT_64, 1u>():
173  pixelFormat = FrameType::FORMAT_F64;
174  break;
175 
176  default:
177  // we do not have a better mapping for the remaining pixel formats
178  break;
179  }
180  }
181 
182  const unsigned int matStrideBytes = (unsigned int)(mat.step);
183 
184  unsigned int paddingElements = 0u;
185  if (!Frame::strideBytes2paddingElements(pixelFormat, width, matStrideBytes, paddingElements))
186  {
187  ocean_assert(false && "Invalid pixel format!");
188  return Frame();
189  }
190 
192 
193  return Frame(FrameType(width, height, pixelFormat, FrameType::ORIGIN_UPPER_LEFT), (void*)(mat.data), copyMode, paddingElements);
194 }
195 
196 template <typename T>
197 inline SquareMatrixT3<T> OpenCVUtilities::toOceanSquareMatrix3(const cv::Matx<T, 3, 3>& matrix)
198 {
199  return SquareMatrixT3<T>(matrix.val, true);
200 }
201 
202 template <typename T>
203 inline SquareMatrixT3<T> OpenCVUtilities::toOceanSquareMatrix3Affine(const cv::Matx<T, 2, 3>& transformation)
204 {
205  const T* v = transformation.val;
206  return SquareMatrixT3<T>(v[0], v[3], T(0), v[1], v[4], T(0), v[2], v[5], T(1));
207 }
208 
209 template <typename T>
210 inline cv::Matx<T, 3, 3> OpenCVUtilities::toCvMatx33(const SquareMatrixT3<T>& matrix)
211 {
212  return cv::Matx<T, 3, 3>(matrix[0], matrix[3], matrix[6], matrix[1], matrix[4], matrix[7], matrix[2], matrix[5], matrix[8]);
213 }
214 
215 template <typename T>
216 inline cv::Matx<T, 2, 3> OpenCVUtilities::toCvMatx23Affine(const SquareMatrixT3<T>& transformation)
217 {
218  ocean_assert(transformation.isAffine());
219  return cv::Matx<T, 2, 3>(transformation[0], transformation[3], transformation[6], transformation[1], transformation[4], transformation[7]);
220 }
221 
222 inline bool OpenCVUtilities::toCvDepth(const FrameType::DataType dataType, int& cvDepth)
223 {
224 #if defined(CV_VERSION_MAJOR) && CV_VERSION_MAJOR >= 4
225 
226  switch (dataType)
227  {
229  cvDepth = CV_8U;
230  break;
231 
233  cvDepth = CV_8S;
234  break;
235 
237  cvDepth = CV_16U;
238  break;
239 
241  cvDepth = CV_16S;
242  break;
243 
245  cvDepth = CV_32S;
246  break;
247 
249  cvDepth = CV_16F;
250  break;
251 
253  cvDepth = CV_32F;
254  break;
255 
257  cvDepth = CV_64F;
258  break;
259 
260  default:
261  return false;
262  }
263 
264 #else
265 
266  switch (dataType)
267  {
269  cvDepth = CV_8U;
270  break;
271 
273  cvDepth = CV_8S;
274  break;
275 
277  cvDepth = CV_16U;
278  break;
279 
281  cvDepth = CV_16S;
282  break;
283 
285  cvDepth = CV_USRTYPE1;
286  break;
287 
289  cvDepth = CV_32S;
290  break;
291 
293  cvDepth = CV_USRTYPE1;
294  break;
295 
297  cvDepth = CV_USRTYPE1;
298  break;
299 
301  cvDepth = CV_USRTYPE1;
302  break;
303 
305  cvDepth = CV_32F;
306  break;
307 
309  cvDepth = CV_64F;
310  break;
311 
312  default:
313  cvDepth = CV_USRTYPE1;
314  break;
315  }
316 
317 #endif
318 
319  return true;
320 }
321 
322 inline bool OpenCVUtilities::toOceanFrameTypeDataType(const int cvDepth, FrameType::DataType& dataType)
323 {
324  switch (cvDepth)
325  {
326  case CV_8U:
328  break;
329 
330  case CV_8S:
332  break;
333 
334  case CV_16U:
336  break;
337 
338  case CV_16S:
340  break;
341 
342  case CV_32S:
344  break;
345 
346 #if defined(CV_VERSION_MAJOR) && CV_VERSION_MAJOR >= 4
347 
348  case CV_16F:
350  break;
351 
352 #endif
353 
354  case CV_32F:
356  break;
357 
358  case CV_64F:
360  break;
361 
362  default:
363  dataType = FrameType::DT_UNDEFINED;
364  return false;
365  }
366 
367  return true;
368 }
369 
370 } // namespace CV
371 
372 } // namespace Ocean
373 
374 #endif // META_OCEAN_CV_OPENCV_UTILITIES_H
This class implements utility functions for the migration from OpenCV to Ocean.
Definition: OpenCVUtilities.h:32
static cv::Matx< T, 2, 3 > toCvMatx23Affine(const SquareMatrixT3< T > &affineTransformation)
Convert an Ocean SquareMatrix3 (column-major) to an OpenCV 2-by-3 matrix (row-major)
Definition: OpenCVUtilities.h:216
static cv::Matx< T, 3, 3 > toCvMatx33(const SquareMatrixT3< T > &matrix)
Convert an Ocean SquareMatrix3 (column-major) to an OpenCV 3-by-3 matrix (row-major)
Definition: OpenCVUtilities.h:210
static SquareMatrixT3< T > toOceanSquareMatrix3Affine(const cv::Matx< T, 2, 3 > &affineTransformation)
Convert an OpenCV 2-by-3 matrix (row-major) to an Ocean SquareMatrix3 (column-major)
Definition: OpenCVUtilities.h:203
static SquareMatrixT3< T > toOceanSquareMatrix3(const cv::Matx< T, 3, 3 > &matrix)
Convert an OpenCV 3-by-3 matrix (row-major) to an Ocean SquareMatrix3 (column-wise order)
Definition: OpenCVUtilities.h:197
static bool toCvDepth(const FrameType::DataType dataType, int &cvDepth)
Converts an Ocean frame data type to a corresponding depth type in OpenCV.
Definition: OpenCVUtilities.h:222
static cv::Mat toCvMat(const Frame &frame, const bool copy=false)
Convert an Ocean Frame image to an OpenCV image.
Definition: OpenCVUtilities.h:105
static bool toOceanFrameTypeDataType(const int cvDepth, FrameType::DataType &dataType)
Converts an OpenCV depth type to a corresponding Ocean frame data type.
Definition: OpenCVUtilities.h:322
static Frame toOceanFrame(const cv::Mat &frame, const bool copy=false, const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_UNDEFINED)
Convert an OpenCV image to an Ocean Frame image object.
Definition: OpenCVUtilities.h:129
This class implements Ocean's image class.
Definition: Frame.h:1760
static bool strideBytes2paddingElements(const PixelFormat &pixelFormat, const unsigned int imageWidth, const unsigned int planeStrideBytes, unsigned int &planePaddingElements, const unsigned int planeIndex=0u)
Determines the number of padding elements at the end of a row of a plane for which the pixel format,...
unsigned int strideBytes(const unsigned int planeIndex=0u) const
Returns the number of bytes within one row, including optional padding at the end of a row for a spec...
Definition: Frame.h:4034
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4136
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4416
CopyMode
Definition of individual copy modes.
Definition: Frame.h:1767
@ CM_USE_KEEP_LAYOUT
The source memory is used only, no copy is created, the padding layout is preserved.
Definition: Frame.h:1769
@ CM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA
Makes a copy of the source memory, the padding layout is preserved, but the padding data is not copie...
Definition: Frame.h:1773
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition: Frame.h:183
@ FORMAT_BGR24
Pixel format with byte order BGR and 24 bits per pixel.
Definition: Frame.h:226
@ FORMAT_UNDEFINED
Undefined pixel format.
Definition: Frame.h:187
@ FORMAT_F32
Pixel format for a frame with one channel and 32 bit floating point precision per element.
Definition: Frame.h:992
@ FORMAT_F64
Pixel format for a frame with one channel and 64 bit floating point precision per element.
Definition: Frame.h:997
@ FORMAT_BGRA32
Pixel format with byte order BGRA and 32 bits per pixel.
Definition: Frame.h:277
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition: Frame.h:594
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3111
constexpr static PixelFormat genericPixelFormat()
Returns a specific generic pixel format with a specified data type and channel number.
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1018
DataType
Definition of individual channel data type.
Definition: Frame.h:37
@ DT_UNSIGNED_INTEGER_64
Unsigned 64 bit integer data type (uint64_t).
Definition: Frame.h:53
@ DT_UNSIGNED_INTEGER_16
Unsigned 16 bit integer data type (uint16_t).
Definition: Frame.h:45
@ DT_SIGNED_INTEGER_16
Signed 16 bit integer data type (int16_t).
Definition: Frame.h:47
@ DT_SIGNED_INTEGER_32
Signed 232 bit integer data type (int32_t).
Definition: Frame.h:51
@ DT_SIGNED_INTEGER_64
Signed 64 bit integer data type (int64_t).
Definition: Frame.h:55
@ DT_UNDEFINED
Undefined data type.
Definition: Frame.h:39
@ DT_SIGNED_FLOAT_64
Signed 64 bit float data type (double).
Definition: Frame.h:61
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition: Frame.h:41
@ DT_UNSIGNED_INTEGER_32
Unsigned 32 bit integer data type (uint32_t).
Definition: Frame.h:49
@ DT_SIGNED_FLOAT_16
Signed 16 bit float data type.
Definition: Frame.h:57
@ DT_SIGNED_FLOAT_32
Signed 32 bit float data type (float).
Definition: Frame.h:59
@ DT_SIGNED_INTEGER_8
Signed 8 bit integer data type (int8_t).
Definition: Frame.h:43
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3116
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition: Frame.h:3141
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition: Frame.h:3131
This class implements a 3x3 square matrix.
Definition: SquareMatrix3.h:88
bool isAffine() const
Returns true if this matrix is a affine transformation.
Definition: SquareMatrix3.h:1353
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15