CalibrationCreator.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
23#include "CalibrationCreator.h"
24
25// VisionX
26//#include <VisionX/tools/TypeMapping.h>
28
29// IVT
30#include <sys/time.h>
31
32#include <opencv2/opencv.hpp>
33
34#include "Image/ByteImage.h"
35#include "Image/ImageProcessor.h"
36#include "Image/IplImageAdaptor.h"
37
38namespace visionx
39{
40
41 void
43 {
44 // set desired image provider
45 providerName = getProperty<std::string>("ImageProviderAdapterName").getValue();
46 usingImageProvider(providerName);
47
48 const int cornersPerRow = getProperty<int>("NumberOfRows").getValue() - 1;
49 const int cornersPerColumn = getProperty<int>("NumberOfColumns").getValue() - 1;
50 const int cornersPerImage = cornersPerColumn * cornersPerRow;
51 const double squareSize = getProperty<double>("PatternSquareSize").getValue();
52
53 m_pCorners2DFloat = new CvPoint2D32f[cornersPerImage];
54 m_pCorners2D = new CvPoint2D64f[cornersPerImage];
55 m_pCorners3D = new CvPoint3D64f[cornersPerImage];
56
57 waitingIntervalBetweenImages = getProperty<int>("WaitingIntervalBetweenImages").getValue();
58 m_sCameraParameterFileName = getProperty<std::string>("OutputFileName").getValue();
59 desiredNumberOfImages = getProperty<int>("NumberOfImages").getValue();
60 numberOfCapturedImages = 0;
61
62 // initialize calibration filter
63 m_pCalibFilter = new CvCalibFilter();
64 ARMARX_INFO << "Calibration pattern with " << cornersPerColumn + 1 << " x "
65 << cornersPerRow + 1 << " squares of size " << squareSize;
66 double etalonParams[3] = {
67 double(cornersPerColumn + 1), double(cornersPerRow + 1), squareSize};
68 m_pCalibFilter->SetCameraCount(2);
69 m_pCalibFilter->SetFrames(desiredNumberOfImages);
70 m_pCalibFilter->SetEtalon(CV_CALIB_ETALON_CHESSBOARD, etalonParams);
71 }
72
73 void
75 {
76 // connect to image provider
77 ARMARX_INFO << getName() << " connecting to " << providerName;
78 visionx::ImageProviderInfo imageProviderInfo = getImageProvider(providerName);
79 imageProviderPrx = getProxy<ImageProviderInterfacePrx>(providerName);
80
81 cameraImages = new CByteImage*[2];
82 cameraImages[0] = tools::createByteImage(imageProviderInfo);
83 cameraImages[1] = tools::createByteImage(imageProviderInfo);
84
85 startingTime = IceUtil::Time::now();
86 timeOfLastCapture = IceUtil::Time::now();
87 finished = false;
88
89
91 2, imageProviderInfo.imageFormat.dimension, imageProviderInfo.imageFormat.type);
92 }
93
94 void
96 {
97 finished = true;
98 usleep(100000);
99 delete cameraImages[0];
100 delete cameraImages[1];
101 delete[] cameraImages;
102 delete m_pCalibFilter;
103 delete[] m_pCorners3D;
104 delete[] m_pCorners2D;
105 delete[] m_pCorners2DFloat;
106 }
107
108 void
110 {
111 long timeSinceStart = (IceUtil::Time::now() - startingTime).toMilliSeconds();
112
113 if (timeSinceStart < 10000)
114 {
115 ARMARX_VERBOSE << "Time until start of capture: " << timeSinceStart - 10000 << " ms";
116 usleep(100000);
117 }
118 else if (!finished)
119 {
120 if (!waitForImages(8000))
121 {
122 ARMARX_WARNING << "Timeout or error in wait for images";
123 }
124 else
125 {
126 // get images
127 int nNumberImages = getImages(cameraImages);
128 ARMARX_VERBOSE << getName() << " got " << nNumberImages << " images";
129
130 if ((IceUtil::Time::now() - timeOfLastCapture).toMilliSeconds() >
131 waitingIntervalBetweenImages)
132 {
133 ARMARX_INFO << "Capturing image " << numberOfCapturedImages + 1 << " of "
134 << desiredNumberOfImages;
135 IplImage* ppIplImages[2] = {IplImageAdaptor::Adapt(cameraImages[0]),
136 IplImageAdaptor::Adapt(cameraImages[1])};
137
138 if (m_pCalibFilter->FindEtalon(ppIplImages))
139 {
140 ARMARX_INFO << "Found calibration pattern";
141 numberOfCapturedImages++;
142 m_pCalibFilter->DrawPoints(ppIplImages);
143 m_pCalibFilter->Push();
144 timeOfLastCapture = IceUtil::Time::now();
145
146 if (numberOfCapturedImages == desiredNumberOfImages)
147 {
148 ARMARX_IMPORTANT << "Calculating calibration";
149
150 if (m_pCalibFilter->IsCalibrated())
151 {
152 ARMARX_INFO << "Saving camera calibration to file "
153 << m_sCameraParameterFileName;
154 m_pCalibFilter->SaveCameraParams(
155 m_sCameraParameterFileName.c_str());
156 finished = true;
157 ARMARX_IMPORTANT << "Calibration finished";
158 }
159 }
160 }
161 provideResultImages(cameraImages);
162 }
163 else
164 {
165 usleep(10000);
166 }
167 }
168 }
169 }
170} // namespace visionx
@ CV_CALIB_ETALON_CHESSBOARD
Definition calibfilter.h:71
Property< PropertyType > getProperty(const std::string &name)
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)
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 onInitImageProcessor() override
Setup the vision component.
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
bool waitForImages(int milliseconds=1000)
Wait for new images.
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
int getImages(CByteImage **ppImages)
Poll images from provider.
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
#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_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
ArmarX headers.