PlaneProjectionCImg.cpp
Go to the documentation of this file.
1 // (C) Copyright Renaud Detry 2007-2015.
2 // Distributed under the GNU General Public License and under the
3 // BSD 3-Clause License (See accompanying file LICENSE.txt).
4 
5 /** @file */
6 
7 #ifdef NUKLEI_USE_OPENCV_LEGACY
8 #include "cvaux.h"
9 #endif
10 
11 #ifdef NUKLEI_USE_CIMG
12 #include "CImg.h"
13 #endif
14 
15 #include <nuklei/PlaneProjection.h>
16 
17 
18 namespace nuklei
19 {
20  PlaneProjection::PlaneProjection(const std::string& opencvStereoCalibFile,
21  unsigned camNum) :
22  rotationMatrixData_(9), translationVectorData_(3),
23  intrinsicMatrixData_(9), distortionCoeffsData_(4),
24  opacity_(1)
25  {
26  color_[0] = color_[1] = color_[2] = 0;
27  readParameters(opencvStereoCalibFile, camNum);
28  }
29 
30  PlaneProjection::PlaneProjection(const PlaneProjection& pp)
31  {
32  rotationMatrixData_ = pp.rotationMatrixData_;
33  translationVectorData_ = pp.translationVectorData_;
34  intrinsicMatrixData_ = pp.intrinsicMatrixData_;
35  distortionCoeffsData_ = pp.distortionCoeffsData_;
36  for (int i = 0; i < 3; ++i) color_[i] = pp.color_[i];
37  opacity_ = pp.opacity_;
38 #ifdef NUKLEI_USE_CIMG
39  if (pp.image_.get() != NULL)
40  {
41  image_.reset(new image_t(pp.getImage()));
42  }
43 #else
44  NUKLEI_THROW("This function requires CIMG.");
45 #endif
46  }
47 
48  PlaneProjection& PlaneProjection::operator=(const PlaneProjection& pp)
49  {
50  NUKLEI_TRACE_BEGIN();
51  if (&pp == this) return *this;
52  rotationMatrixData_ = pp.rotationMatrixData_;
53  translationVectorData_ = pp.translationVectorData_;
54  intrinsicMatrixData_ = pp.intrinsicMatrixData_;
55  distortionCoeffsData_ = pp.distortionCoeffsData_;
56  for (int i = 0; i < 3; ++i) color_[i] = pp.color_[i];
57  opacity_ = pp.opacity_;
58 #ifdef NUKLEI_USE_CIMG
59  if (pp.image_.get() != NULL)
60  {
61  image_.reset(new image_t(pp.getImage()));
62  }
63 #else
64  NUKLEI_THROW("This function requires CIMG.");
65 #endif
66  return *this;
67  NUKLEI_TRACE_END();
68  }
69 
70  // Force the destructor to be defined after CImg has been defined:
71  PlaneProjection::~PlaneProjection() {}
72 
73  void PlaneProjection::readParameters(const std::string& opencvStereoCalibFile,
74  unsigned camNum)
75  {
76  NUKLEI_TRACE_BEGIN();
77 
78 #ifdef NUKLEI_USE_OPENCV_LEGACY
79  CvCalibFilter calibFilter;
80  NUKLEI_ASSERT(calibFilter.LoadCameraParams(opencvStereoCalibFile.c_str()));
81  const CvCamera* camera = calibFilter.GetCameraParams(camNum);
82 
83  for (int i = 0; i < 9; ++i) rotationMatrixData_.at(i) = camera->rotMatr[i];
84  for (int i = 0; i < 3; ++i) translationVectorData_.at(i) = camera->transVect[i];
85  for (int i = 0; i < 9; ++i) intrinsicMatrixData_.at(i) = camera->matrix[i];
86  for (int i = 0; i < 4; ++i) distortionCoeffsData_.at(i) = camera->distortion[i];
87 #else
88  NUKLEI_THROW("This function requires lecagy OpenCV code. It will require some work to bring it back to life.");
89 #endif
90 
91  NUKLEI_TRACE_END();
92  }
93 
94  std::vector<Vector2>
95  PlaneProjection::project(const std::vector<Vector3> worldPoints) const
96  {
97  NUKLEI_TRACE_BEGIN();
98 
99 #ifdef NUKLEI_USE_CIMG
100 
101  // cvProjectPoints2 projects p points to the image plane.
102  // cvProjectPoints2 assumes that p > 3 :-(.
103  const unsigned p = worldPoints.size();
104  const unsigned large_p = std::max(p, 4u);
105  std::vector<double> objectPointsData(3*large_p, 0);
106  std::vector<double> imagePointsData(2*large_p, 0);
107 
108  for (unsigned pc = 0; pc < p; ++pc)
109  for (unsigned i = 0; i < 3; ++i)
110  objectPointsData.at(3*pc+i) = worldPoints.at(pc)[i];
111 
112 #ifdef NUKLEI_USE_OPENCV_LEGACY
113  CvMat object_points = cvMat(large_p, 3, CV_64FC1, &objectPointsData.front());
114  CvMat rotation_vector = cvMat(3, 3, CV_64FC1, const_cast<double*>(&rotationMatrixData_.front()));
115  CvMat translation_vector = cvMat(1, 3, CV_64FC1, const_cast<double*>(&translationVectorData_.front()));
116  CvMat intrinsic_matrix = cvMat(3, 3, CV_64FC1, const_cast<double*>(&intrinsicMatrixData_.front()));
117  CvMat distortion_coeffs = cvMat(1, 4, CV_64FC1, const_cast<double*>(&distortionCoeffsData_.front()));
118  CvMat image_points = cvMat(large_p, 2, CV_64FC1, &imagePointsData.front());
119 
120  cvProjectPoints2(&object_points,
121  &rotation_vector,
122  &translation_vector,
123  &intrinsic_matrix,
124  &distortion_coeffs,
125  &image_points);
126 #else
127  NUKLEI_THROW("This function requires lecagy OpenCV code. It will require some work to bring it back to life.");
128 #endif
129 
130  std::vector<Vector2> imagePoints(p);
131  for (unsigned pc = 0; pc < p; ++pc)
132  for (unsigned i = 0; i < 2; ++i)
133  imagePoints.at(pc)[i] = imagePointsData.at(2*pc+i);
134 
135  if (image_.get() != NULL)
136  {
137  try {
138  for (std::vector<Vector2>::iterator i = imagePoints.begin();
139  i != imagePoints.end(); ++i) {
140  image_->draw_circle(i->X(), i->Y(), IMAGE_PROJECTION_RADIUS,
141  color_, opacity_);
142  unsigned char black[] = { 0,0,0 };
143  image_->draw_circle(i->X(), i->Y(), IMAGE_PROJECTION_RADIUS,
144  black, 1, static_cast<unsigned int>(0));
145  }
146  } catch (cimg_library::CImgException &e) {
147  NUKLEI_THROW("CImg error: " << e.what());
148  }
149  }
150 
151  return imagePoints;
152 
153 #else
154  NUKLEI_THROW("This function requires CIMG.");
155 #endif
156 
157  NUKLEI_TRACE_END();
158  }
159 
160  Vector2 PlaneProjection::project(const Vector3& p) const
161  {
162  NUKLEI_TRACE_BEGIN();
163  std::vector<Vector3> worldPoints;
164  worldPoints.push_back(p);
165  std::vector<Vector2> imagePoints = project(worldPoints);
166  NUKLEI_ASSERT(imagePoints.size() == 1);
167  return imagePoints.front();
168  NUKLEI_TRACE_END();
169  }
170 
171  void PlaneProjection::readImage(const std::string& name)
172  {
173  NUKLEI_TRACE_BEGIN();
174 #ifdef NUKLEI_USE_CIMG
175  try {
176  image_ = NUKLEI_UNIQUE_PTR<image_t>(new image_t(name.c_str()));
177  } catch (cimg_library::CImgException &e) {
178  NUKLEI_THROW("CImg error: " << e.what());
179  }
180 #else
181  NUKLEI_THROW("This function requires CIMG.");
182 #endif
183  NUKLEI_TRACE_END();
184  }
185 
186  void PlaneProjection::writeImage(const std::string& name) const
187  {
188  NUKLEI_TRACE_BEGIN();
189 #ifdef NUKLEI_USE_CIMG
190  NUKLEI_ASSERT(image_.get() != NULL);
191  try {
192  image_->save(name.c_str());
193  } catch (cimg_library::CImgException &e) {
194  NUKLEI_THROW("CImg error: " << e.what());
195  }
196 #else
197  NUKLEI_THROW("This function requires CIMG.");
198 #endif
199  NUKLEI_TRACE_END();
200  }
201 
202  void StereoPlaneProjection::writeStereoImage(const std::string& name) const
203  {
204  NUKLEI_TRACE_BEGIN();
205 #ifdef NUKLEI_USE_CIMG
206  try {
207  image_t image = (left_.getImage().get_append(right_.getImage(), 'x'));
208  image.save(name.c_str());
209  } catch (cimg_library::CImgException &e) {
210  NUKLEI_THROW("CImg error: " << e.what());
211  }
212 #else
213  NUKLEI_THROW("This function requires CIMG.");
214 #endif
215  NUKLEI_TRACE_END();
216  }
217 
218 
219 }
Public namespace.
Definition: Color.cpp:9
#define NUKLEI_ASSERT(expression)
Throws an Error if expression is not true.
Definition: Common.h:113
Vector3 project(const Vector3 &x, const Matrix3 &X, const Vector3 &z)
Returns .
#define NUKLEI_THROW(x)
Throws an Error.
Definition: Common.h:94
© Copyright 2007-2013 Renaud Detry.
Distributed under the terms of the GNU General Public License (GPL).
(See accompanying file LICENSE.txt or copy at http://www.gnu.org/copyleft/gpl.html.)
Revised Sun Sep 13 2020 19:10:06.