Skip to content

Commit 39c958a

Browse files
committed
Make intrinsic calib plugin independent of greyscale plugin
1 parent a3814cb commit 39c958a

File tree

4 files changed

+201
-98
lines changed

4 files changed

+201
-98
lines changed

src/app/plugins/plugin_camera_intrinsic_calib.cpp

Lines changed: 64 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
#include "plugin_camera_intrinsic_calib.h"
2+
23
#include <dirent.h>
3-
#include <iostream>
4+
45
#include <chrono>
6+
#include <iostream>
57

6-
PluginCameraIntrinsicCalibration::PluginCameraIntrinsicCalibration(
7-
FrameBuffer *buffer, CameraParameters &_camera_params)
8+
#include "conversions_greyscale.h"
9+
10+
PluginCameraIntrinsicCalibration::PluginCameraIntrinsicCalibration(FrameBuffer *buffer,
11+
CameraParameters &_camera_params)
812
: VisionPlugin(buffer),
913
settings(new VarList("Camera Intrinsic Calibration")),
1014
widget(new CameraIntrinsicCalibrationWidget(_camera_params)),
1115
camera_params(_camera_params) {
12-
1316
worker = new PluginCameraIntrinsicCalibrationWorker(_camera_params, widget);
1417

1518
chessboard_capture_dt = new VarDouble("chessboard capture dT", 0.2);
@@ -40,42 +43,30 @@ PluginCameraIntrinsicCalibration::~PluginCameraIntrinsicCalibration() {
4043
delete chessboard_capture_dt;
4144
}
4245

43-
VarList *PluginCameraIntrinsicCalibration::getSettings() {
44-
return settings.get();
45-
}
46+
VarList *PluginCameraIntrinsicCalibration::getSettings() { return settings.get(); }
4647

47-
std::string PluginCameraIntrinsicCalibration::getName() {
48-
return "Camera Intrinsic Calibration";
49-
}
48+
std::string PluginCameraIntrinsicCalibration::getName() { return "Camera Intrinsic Calibration"; }
5049

51-
QWidget *PluginCameraIntrinsicCalibration::getControlWidget() {
52-
return static_cast<QWidget *>(worker->widget);
53-
}
50+
QWidget *PluginCameraIntrinsicCalibration::getControlWidget() { return static_cast<QWidget *>(worker->widget); }
5451

55-
ProcessResult
56-
PluginCameraIntrinsicCalibration::process(FrameData *data,
57-
RenderOptions *options) {
52+
ProcessResult PluginCameraIntrinsicCalibration::process(FrameData *data, RenderOptions *options) {
5853
(void)options;
5954

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>()));
6658
}
6759

60+
ConversionsGreyscale::cvColor2Grey(data->video, img_calibration);
61+
6862
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()));
7365
}
7466

7567
// cv expects row major order and image stores col major.
7668
// 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());
7970
worker->imageSize = greyscale_mat.size();
8071

8172
if (widget->should_load_images) {
@@ -88,7 +79,6 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
8879
}
8980

9081
if (widget->isCapturing() && chessboard->pattern_was_found) {
91-
9282
double captureDiff = data->video.getTime() - lastChessboardCaptureFrame;
9383
if (captureDiff < chessboard_capture_dt->getDouble()) {
9484
return ProcessingOk;
@@ -105,7 +95,7 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
10595
}
10696
}
10797

