OpenCVUtil.cpp
Go to the documentation of this file.
1 #include "OpenCVUtil.h"
2 
3 #include <cstring>
4 
6 
7 #include <VisionX/interface/components/Calibration.h>
8 
9 #include <Image/ByteImage.h>
10 
11 void
12 visionx::copyCvMatToIVT(cv::Mat const& input, CByteImage* output)
13 {
15  ARMARX_CHECK_NOT_NULL(output);
16  ARMARX_CHECK_EXPRESSION(input.isContinuous());
17  ARMARX_CHECK_EQUAL(int(input.elemSize()), output->bytesPerPixel);
18 
19  int imageSize = output->width * output->height * output->bytesPerPixel;
20  ARMARX_CHECK_EQUAL(int(input.total() * input.elemSize()), imageSize);
21 
22  std::memcpy(output->pixels, input.data, imageSize);
23 }
24 
25 void
26 visionx::copyCvDepthToGrayscaleIVT(cv::Mat const& inputInMeters, CByteImage* output)
27 {
28  ARMARX_CHECK_NOT_NULL(inputInMeters.data);
29  ARMARX_CHECK_NOT_NULL(output);
30  ARMARX_CHECK_EQUAL(inputInMeters.type(), CV_32FC1);
31  ARMARX_CHECK_EQUAL(output->type, CByteImage::eRGB24);
32  ARMARX_CHECK_EQUAL(inputInMeters.rows, output->height);
33  ARMARX_CHECK_EQUAL(inputInMeters.cols, output->width);
34 
35  uchar* outRow = output->pixels;
36  int outStride = 3 * output->width;
37 
38  double minD, maxD;
39  cv::minMaxLoc(inputInMeters, &minD, &maxD);
40 
41  float invRangeD = 1.0 / (maxD - minD);
42 
43  for (int y = 0; y < inputInMeters.rows; ++y)
44  {
45  float const* depthRow = inputInMeters.ptr<float>(y);
46  for (int x = 0; x < inputInMeters.cols; ++x)
47  {
48  float depth = depthRow[x];
49  float normalizedDepth = (depth - minD) * invRangeD;
50  int pixelValue = std::floor(255.0f - 255.0f * normalizedDepth);
51 
52  outRow[3 * x + 0] = pixelValue;
53  outRow[3 * x + 1] = pixelValue;
54  outRow[3 * x + 2] = pixelValue;
55  }
56 
57  outRow += outStride;
58  }
59 }
60 
61 cv::Mat
63 {
65  ARMARX_CHECK_EQUAL(input->type, CByteImage::eRGB24);
66 
67  int width = input->width;
68  int height = input->height;
69  cv::Mat result(height, width, CV_32FC1);
70 
72 
73  return result;
74 }
75 
76 void
77 visionx::convertWeirdArmarXToDepthInMeters(const uint8_t* input, cv::Mat& output)
78 {
79  ARMARX_CHECK_EQUAL(output.type(), CV_32FC1);
80 
81  const unsigned char* inputRow = input;
82  for (int row = 0; row < output.rows; ++row)
83  {
84  float* outputRow = output.ptr<float>(row);
85  for (int col = 0; col < output.cols; ++col)
86  {
87  // Depth is stored in mm (lower 8 bits in r, higher 8 bits g)
88  int r = inputRow[col * 3 + 0];
89  int g = inputRow[col * 3 + 1];
90  int depthInMM = (g << 8) + r;
91  outputRow[col] = static_cast<float>(depthInMM) / 1000.0f;
92  }
93 
94  inputRow += output.cols * 3;
95  }
96 }
97 
98 void
99 visionx::convertDepthInMetersToWeirdArmarX(const cv::Mat& input, CByteImage* output)
100 {
101  ARMARX_CHECK_NOT_NULL(output);
102  ARMARX_CHECK_EQUAL(output->type, CByteImage::eRGB24);
103  ARMARX_CHECK_EQUAL(output->width, input.cols);
104  ARMARX_CHECK_EQUAL(output->height, input.rows);
105  ARMARX_CHECK_EQUAL(CV_32FC1, input.type());
106 
107  const auto height = output->height;
108  const auto width = output->width;
109 
110  unsigned char* outputRow = output->pixels;
111  for (int y = 0; y < height; ++y)
112  {
113  const float* inputRow = input.ptr<float>(y);
114  for (int x = 0; x < width; ++x)
115  {
116  const auto depthInMM = inputRow[x] * 1000;
117  // Depth is stored in mm (lower 8 bits in r, higher 8 bits g)
118  outputRow[x * 3 + 0] = static_cast<unsigned char>(std::fmod(depthInMM, 256));
119  outputRow[x * 3 + 1] = static_cast<unsigned char>(std::fmod(depthInMM / 256, 256));
120  outputRow[x * 3 + 2] =
121  static_cast<unsigned char>(std::fmod(depthInMM / 256 / 256, 256));
122  }
123 
124  inputRow += width * 3;
125  }
126 }
127 
128 namespace detail
129 {
130  template <typename Float>
131  void
132  fillEmptyValues(cv::Mat& output)
133  {
134  output.at<Float>(0, 1) = 0;
135  output.at<Float>(1, 0) = 0;
136  output.at<Float>(2, 0) = 0;
137  output.at<Float>(2, 1) = 0;
138  output.at<Float>(2, 2) = 1;
139  }
140 
141  void
142  checkFloatMatrix(const cv::Mat& matrix, const std::string& semanticName)
143  {
144  if (!(matrix.depth() == CV_32F || matrix.depth() == CV_64F))
145  {
146  std::stringstream ss;
147  ss << "Passed " << semanticName << " must be floating point type, "
148  << "i.e. CV_32F (" << CV_32F << ") or CV_64F (" << CV_64F << "), "
149  << "but its type was " << matrix.type() << ".";
150  throw std::invalid_argument(ss.str());
151  }
152  }
153 
154  void
155  checkCameraMatrix(const cv::Mat& matrix)
156  {
157  checkFloatMatrix(matrix, "camera matrix");
158  ARMARX_CHECK_GREATER_EQUAL(matrix.rows, 3);
159  ARMARX_CHECK_GREATER_EQUAL(matrix.cols, 3);
160  }
161 
162  template <typename Float>
163  void
164  fillCameraMatrix(const CCalibration::CCameraParameters& ivtCameraParameters, cv::Mat& output)
165  {
166  checkCameraMatrix(output);
167 
168  fillEmptyValues<Float>(output);
169 
170  output.at<Float>(0, 0) = Float(ivtCameraParameters.focalLength.x);
171  output.at<Float>(0, 2) = Float(ivtCameraParameters.principalPoint.x);
172  output.at<Float>(1, 1) = Float(ivtCameraParameters.focalLength.y);
173  output.at<Float>(1, 2) = Float(ivtCameraParameters.principalPoint.y);
174  }
175 
176  template <typename Float>
177  void
178  fillCameraMatrix(const visionx::CameraParameters& cameraParams, cv::Mat& output)
179  {
180  checkCameraMatrix(output);
181 
182  ARMARX_CHECK_EQUAL(cameraParams.focalLength.size(), 2);
183  ARMARX_CHECK_EQUAL(cameraParams.principalPoint.size(), 2);
184 
185  const float nodalPointX = cameraParams.principalPoint.at(0);
186  const float nodalPointY = cameraParams.principalPoint.at(1);
187  const float focalLengthX = cameraParams.focalLength.at(0);
188  const float focalLengthY = cameraParams.focalLength.at(1);
189 
190  fillEmptyValues<Float>(output);
191 
192  output.at<Float>(0, 0) = Float(focalLengthX);
193  output.at<Float>(0, 2) = Float(nodalPointX);
194  output.at<Float>(1, 1) = Float(focalLengthY);
195  output.at<Float>(1, 2) = Float(nodalPointY);
196  }
197 
198 } // namespace detail
199 
200 void
201 visionx::fillCameraMatrix(const visionx::CameraParameters& cameraParams, cv::Mat& output)
202 {
204  if (output.depth() == CV_32F)
205  {
206  detail::fillCameraMatrix<float>(cameraParams, output);
207  }
208  else if (output.depth() == CV_64F)
209  {
210  detail::fillCameraMatrix<double>(cameraParams, output);
211  }
212 }
213 
214 void
215 visionx::fillCameraMatrix(const CCalibration::CCameraParameters& ivtCameraParameters,
216  cv::Mat& output)
217 {
219  if (output.depth() == CV_32F)
220  {
221  detail::fillCameraMatrix<float>(ivtCameraParameters, output);
222  }
223  else if (output.depth() == CV_64F)
224  {
225  detail::fillCameraMatrix<double>(ivtCameraParameters, output);
226  }
227 }
detail::checkCameraMatrix
void checkCameraMatrix(const cv::Mat &matrix)
Definition: OpenCVUtil.cpp:155
visionx::convertDepthInMetersToWeirdArmarX
void convertDepthInMetersToWeirdArmarX(const cv::Mat &input, CByteImage *output)
Definition: OpenCVUtil.cpp:99
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
visionx::convertWeirdArmarXToDepthInMeters
cv::Mat convertWeirdArmarXToDepthInMeters(CByteImage const *input)
Convert ArmarX encoding of depth information in an RGB image to depth in meters.
Definition: OpenCVUtil.cpp:62
detail
Definition: OpenCVUtil.cpp:128
detail::fillEmptyValues
void fillEmptyValues(cv::Mat &output)
Definition: OpenCVUtil.cpp:132
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
visionx::copyCvDepthToGrayscaleIVT
void copyCvDepthToGrayscaleIVT(cv::Mat const &inputInMeters, CByteImage *output)
Copies a floating point depth image (in meters) to an RGB depth representation.
Definition: OpenCVUtil.cpp:26
ARMARX_CHECK_GREATER_EQUAL
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
Definition: ExpressionException.h:123
ExpressionException.h
visionx::copyCvMatToIVT
void copyCvMatToIVT(cv::Mat const &input, CByteImage *output)
Copies the contents of an OpenCV matrix to an IVT CByteImage.
Definition: OpenCVUtil.cpp:12
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
detail::checkFloatMatrix
void checkFloatMatrix(const cv::Mat &matrix, const std::string &semanticName)
Definition: OpenCVUtil.cpp:142
OpenCVUtil.h
detail::fillCameraMatrix
void fillCameraMatrix(const CCalibration::CCameraParameters &ivtCameraParameters, cv::Mat &output)
Fill a propertly initialized camera matrix with the given camera parameters.
Definition: OpenCVUtil.cpp:164
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
visionx::fillCameraMatrix
void fillCameraMatrix(const visionx::CameraParameters &cameraParams, cv::Mat &output)
Fill a propertly initialized camera matrix with the given camera parameters.
Definition: OpenCVUtil.cpp:201