OpenCVUtil.cpp
Go to the documentation of this file.
1 #include "OpenCVUtil.h"
2 
3 #include <cstring>
4 
5 #include <Image/ByteImage.h>
6 
8 
9 #include <VisionX/interface/components/Calibration.h>
10 
11 
12 
13  void visionx::copyCvMatToIVT(cv::Mat const& input, CByteImage* output)
14  {
16  ARMARX_CHECK_NOT_NULL(output);
17  ARMARX_CHECK_EXPRESSION(input.isContinuous());
18  ARMARX_CHECK_EQUAL(int(input.elemSize()), output->bytesPerPixel);
19 
20  int imageSize = output->width * output->height * output->bytesPerPixel;
21  ARMARX_CHECK_EQUAL(int(input.total() * input.elemSize()), imageSize);
22 
23  std::memcpy(output->pixels, input.data, imageSize);
24  }
25 
26  void 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 
62  {
64  ARMARX_CHECK_EQUAL(input->type, CByteImage::eRGB24);
65 
66  int width = input->width;
67  int height = input->height;
68  cv::Mat result(height, width, CV_32FC1);
69 
71 
72  return result;
73  }
74 
75 
76  void visionx::convertWeirdArmarXToDepthInMeters(const uint8_t* input, cv::Mat& output)
77  {
78  ARMARX_CHECK_EQUAL(output.type(), CV_32FC1);
79 
80  const unsigned char* inputRow = input;
81  for (int row = 0; row < output.rows; ++row)
82  {
83  float* outputRow = output.ptr<float>(row);
84  for (int col = 0; col < output.cols; ++col)
85  {
86  // Depth is stored in mm (lower 8 bits in r, higher 8 bits g)
87  int r = inputRow[col * 3 + 0];
88  int g = inputRow[col * 3 + 1];
89  int depthInMM = (g << 8) + r;
90  outputRow[col] = static_cast<float>(depthInMM) / 1000.0f;
91  }
92 
93  inputRow += output.cols * 3;
94  }
95  }
96 
97 
98  void visionx::convertDepthInMetersToWeirdArmarX(const cv::Mat& input, CByteImage* output)
99  {
100  ARMARX_CHECK_NOT_NULL(output);
101  ARMARX_CHECK_EQUAL(output->type, CByteImage::eRGB24);
102  ARMARX_CHECK_EQUAL(output->width, input.cols);
103  ARMARX_CHECK_EQUAL(output->height, input.rows);
104  ARMARX_CHECK_EQUAL(CV_32FC1, input.type());
105 
106  const auto height = output->height;
107  const auto width = output->width;
108 
109  unsigned char* outputRow = output->pixels;
110  for (int y = 0; y < height; ++y)
111  {
112  const float* inputRow = input.ptr<float>(y);
113  for (int x = 0; x < width; ++x)
114  {
115  const auto depthInMM = inputRow[x] * 1000;
116  // Depth is stored in mm (lower 8 bits in r, higher 8 bits g)
117  outputRow[x * 3 + 0] = static_cast<unsigned char>(std::fmod(depthInMM, 256));
118  outputRow[x * 3 + 1] = static_cast<unsigned char>(std::fmod(depthInMM / 256, 256));
119  outputRow[x * 3 + 2] = static_cast<unsigned char>(std::fmod(depthInMM / 256 / 256, 256));
120  }
121 
122  inputRow += width * 3;
123  }
124  }
125 
126 
127 namespace detail
128 {
129  template <typename Float>
130  void fillEmptyValues(cv::Mat& output)
131  {
132  output.at<Float>(0, 1) = 0;
133  output.at<Float>(1, 0) = 0;
134  output.at<Float>(2, 0) = 0;
135  output.at<Float>(2, 1) = 0;
136  output.at<Float>(2, 2) = 1;
137  }
138 
139  void checkFloatMatrix(const cv::Mat& matrix, const std::string& semanticName)
140  {
141  if (!(matrix.depth() == CV_32F || matrix.depth() == CV_64F))
142  {
143  std::stringstream ss;
144  ss << "Passed " << semanticName << " must be floating point type, "
145  << "i.e. CV_32F (" << CV_32F << ") or CV_64F (" << CV_64F << "), "
146  << "but its type was " << matrix.type() << ".";
147  throw std::invalid_argument(ss.str());
148  }
149  }
150 
151  void checkCameraMatrix(const cv::Mat& matrix)
152  {
153  checkFloatMatrix(matrix, "camera matrix");
154  ARMARX_CHECK_GREATER_EQUAL(matrix.rows, 3);
155  ARMARX_CHECK_GREATER_EQUAL(matrix.cols, 3);
156  }
157 
158  template <typename Float>
159  void fillCameraMatrix(const CCalibration::CCameraParameters& ivtCameraParameters, cv::Mat& output)
160  {
161  checkCameraMatrix(output);
162 
163  fillEmptyValues<Float>(output);
164 
165  output.at<Float>(0, 0) = Float(ivtCameraParameters.focalLength.x);
166  output.at<Float>(0, 2) = Float(ivtCameraParameters.principalPoint.x);
167  output.at<Float>(1, 1) = Float(ivtCameraParameters.focalLength.y);
168  output.at<Float>(1, 2) = Float(ivtCameraParameters.principalPoint.y);
169  }
170 
171  template <typename Float>
172  void fillCameraMatrix(const visionx::CameraParameters& cameraParams, cv::Mat& output)
173  {
174  checkCameraMatrix(output);
175 
176  ARMARX_CHECK_EQUAL(cameraParams.focalLength.size(), 2);
177  ARMARX_CHECK_EQUAL(cameraParams.principalPoint.size(), 2);
178 
179  const float nodalPointX = cameraParams.principalPoint.at(0);
180  const float nodalPointY = cameraParams.principalPoint.at(1);
181  const float focalLengthX = cameraParams.focalLength.at(0);
182  const float focalLengthY = cameraParams.focalLength.at(1);
183 
184  fillEmptyValues<Float>(output);
185 
186  output.at<Float>(0, 0) = Float(focalLengthX);
187  output.at<Float>(0, 2) = Float(nodalPointX);
188  output.at<Float>(1, 1) = Float(focalLengthY);
189  output.at<Float>(1, 2) = Float(nodalPointY);
190  }
191 
192 }
193 
194 
195 void visionx::fillCameraMatrix(const visionx::CameraParameters& cameraParams, cv::Mat& output)
196 {
198  if (output.depth() == CV_32F)
199  {
200  detail::fillCameraMatrix<float>(cameraParams, output);
201  }
202  else if (output.depth() == CV_64F)
203  {
204  detail::fillCameraMatrix<double>(cameraParams, output);
205  }
206 }
207 
208 
210  const CCalibration::CCameraParameters& ivtCameraParameters, cv::Mat& output)
211 {
213  if (output.depth() == CV_32F)
214  {
215  detail::fillCameraMatrix<float>(ivtCameraParameters, output);
216  }
217  else if (output.depth() == CV_64F)
218  {
219  detail::fillCameraMatrix<double>(ivtCameraParameters, output);
220  }
221 }
222 
223 
detail::checkCameraMatrix
void checkCameraMatrix(const cv::Mat &matrix)
Definition: OpenCVUtil.cpp:151
visionx::convertDepthInMetersToWeirdArmarX
void convertDepthInMetersToWeirdArmarX(const cv::Mat &input, CByteImage *output)
Definition: OpenCVUtil.cpp:98
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
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:61
detail
Definition: OpenCVUtil.cpp:127
detail::fillEmptyValues
void fillEmptyValues(cv::Mat &output)
Definition: OpenCVUtil.cpp:130
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
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:13
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:139
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:159
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:195