108-
if(widget->should_calibrate) {
98+
if (widget->should_calibrate) {
10999
widget->should_calibrate = false;
110100
emit startCalibration();
111101
}
@@ -118,10 +108,9 @@ PluginCameraIntrinsicCalibration::process(FrameData *data,
118108
return ProcessingOk;
119109
}
120110

121-
PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker(
122-
CameraParameters &_camera_params, CameraIntrinsicCalibrationWidget *widget)
111+
PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker(CameraParameters &_camera_params,
112+
CameraIntrinsicCalibrationWidget *widget)
123113
: widget(widget), camera_params(_camera_params) {
124-
125114
corner_sub_pixel_windows_size = new VarInt("window size", 5, 1);
126115
corner_sub_pixel_max_iterations = new VarInt("max iterations", 30, 1);
127116
corner_sub_pixel_epsilon = new VarDouble("epsilon", 0.1, 1e-10);
@@ -139,8 +128,7 @@ PluginCameraIntrinsicCalibrationWorker::PluginCameraIntrinsicCalibrationWorker(
139128
thread->start();
140129
}
141130

142-
PluginCameraIntrinsicCalibrationWorker::
143-
~PluginCameraIntrinsicCalibrationWorker() {
131+
PluginCameraIntrinsicCalibrationWorker::~PluginCameraIntrinsicCalibrationWorker() {
144132
thread->quit();
145133
thread->deleteLater();
146134

@@ -156,7 +144,6 @@ PluginCameraIntrinsicCalibrationWorker::
156144
}
157145

158146
void PluginCameraIntrinsicCalibrationWorker::calibrate() {
159-
160147
calib_mutex.lock();
161148
widget->calibrating = true;
162149
widget->updateConfigurationEnabled();
@@ -174,15 +161,14 @@ void PluginCameraIntrinsicCalibrationWorker::calibrate() {
174161
if (!initializeCameraMatrix->getBool()) {
175162
flags |= cv::CALIB_USE_INTRINSIC_GUESS;
176163
}
177-
164+
178165
try {
179166
std::cout << "Start calibrating with " << image_points.size() << " samples" << std::endl;
180167
auto start = std::chrono::high_resolution_clock::now();
181168

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);
186172

187173
auto finish = std::chrono::high_resolution_clock::now();
188174
std::chrono::duration<double> elapsed = finish - start;
@@ -199,19 +185,18 @@ void PluginCameraIntrinsicCalibrationWorker::calibrate() {
199185
calib_mutex.unlock();
200186
}
201187

202-
bool PluginCameraIntrinsicCalibrationWorker::addChessboard(
203-
const Chessboard *chessboard) {
188+
bool PluginCameraIntrinsicCalibrationWorker::addChessboard(const Chessboard *chessboard) {
204189
calib_mutex.lock();
205190

206191
// 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) {
208193
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++) {
210195
double diff = cv::norm(img_points[i] - chessboard->corners[i]);
211-
sq_diff_sum += diff*diff;
196+
sq_diff_sum += diff * diff;
212197
}
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()) {
215200
calib_mutex.unlock();
216201
return false;
217202
}
@@ -227,65 +212,51 @@ bool PluginCameraIntrinsicCalibrationWorker::addChessboard(
227212
}
228213
this->object_points.push_back(obj);
229214

230-
this->widget->setNumDataPoints(this->object_points.size());
215+
this->widget->setNumDataPoints((int) this->object_points.size());
231216
calib_mutex.unlock();
232217
return true;
233218
}
234219

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();
243224
chessboard->corners.clear();
244225

245226
cv::Mat greyscale_mat_low_res;
246227
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);
249229

250230
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);
253232

254233
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));
257235
}
258236

259-
if (chessboard->pattern_was_found &&
260-
this->widget->cornerSubPixCorrectionEnabled()) {
237+
if (chessboard->pattern_was_found && this->widget->cornerSubPixCorrectionEnabled()) {
261238
cv::cornerSubPix(
262239
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(),
268242
corner_sub_pixel_epsilon->getDouble()));
269243
}
270244
}
271245

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 {
275248
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;
278250

279251
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;
289260
}
290261
}
291262

@@ -299,10 +270,10 @@ void PluginCameraIntrinsicCalibrationWorker::loadImages() {
299270
detectChessboard(mat, &image_chessboard);
300271
if (image_chessboard.pattern_was_found) {
301272
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;
304275
} else {
305-
std::cout << "Filtered chessboard" <<std::endl;
276+
std::cout << "Filtered chessboard" << std::endl;
306277
}
307278
} else {
308279
std::cout << "No chessboard detected" << std::endl;
@@ -326,10 +297,8 @@ void PluginCameraIntrinsicCalibrationWorker::clearData() {
326297
calib_mutex.unlock();
327298
}
328299

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");
333302

334303
thread = new QThread();
335304
thread->setObjectName("IntrinsicCalibrationImageStorage");
@@ -344,7 +313,6 @@ ImageStorage::~ImageStorage() {
344313
}
345314

346315
void ImageStorage::saveImages() {
347-
348316
image_save_mutex.lock();
349317
if (images_to_save.empty()) {
350318
image_save_mutex.unlock();
@@ -357,26 +325,24 @@ void ImageStorage::saveImages() {
357325
}
358326
}
359327

360-
void ImageStorage::saveImage(cv::Mat& image) const {
328+
void ImageStorage::saveImage(cv::Mat &image) const {
361329
long t_now = (long)(GetTimeSec() * 1e9);
362330
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";
365332
cv::imwrite(filename.toStdString(), image);
366333
}
367334

368335
void ImageStorage::readImages(std::vector<cv::Mat> &images) const {
369336
DIR *dp;
370337
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;
373339
return;
374340
}
375341
struct dirent *dirp;
376342
std::list<std::string> imgs_to_load(0);
377343
while ((dirp = readdir(dp))) {
378344
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 '.'
380346
imgs_to_load.push_back(image_dir->getString() + "/" + file_name);
381347
}
382348
}

src/shared/CMakeLists.txt.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ set (SHARED_SRCS
3636
${shared_dir}/util/camera_calibration.cpp
3737
${shared_dir}/util/camera_parameters.cpp
3838
${shared_dir}/util/conversions.cpp
39+
${shared_dir}/util/conversions_greyscale.cpp
3940
${shared_dir}/util/global_random.cpp
4041
${shared_dir}/util/image.cpp
4142
${shared_dir}/util/image_io.cpp

0 commit comments

Comments
 (0)