KinectAndCameraCalibration.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package VisionX::Component
17* @author David Schiebener <schiebener at kit dot edu>
18* @copyright 2014 Humanoids Group, HIS, KIT
19* @license http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
25// VisionX
28
29// IVT
30#include <sys/time.h>
31
32#include <opencv2/opencv.hpp>
33
35
36#include "Calibration/Calibration.h"
37#include "Calibration/StereoCalibration.h"
38#include "Image/ByteImage.h"
39#include "Image/ImageProcessor.h"
40#include "Image/IplImageAdaptor.h"
41
42namespace visionx
43{
44
45 void
47 {
48 // set desired image provider
49 cameraImageProviderName =
50 getProperty<std::string>("CameraImageProviderAdapterName").getValue();
51 usingImageProvider(cameraImageProviderName);
52
53 kinectImageProviderName =
54 getProperty<std::string>("KinectImageProviderAdapterName").getValue();
55 usingImageProvider(kinectImageProviderName);
56
57 const int cornersPerRow = getProperty<int>("NumberOfRows").getValue() - 1;
58 const int cornersPerColumn = getProperty<int>("NumberOfColumns").getValue() - 1;
59 const double squareSize = getProperty<double>("PatternSquareSize").getValue();
60
61 waitingIntervalBetweenImages = getProperty<int>("WaitingIntervalBetweenImages").getValue();
62 m_sCameraParameterFileName = getProperty<std::string>("OutputFileName").getValue();
63 desiredNumberOfImages = getProperty<int>("NumberOfImages").getValue();
64 numberOfCapturedImages = 0;
65
66 // initialize calibration filter
67 m_pCalibFilter = new CvCalibFilter();
68 ARMARX_INFO << "Calibration pattern with " << cornersPerColumn + 1 << " x "
69 << cornersPerRow + 1 << " squares of size " << squareSize;
70 etalonParams[0] = double(cornersPerColumn + 1);
71 etalonParams[1] = double(cornersPerRow + 1);
72 etalonParams[2] = squareSize;
73 m_pCalibFilter->SetCameraCount(2);
74 m_pCalibFilter->SetFrames(desiredNumberOfImages);
75 m_pCalibFilter->SetEtalon(CV_CALIB_ETALON_CHESSBOARD, etalonParams);
76
77 offeringTopic("KinectAndCameraCalibration");
78 }
79
80 void
82 {
83 // connect to image provider
84 ARMARX_INFO << getName() << " connecting to " << cameraImageProviderName;
85 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(cameraImageProviderName);
86 cameraImageProviderPrx = getProxy<ImageProviderInterfacePrx>(cameraImageProviderName);
87 listenerPrx = getTopic<KinectAndCameraCalibrationListenerPrx>("KinectAndCameraCalibration");
88
89 cameraImages = new CByteImage*[2];
90 cameraImages[0] = tools::createByteImage(imageProviderInfo);
91 cameraImages[1] = tools::createByteImage(imageProviderInfo);
92
93 ARMARX_INFO << getName() << " connecting to " << kinectImageProviderName;
94 getImageProvider(kinectImageProviderName);
95 kinectImageProviderPrx = getProxy<ImageProviderInterfacePrx>(kinectImageProviderName);
96 kinectImages = new CByteImage*[kinectImageProviderPrx->getNumberImages()];
97
98 for (int i = 0; i < kinectImageProviderPrx->getNumberImages(); i++)
99 {
100 kinectImages[i] = tools::createByteImage(kinectImageProviderPrx->getImageFormat(),
101 kinectImageProviderPrx->getImageFormat().type);
102 }
103
104 startingTime = IceUtil::Time::now();
105 timeOfLastCapture = IceUtil::Time::now();
106
107 finished = false;
108 requested = false;
109 result.result = false;
110 }
111
112 void
114 {
115 finished = true;
116 requested = false;
117 result.result = false;
118
119 usleep(100000);
120 delete cameraImages[0];
121 delete cameraImages[1];
122 delete[] cameraImages;
123 delete m_pCalibFilter;
124 }
125
126 void
128 {
129 if (requested)
130 {
131 long timeSinceStart = (IceUtil::Time::now() - startingTime).toMilliSeconds();
132
133 if (timeSinceStart < 10000)
134 {
135 ARMARX_VERBOSE << "Time until start of capture: " << timeSinceStart - 10000
136 << " ms";
137 usleep(100000);
138 }
139 else if (!finished)
140 {
141 // get images
142 armarx::MetaInfoSizeBasePtr info;
143 int nNumberCameraImages = getImages(cameraImageProviderName, cameraImages, info);
144 ARMARX_VERBOSE << getName() << " got " << nNumberCameraImages << " camera images";
145
146 armarx::MetaInfoSizeBasePtr info2;
147 int nNumberKinectImages = getImages(kinectImageProviderName, kinectImages, info2);
148 ARMARX_VERBOSE << getName() << " got " << nNumberKinectImages << " kinect images";
149
150 if (nNumberCameraImages > 0 && nNumberKinectImages > 0)
151 {
152 if ((IceUtil::Time::now() - timeOfLastCapture).toMilliSeconds() >
153 waitingIntervalBetweenImages)
154 {
155 ARMARX_INFO << "Capturing image " << numberOfCapturedImages + 1 << " of "
156 << desiredNumberOfImages;
157 IplImage* ppIplImages[2] = {IplImageAdaptor::Adapt(cameraImages[0]),
158 IplImageAdaptor::Adapt(kinectImages[0])};
159
160 if (m_pCalibFilter->FindEtalon(ppIplImages))
161 {
162 ARMARX_INFO << "Found calibration pattern";
163 numberOfCapturedImages++;
164 timeOfLastCapture = IceUtil::Time::now();
165 m_pCalibFilter->DrawPoints(ppIplImages);
166 m_pCalibFilter->Push();
167
168 if (numberOfCapturedImages == desiredNumberOfImages)
169 {
170 ARMARX_IMPORTANT << "Calculating calibration";
171 usleep(10000);
172
173 if (m_pCalibFilter->IsCalibrated())
174 {
175 ARMARX_INFO << "Saving camera calibration to file "
176 << m_sCameraParameterFileName;
177 m_pCalibFilter->SaveCameraParams(
178 m_sCameraParameterFileName.c_str());
179 CStereoCalibration calibration;
180 calibration.LoadCameraParameters(
181 m_sCameraParameterFileName.c_str());
182 CCalibration cRight = *calibration.GetRightCalibration();
183 Vec3d translation = cRight.GetCameraParameters().translation;
184 ARMARX_INFO << "RightCalibration traslation; " << translation.x
185 << " " << translation.y << " " << translation.z;
186 Mat3d rotation = cRight.GetCameraParameters().rotation;
187 ARMARX_INFO << "RightCalibration rotation; " << rotation.r1
188 << " " << rotation.r2 << " " << rotation.r3 << " \n"
189 << rotation.r4 << " " << rotation.r5 << " "
190 << rotation.r6 << " \n"
191 << rotation.r7 << " " << rotation.r8 << " "
192 << rotation.r9 << " \n";
193
194
195 CCalibration cLeft = *calibration.GetLeftCalibration();
196 Vec3d translationLeft = cLeft.GetCameraParameters().translation;
197 ARMARX_INFO << "LeftCalibration traslation; "
198 << translationLeft.x << " " << translationLeft.y
199 << " " << translationLeft.z;
200 Mat3d rotationLeft = cLeft.GetCameraParameters().rotation;
201 ARMARX_INFO << "LeftCalibration rotation; " << rotationLeft.r1
202 << " " << rotationLeft.r2 << " " << rotationLeft.r3
203 << " \n"
204 << rotationLeft.r4 << " " << rotationLeft.r5 << " "
205 << rotationLeft.r6 << " \n"
206 << rotationLeft.r7 << " " << rotationLeft.r8 << " "
207 << rotationLeft.r9 << " \n";
208
209 finished = true;
210 result.result = finished;
211 result.transformation =
213 tools::convertIVTtoEigen(translation));
214
215 listenerPrx->reportCalibrationFinished(result.result);
216 ARMARX_IMPORTANT << "Calibration finished";
217 }
218 }
219 }
220 }
221 else
222 {
223 usleep(10000);
224 }
225 }
226 else
227 {
228 usleep(100000);
229 }
230 }
231 }
232 else
233 {
234 usleep(100000);
235 startingTime = IceUtil::Time::now();
236 }
237 }
238
239 void
241 {
242 requested = true;
243 startingTime = IceUtil::Time::now();
244 }
245
246 void
248 {
249 requested = false;
250 usleep(10000);
251
252 numberOfCapturedImages = 0;
253 delete m_pCalibFilter;
254 m_pCalibFilter = new CvCalibFilter();
255 m_pCalibFilter->SetCameraCount(2);
256 m_pCalibFilter->SetFrames(desiredNumberOfImages);
257 m_pCalibFilter->SetEtalon(CV_CALIB_ETALON_CHESSBOARD, etalonParams);
258
259 finished = false;
260 result.result = false;
261
262 startingTime = IceUtil::Time::now();
263 }
264
265 KinectPoseCalibration
267 {
268 return result;
269 }
270} // namespace visionx
constexpr T c
@ CV_CALIB_ETALON_CHESSBOARD
Definition calibfilter.h:71
Property< PropertyType > getProperty(const std::string &name)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
The Pose class.
Definition Pose.h:243
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
int getImages(CByteImage **ppImages)
Poll images from provider.
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
void onExitImageProcessor() override
Exit the ImapeProcessor component.
void process() override
Process the vision component.
void startCalibration(const ::Ice::Current &c=Ice::emptyCurrent) override
ice related functions (todo: put comments)
void stopCalibration(const ::Ice::Current &c=Ice::emptyCurrent) override
void onInitImageProcessor() override
Setup the vision component.
visionx::KinectPoseCalibration getCalibrationParameters(const ::Ice::Current &c=Ice::emptyCurrent) override
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
Eigen::Matrix3f convertIVTtoEigen(const Mat3d &m)
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
ArmarX headers.