1
1
#include " plugin_camera_intrinsic_calib.h"
2
+
2
3
#include < dirent.h>
3
- # include < iostream >
4
+
4
5
#include < chrono>
6
+ #include < iostream>
5
7
6
- PluginCameraIntrinsicCalibration::PluginCameraIntrinsicCalibration (
7
- FrameBuffer *buffer, CameraParameters &_camera_params)
8
+ #include " conversions_greyscale.h"
9
+
10
+ PluginCameraIntrinsicCalibration::PluginCameraIntrinsicCalibration (FrameBuffer *buffer,
11
+ CameraParameters &_camera_params)
8
12
: VisionPlugin(buffer),
9
13
settings(new VarList(" Camera Intrinsic Calibration" )),
10
14
widget(new CameraIntrinsicCalibrationWidget(_camera_params)),
11
15
camera_params(_camera_params) {
12
-
13
16
worker = new PluginCameraIntrinsicCalibrationWorker (_camera_params, widget);
14
17
15
18
chessboard_capture_dt = new VarDouble (" chessboard capture dT" , 0.2 );
@@ -40,42 +43,30 @@ PluginCameraIntrinsicCalibration::~PluginCameraIntrinsicCalibration() {
40
43
delete chessboard_capture_dt;
41
44
}
42
45
43
- VarList *PluginCameraIntrinsicCalibration::getSettings () {
44
- return settings.get ();
45
- }
46
+ VarList *PluginCameraIntrinsicCalibration::getSettings () { return settings.get (); }
46
47
47
- std::string PluginCameraIntrinsicCalibration::getName () {
48
- return " Camera Intrinsic Calibration" ;
49
- }
48
+ std::string PluginCameraIntrinsicCalibration::getName () { return " Camera Intrinsic Calibration" ; }
50
49
51
- QWidget *PluginCameraIntrinsicCalibration::getControlWidget () {
52
- return static_cast <QWidget *>(worker->widget );
53
- }
50
+ QWidget *PluginCameraIntrinsicCalibration::getControlWidget () { return static_cast <QWidget *>(worker->widget ); }
54
51
55
- ProcessResult
56
- PluginCameraIntrinsicCalibration::process (FrameData *data,
57
- RenderOptions *options) {
52
+ ProcessResult PluginCameraIntrinsicCalibration::process (FrameData *data, RenderOptions *options) {
58
53
(void )options;
59
54
60
- Image<raw8> *img_greyscale;
61
- if ((img_greyscale = reinterpret_cast <Image<raw8> *>(
62
- data->map .get (" greyscale" ))) == nullptr ) {
63
- std::cerr << " Cannot run camera intrinsic calibration. Greyscale image is "
64
- " not available.\n " ;
65
- return ProcessingFailed;
55
+ Image<raw8> *img_calibration;
56
+ if ((img_calibration = reinterpret_cast <Image<raw8> *>(data->map .get (" img_calibration" ))) == nullptr ) {
57
+ img_calibration = reinterpret_cast <Image<raw8> *>(data->map .insert (" img_calibration" , new Image<raw8>()));
66
58
}
67
59
60
+ ConversionsGreyscale::cvColor2Grey (data->video , img_calibration);
61
+
68
62
Chessboard *chessboard;
69
- if ((chessboard = reinterpret_cast <Chessboard *>(
70
- data->map .get (" chessboard" ))) == nullptr ) {
71
- chessboard = reinterpret_cast <Chessboard *>(
72
- data->map .insert (" chessboard" , new Chessboard ()));
63
+ if ((chessboard = reinterpret_cast <Chessboard *>(data->map .get (" chessboard" ))) == nullptr ) {
64
+ chessboard = reinterpret_cast <Chessboard *>(data->map .insert (" chessboard" , new Chessboard ()));
73
65
}
74
66
75
67
// cv expects row major order and image stores col major.
76
68
// height and width are swapped intentionally!
77
- cv::Mat greyscale_mat (img_greyscale->getHeight (), img_greyscale->getWidth (),
78
- CV_8UC1, img_greyscale->getData ());
69
+ cv::Mat greyscale_mat (img_calibration->getHeight (), img_calibration->getWidth (), CV_8UC1, img_calibration->getData ());
79
70
worker->imageSize = greyscale_mat.size ();
80
71
81
72
if (widget->should_load_images ) {
@@ -88,7 +79,6 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
88
79
}
89
80
90
81
if (widget->isCapturing () && chessboard->pattern_was_found ) {
91
-
92
82
double captureDiff = data->video .getTime () - lastChessboardCaptureFrame;
93
83
if (captureDiff < chessboard_capture_dt->getDouble ()) {
94
84
return ProcessingOk;
@@ -105,7 +95,7 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
105
95
}
106
96
}
107
97
108
- if (widget->should_calibrate ) {
98
+ if (widget->should_calibrate ) {
109
99
widget->should_calibrate = false ;
110
100
emit startCalibration ();
111
101
}
@@ -118,10 +108,9 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
118
108
return ProcessingOk;
119
109
}
120
110
121
- PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker (
122
- CameraParameters &_camera_params, CameraIntrinsicCalibrationWidget *widget)
111
+ PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker (CameraParameters &_camera_params,
112
+ CameraIntrinsicCalibrationWidget *widget)
123
113
: widget(widget), camera_params(_camera_params) {
124
-
125
114
corner_sub_pixel_windows_size = new VarInt (" window size" , 5 , 1 );
126
115
corner_sub_pixel_max_iterations = new VarInt (" max iterations" , 30 , 1 );
127
116
corner_sub_pixel_epsilon = new VarDouble (" epsilon" , 0.1 , 1e-10 );
@@ -139,8 +128,7 @@ PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker(
139
128
thread->start ();
140
129
}
141
130
142
- PluginCameraIntrinsicCalibrationWorker::
143
- ~PluginCameraIntrinsicCalibrationWorker () {
131
+ PluginCameraIntrinsicCalibrationWorker::~PluginCameraIntrinsicCalibrationWorker () {
144
132
thread->quit ();
145
133
thread->deleteLater ();
146
134
@@ -156,7 +144,6 @@ PluginCameraIntrinsicCalibrationWorker::
156
144
}
157
145
158
146
void PluginCameraIntrinsicCalibrationWorker::calibrate () {
159
-
160
147
calib_mutex.lock ();
161
148
widget->calibrating = true ;
162
149
widget->updateConfigurationEnabled ();
@@ -174,15 +161,14 @@ void PluginCameraIntrinsicCalibrationWorker::calibrate() {
174
161
if (!initializeCameraMatrix->getBool ()) {
175
162
flags |= cv::CALIB_USE_INTRINSIC_GUESS;
176
163
}
177
-
164
+
178
165
try {
179
166
std::cout << " Start calibrating with " << image_points.size () << " samples" << std::endl;
180
167
auto start = std::chrono::high_resolution_clock::now ();
181
168
182
- double rms = cv::calibrateCamera (object_points, image_points, imageSize,
183
- camera_params.intrinsic_parameters ->camera_mat ,
184
- camera_params.intrinsic_parameters ->dist_coeffs ,
185
- rvecs, tvecs, flags);
169
+ double rms =
170
+ cv::calibrateCamera (object_points, image_points, imageSize, camera_params.intrinsic_parameters ->camera_mat ,
171
+ camera_params.intrinsic_parameters ->dist_coeffs , rvecs, tvecs, flags);
186
172
187
173
auto finish = std::chrono::high_resolution_clock::now ();
188
174
std::chrono::duration<double > elapsed = finish - start;
@@ -199,19 +185,18 @@ void PluginCameraIntrinsicCalibrationWorker::calibrate() {
199
185
calib_mutex.unlock ();
200
186
}
201
187
202
- bool PluginCameraIntrinsicCalibrationWorker::addChessboard (
203
- const Chessboard *chessboard) {
188
+ bool PluginCameraIntrinsicCalibrationWorker::addChessboard (const Chessboard *chessboard) {
204
189
calib_mutex.lock ();
205
190
206
191
// Check if there is a similar sample already
207
- for (const auto & img_points : this ->image_points ) {
192
+ for (const auto & img_points : this ->image_points ) {
208
193
double sq_diff_sum = 0 ;
209
- for (uint i = 0 ; i < img_points.size (); i++) {
194
+ for (uint i = 0 ; i < img_points.size (); i++) {
210
195
double diff = cv::norm (img_points[i] - chessboard->corners [i]);
211
- sq_diff_sum += diff* diff;
196
+ sq_diff_sum += diff * diff;
212
197
}
213
- double sq_diff = sq_diff_sum / img_points.size ();
214
- if (sq_diff < this ->corner_diff_sq_threshold ->getDouble ()) {
198
+ double sq_diff = sq_diff_sum / ( double ) img_points.size ();
199
+ if (sq_diff < this ->corner_diff_sq_threshold ->getDouble ()) {
215
200
calib_mutex.unlock ();
216
201
return false ;
217
202
}
@@ -227,65 +212,51 @@ bool PluginCameraIntrinsicCalibrationWorker::addChessboard(
227
212
}
228
213
this ->object_points .push_back (obj);
229
214
230
- this ->widget ->setNumDataPoints (this ->object_points .size ());
215
+ this ->widget ->setNumDataPoints (( int ) this ->object_points .size ());
231
216
calib_mutex.unlock ();
232
217
return true ;
233
218
}
234
219
235
- void PluginCameraIntrinsicCalibrationWorker::detectChessboard (
236
- const cv::Mat &greyscale_mat, Chessboard *chessboard) const {
237
- chessboard->pattern_size .height =
238
- this ->camera_params .additional_calibration_information ->grid_height
239
- ->getDouble ();
240
- chessboard->pattern_size .width =
241
- this ->camera_params .additional_calibration_information ->grid_width
242
- ->getDouble ();
220
+ void PluginCameraIntrinsicCalibrationWorker::detectChessboard (const cv::Mat &greyscale_mat,
221
+ Chessboard *chessboard) const {
222
+ chessboard->pattern_size .height = this ->camera_params .additional_calibration_information ->grid_height ->getDouble ();
223
+ chessboard->pattern_size .width = this ->camera_params .additional_calibration_information ->grid_width ->getDouble ();
243
224
chessboard->corners .clear ();
244
225
245
226
cv::Mat greyscale_mat_low_res;
246
227
double scale_factor = min (1.0 , reduced_image_width->getDouble () / greyscale_mat.size ().width );
247
- cv::resize (greyscale_mat, greyscale_mat_low_res, cv::Size (), scale_factor,
248
- scale_factor);
228
+ cv::resize (greyscale_mat, greyscale_mat_low_res, cv::Size (), scale_factor, scale_factor);
249
229
250
230
std::vector<cv::Point2f> corners_low_res;
251
- chessboard->pattern_was_found = this ->findPattern (
252
- greyscale_mat_low_res, chessboard->pattern_size , corners_low_res);
231
+ chessboard->pattern_was_found = this ->findPattern (greyscale_mat_low_res, chessboard->pattern_size , corners_low_res);
253
232
254
233
for (auto &corner : corners_low_res) {
255
- chessboard->corners .push_back (
256
- cv::Point (corner.x / scale_factor, corner.y / scale_factor));
234
+ chessboard->corners .push_back (cv::Point (corner.x / scale_factor, corner.y / scale_factor));
257
235
}
258
236
259
- if (chessboard->pattern_was_found &&
260
- this ->widget ->cornerSubPixCorrectionEnabled ()) {
237
+ if (chessboard->pattern_was_found && this ->widget ->cornerSubPixCorrectionEnabled ()) {
261
238
cv::cornerSubPix (
262
239
greyscale_mat, chessboard->corners ,
263
- cv::Size (corner_sub_pixel_windows_size->getInt (),
264
- corner_sub_pixel_windows_size->getInt ()),
265
- cv::Size (-1 , -1 ),
266
- cv::TermCriteria (cv::TermCriteria::EPS | cv::TermCriteria::MAX_ITER,
267
- corner_sub_pixel_max_iterations->getInt (),
240
+ cv::Size (corner_sub_pixel_windows_size->getInt (), corner_sub_pixel_windows_size->getInt ()), cv::Size (-1 , -1 ),
241
+ cv::TermCriteria (cv::TermCriteria::EPS | cv::TermCriteria::MAX_ITER, corner_sub_pixel_max_iterations->getInt (),
268
242
corner_sub_pixel_epsilon->getDouble ()));
269
243
}
270
244
}
271
245
272
- bool PluginCameraIntrinsicCalibrationWorker::findPattern (
273
- const cv::Mat &image, const cv::Size &pattern_size,
274
- vector<cv::Point2f> &corners) const {
246
+ bool PluginCameraIntrinsicCalibrationWorker::findPattern (const cv::Mat &image, const cv::Size &pattern_size,
247
+ vector<cv::Point2f> &corners) const {
275
248
using Pattern = CameraIntrinsicCalibrationWidget::Pattern;
276
- int cb_flags = cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_FAST_CHECK +
277
- cv::CALIB_CB_NORMALIZE_IMAGE;
249
+ int cb_flags = cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_NORMALIZE_IMAGE;
278
250
279
251
switch (widget->getPattern ()) {
280
- case Pattern::CHECKERBOARD:
281
- return cv::findChessboardCorners (image, pattern_size, corners, cb_flags);
282
- case Pattern::CIRCLES:
283
- return cv::findCirclesGrid (image, pattern_size, corners);
284
- case Pattern::ASYMMETRIC_CIRCLES:
285
- return cv::findCirclesGrid (image, pattern_size, corners,
286
- cv::CALIB_CB_ASYMMETRIC_GRID);
287
- default :
288
- return false ;
252
+ case Pattern::CHECKERBOARD:
253
+ return cv::findChessboardCorners (image, pattern_size, corners, cb_flags);
254
+ case Pattern::CIRCLES:
255
+ return cv::findCirclesGrid (image, pattern_size, corners);
256
+ case Pattern::ASYMMETRIC_CIRCLES:
257
+ return cv::findCirclesGrid (image, pattern_size, corners, cv::CALIB_CB_ASYMMETRIC_GRID);
258
+ default :
259
+ return false ;
289
260
}
290
261
}
291
262
@@ -299,10 +270,10 @@ void PluginCameraIntrinsicCalibrationWorker::loadImages() {
299
270
detectChessboard (mat, &image_chessboard);
300
271
if (image_chessboard.pattern_was_found ) {
301
272
bool added = addChessboard (&image_chessboard);
302
- if (added) {
303
- std::cout << " Added chessboard" <<std::endl;
273
+ if (added) {
274
+ std::cout << " Added chessboard" << std::endl;
304
275
} else {
305
- std::cout << " Filtered chessboard" <<std::endl;
276
+ std::cout << " Filtered chessboard" << std::endl;
306
277
}
307
278
} else {
308
279
std::cout << " No chessboard detected" << std::endl;
@@ -326,10 +297,8 @@ void PluginCameraIntrinsicCalibrationWorker::clearData() {
326
297
calib_mutex.unlock ();
327
298
}
328
299
329
- ImageStorage::ImageStorage (CameraIntrinsicCalibrationWidget *widget)
330
- : widget(widget) {
331
- image_dir =
332
- new VarString (" pattern image dir" , " test-data/intrinsic_calibration" );
300
+ ImageStorage::ImageStorage (CameraIntrinsicCalibrationWidget *widget) : widget(widget) {
301
+ image_dir = new VarString (" pattern image dir" , " test-data/intrinsic_calibration" );
333
302
334
303
thread = new QThread ();
335
304
thread->setObjectName (" IntrinsicCalibrationImageStorage" );
@@ -344,7 +313,6 @@ ImageStorage::~ImageStorage() {
344
313
}
345
314
346
315
void ImageStorage::saveImages () {
347
-
348
316
image_save_mutex.lock ();
349
317
if (images_to_save.empty ()) {
350
318
image_save_mutex.unlock ();
@@ -357,26 +325,24 @@ void ImageStorage::saveImages() {
357
325
}
358
326
}
359
327
360
- void ImageStorage::saveImage (cv::Mat& image) const {
328
+ void ImageStorage::saveImage (cv::Mat & image) const {
361
329
long t_now = (long )(GetTimeSec () * 1e9 );
362
330
QString num = QString::number (t_now);
363
- QString filename =
364
- QString (image_dir->getString ().c_str ()) + " /" + num + " .png" ;
331
+ QString filename = QString (image_dir->getString ().c_str ()) + " /" + num + " .png" ;
365
332
cv::imwrite (filename.toStdString (), image);
366
333
}
367
334
368
335
void ImageStorage::readImages (std::vector<cv::Mat> &images) const {
369
336
DIR *dp;
370
337
if ((dp = opendir (image_dir->getString ().c_str ())) == nullptr ) {
371
- std::cerr << " Failed to open directory: " << image_dir->getString ()
372
- << std::endl;
338
+ std::cerr << " Failed to open directory: " << image_dir->getString () << std::endl;
373
339
return ;
374
340
}
375
341
struct dirent *dirp;
376
342
std::list<std::string> imgs_to_load (0 );
377
343
while ((dirp = readdir (dp))) {
378
344
std::string file_name (dirp->d_name );
379
- if (file_name[0 ] != ' .' ) { // not a hidden file or one of '..' or '.'
345
+ if (file_name[0 ] != ' .' ) { // not a hidden file or one of '..' or '.'
380
346
imgs_to_load.push_back (image_dir->getString () + " /" + file_name);
381
347
}
382
348
}
0 commit comments