Subversion Repositories seema-scanner

Rev

Rev 36 | Rev 42 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36 Rev 41
1
#include "SMScanner.h"
1
#include "SMScanner.h"
2
#include "ui_SMScanner.h"
2
#include "ui_SMScanner.h"
3
 
3
 
4
#include <QMetaObject>
4
#include <QMetaObject>
5
#include <QFileDialog>
5
#include <QFileDialog>
6
 
6
 
7
SMScanner::SMScanner(QWidget *parent) :QMainWindow(parent), ui(new Ui::SMScanner),
7
SMScanner::SMScanner(QWidget *parent) :QMainWindow(parent), ui(new Ui::SMScanner),
8
                                        calibrationReviewMode(false), captureReviewMode(false){
8
                                        calibrationReviewMode(false), captureReviewMode(false){
9
    ui->setupUi(this);
9
    ui->setupUi(this);
10
 
10
 
11
    // Register metatypes
11
    // Register metatypes
12
    qRegisterMetaType<cv::Mat>("cv::Mat");
12
    qRegisterMetaType<cv::Mat>("cv::Mat");
13
    qRegisterMetaType< std::vector<cv::Mat> >("std::vector<cv::Mat>");
13
    qRegisterMetaType< std::vector<cv::Mat> >("std::vector<cv::Mat>");
14
    qRegisterMetaType< std::vector<float> >("std::vector<float>");
14
    qRegisterMetaType< std::vector<float> >("std::vector<float>");
15
    qRegisterMetaType<SMCalibrationSet>("SMCalibrationSet");
15
    qRegisterMetaType<SMCalibrationSet>("SMCalibrationSet");
16
    qRegisterMetaType<SMCalibrationParameters>("SMCalibrationParameters");
16
    qRegisterMetaType<SMCalibrationParameters>("SMCalibrationParameters");
17
    qRegisterMetaTypeStreamOperators<SMCalibrationParameters>("SMCalibrationParameters");
17
    qRegisterMetaTypeStreamOperators<SMCalibrationParameters>("SMCalibrationParameters");
18
    qRegisterMetaType< std::vector<SMCalibrationSet> >("std::vector<SMCalibrationSet>");
18
    qRegisterMetaType< std::vector<SMCalibrationSet> >("std::vector<SMCalibrationSet>");
19
    qRegisterMetaType<SMFrameSequence>("SMFrameSequence");
19
    qRegisterMetaType<SMFrameSequence>("SMFrameSequence");
-
 
20
    qRegisterMetaType<pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr>("pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr");
20
 
21
 
21
    // Restore geometry
22
    // Restore geometry
22
    this->restoreGeometry(settings.value("geometry/mainwindow").toByteArray());
23
    this->restoreGeometry(settings.value("geometry/mainwindow").toByteArray());
23
    this->restoreState(settings.value("state/mainwindow").toByteArray());
24
    this->restoreState(settings.value("state/mainwindow").toByteArray());
24
 
25
 
25
    // Set up threads
26
    // Set up threads
26
    captureWorker = new SMCaptureWorker;
27
    captureWorker = new SMCaptureWorker;
27
    captureWorkerThread = new QThread(this);
28
    captureWorkerThread = new QThread(this);
28
    captureWorkerThread->setObjectName("captureWorkerThread");
29
    captureWorkerThread->setObjectName("captureWorkerThread");
29
    captureWorker->moveToThread(captureWorkerThread);
30
    captureWorker->moveToThread(captureWorkerThread);
30
    captureWorkerThread->start();
31
    captureWorkerThread->start();
31
 
32
 
32
    // Connections
33
    // Connections
33
    connect(captureWorker, SIGNAL(newFrame(unsigned int, cv::Mat)), this, SLOT(onReceiveFrame(unsigned int, cv::Mat)));
34
    connect(captureWorker, SIGNAL(newFrame(unsigned int, cv::Mat)), this, SLOT(onReceiveFrame(unsigned int, cv::Mat)));
34
    connect(captureWorker, SIGNAL(newCalibrationSet(SMCalibrationSet)), this, SLOT(onReceiveCalibrationSet(SMCalibrationSet)));
35
    connect(captureWorker, SIGNAL(newCalibrationSet(SMCalibrationSet)), this, SLOT(onReceiveCalibrationSet(SMCalibrationSet)));
35
    connect(captureWorker, SIGNAL(newFrameSequence(SMFrameSequence)), this, SLOT(onReceiveFrameSequence(SMFrameSequence)));
36
    connect(captureWorker, SIGNAL(newFrameSequence(SMFrameSequence)), this, SLOT(onReceiveFrameSequence(SMFrameSequence)));
36
    connect(captureWorker, SIGNAL(rotatedTo(float)), this, SLOT(onReceiveRotatedTo(float)));
37
    connect(captureWorker, SIGNAL(rotatedTo(float)), this, SLOT(onReceiveRotatedTo(float)));
37
 
38
 
38
    // Start capturing
39
    // Start capturing
39
    QMetaObject::invokeMethod(captureWorker, "setup");
40
    QMetaObject::invokeMethod(captureWorker, "setup");
40
    QMetaObject::invokeMethod(captureWorker, "doWork");
41
    QMetaObject::invokeMethod(captureWorker, "doWork");
41
 
42
 
42
}
43
}
43
 
44
 
44
void SMScanner::onReceiveFrame(unsigned int camId, cv::Mat frame){
45
void SMScanner::onReceiveFrame(unsigned int camId, cv::Mat frame){
45
 
46
 
46
    if(camId == 0){
47
    if(camId == 0){
47
        if(!calibrationReviewMode)
48
        if(!calibrationReviewMode)
48
            ui->calibrationCamera0Widget->showImageCV(frame);
49
            ui->calibrationCamera0Widget->showImageCV(frame);
49
        if(!captureReviewMode)
50
        if(!captureReviewMode)
50
            ui->captureCamera0Widget->showImageCV(frame);
51
            ui->captureCamera0Widget->showImageCV(frame);
51
    } else if(camId == 1){
52
    } else if(camId == 1){
52
        if(!calibrationReviewMode)
53
        if(!calibrationReviewMode)
53
            ui->calibrationCamera1Widget->showImageCV(frame);
54
            ui->calibrationCamera1Widget->showImageCV(frame);
54
        if(!captureReviewMode)
55
        if(!captureReviewMode)
55
            ui->captureCamera1Widget->showImageCV(frame);
56
            ui->captureCamera1Widget->showImageCV(frame);
56
    }
57
    }
57
}
58
}
58
 
59
 
59
void SMScanner::on_actionPreferences_triggered(){
60
void SMScanner::on_actionPreferences_triggered(){
60
 
61
 
61
    preferenceDialog.show();
62
    preferenceDialog.show();
62
}
63
}
63
 
64
 
64
void SMScanner::closeEvent(QCloseEvent *event){
65
void SMScanner::closeEvent(QCloseEvent *event){
65
 
66
 
66
    // Stop capturing thread
67
    // Stop capturing thread
67
    connect(captureWorker, SIGNAL(finished()), captureWorker, SLOT(deleteLater()));
68
    connect(captureWorker, SIGNAL(finished()), captureWorker, SLOT(deleteLater()));
68
    connect(captureWorker, SIGNAL(finished()), captureWorkerThread, SLOT(quit()));
69
    connect(captureWorker, SIGNAL(finished()), captureWorkerThread, SLOT(quit()));
69
    QMetaObject::invokeMethod(captureWorker, "stopWork");
70
    QMetaObject::invokeMethod(captureWorker, "stopWork");
70
    captureWorkerThread->quit();
71
    captureWorkerThread->quit();
71
    captureWorkerThread->wait();
72
    captureWorkerThread->wait();
72
 
73
 
73
    // Save window geometry
74
    // Save window geometry
74
    settings.setValue("geometry/mainwindow", this->saveGeometry());
75
    settings.setValue("geometry/mainwindow", this->saveGeometry());
75
    settings.setValue("state/mainwindow", this->saveState());
76
    settings.setValue("state/mainwindow", this->saveState());
76
 
77
 
77
    event->accept();
78
    event->accept();
78
 
79
 
79
}
80
}
80
 
81
 
81
SMScanner::~SMScanner(){
82
SMScanner::~SMScanner(){
82
    delete ui;
83
    delete ui;
83
}
84
}
84
 
85
 
85
void SMScanner::on_singleCalibrationButton_clicked(){
86
void SMScanner::on_singleCalibrationButton_clicked(){
86
 
87
 
87
    // If in review mode, go back to aquisition mode
88
    // If in review mode, go back to aquisition mode
88
    if(calibrationReviewMode){
89
    if(calibrationReviewMode){
89
        ui->calibrationListWidget->clearSelection();
90
        ui->calibrationListWidget->clearSelection();
90
        ui->singleCalibrationButton->setText("Single Aquisition");
91
        ui->singleCalibrationButton->setText("Single Aquisition");
91
        ui->batchCalibrationButton->setText("Batch Aquisition");
92
        ui->batchCalibrationButton->setText("Batch Aquisition");
92
        calibrationReviewMode = false;
93
        calibrationReviewMode = false;
93
        return;
94
        return;
94
    }
95
    }
95
 
96
 
96
    QMetaObject::invokeMethod(captureWorker, "acquireCalibrationSet", Q_ARG(float, -1.0));
97
    QMetaObject::invokeMethod(captureWorker, "acquireCalibrationSet", Q_ARG(float, -1.0));
97
 
98
 
98
}
99
}
99
 
100
 
100
 
101
 
101
void SMScanner::on_batchCalibrationButton_clicked(){
102
void SMScanner::on_batchCalibrationButton_clicked(){
102
 
103
 
103
    // If in review mode, go back to aquisition mode
104
    // If in review mode, go back to aquisition mode
104
    if(calibrationReviewMode){
105
    if(calibrationReviewMode){
105
        ui->calibrationListWidget->clearSelection();
106
        ui->calibrationListWidget->clearSelection();
106
        ui->singleCalibrationButton->setText("Single Aquisition");
107
        ui->singleCalibrationButton->setText("Single Aquisition");
107
        ui->batchCalibrationButton->setText("Batch Aquisition");
108
        ui->batchCalibrationButton->setText("Batch Aquisition");
108
        calibrationReviewMode = false;
109
        calibrationReviewMode = false;
109
        return;
110
        return;
110
    }
111
    }
111
 
112
 
112
    // Construct vector of angles
113
    // Construct vector of angles
113
    int angleStart = ui->calibrationBatchStartSpinBox->value();
114
    int angleStart = ui->calibrationBatchStartSpinBox->value();
114
    int angleEnd = ui->calibrationBatchEndSpinBox->value();
115
    int angleEnd = ui->calibrationBatchEndSpinBox->value();
115
    int angleStep = ui->calibrationBatchStepSpinBox->value();
116
    int angleStep = ui->calibrationBatchStepSpinBox->value();
116
 
117
 
117
    if(angleStart > angleEnd)
118
    if(angleStart > angleEnd)
118
        angleEnd += 360;
119
        angleEnd += 360;
119
 
120
 
120
    std::vector<float> angles;
121
    std::vector<float> angles;
121
    for(int i=angleStart; i<=angleEnd; i+=angleStep)
122
    for(int i=angleStart; i<=angleEnd; i+=angleStep)
122
        angles.push_back(i % 360);
123
        angles.push_back(i % 360);
123
 
124
 
124
    QMetaObject::invokeMethod(captureWorker, "acquireCalibrationSets", Q_ARG(std::vector<float>, angles));
125
    QMetaObject::invokeMethod(captureWorker, "acquireCalibrationSets", Q_ARG(std::vector<float>, angles));
125
 
126
 
126
    std::cout << "Aquiring sets at ";
127
    std::cout << "Aquiring sets at ";
127
    for(int i=0; i<angles.size(); i++)
128
    for(int i=0; i<angles.size(); i++)
128
        std::cout << angles[i] << " ";
129
        std::cout << angles[i] << " ";
129
    std::cout << " degrees" <<std::endl;
130
    std::cout << " degrees" <<std::endl;
130
}
131
}
131
 
132
 
132
 
133
 
133
void SMScanner::on_calibrationRotationDial_sliderReleased(){
134
void SMScanner::on_calibrationRotationDial_sliderReleased(){
134
 
135
 
135
    float angle = ui->calibrationRotationDial->value();
136
    float angle = ui->calibrationRotationDial->value();
136
    std::cout << "Rotation stage target: " << angle << std::endl;
137
    std::cout << "Rotation stage target: " << angle << std::endl;
137
    QMetaObject::invokeMethod(captureWorker, "rotateTo", Q_ARG(float, angle));
138
    QMetaObject::invokeMethod(captureWorker, "rotateTo", Q_ARG(float, angle));
138
 
139
 
139
    ui->captureRotationDial->setValue(ui->calibrationRotationDial->value());
140
    ui->captureRotationDial->setValue(ui->calibrationRotationDial->value());
140
}
141
}
141
 
142
 
142
void SMScanner::onReceiveCalibrationSet(SMCalibrationSet calibrationSet){
143
void SMScanner::onReceiveCalibrationSet(SMCalibrationSet calibrationSet){
143
    calibrationData.push_back(calibrationSet);
144
    calibrationData.push_back(calibrationSet);
144
 
145
 
145
    // Add identifier to list
146
    // Add identifier to list
146
    QListWidgetItem* item = new QListWidgetItem(QString("Calibration Set %1 -- %2 deg").arg(ui->calibrationListWidget->count()).arg(calibrationSet.rotationAngle), ui->calibrationListWidget);
147
    QListWidgetItem* item = new QListWidgetItem(QString("Calibration Set %1 -- %2 deg").arg(ui->calibrationListWidget->count()).arg(calibrationSet.rotationAngle), ui->calibrationListWidget);
147
    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
148
    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
148
    item->setCheckState(Qt::Checked);
149
    item->setCheckState(Qt::Checked);
149
    ui->calibrationListWidget->addItem(item);
150
    ui->calibrationListWidget->addItem(item);
150
 
151
 
151
    // Set enabled checkmark
152
    // Set enabled checkmark
152
    if(calibrationData.size() >= 2)
153
    if(calibrationData.size() >= 2)
153
        ui->calibrateButton->setEnabled(true);
154
        ui->calibrateButton->setEnabled(true);
154
}
155
}
155
 
156
 
156
void SMScanner::on_calibrateButton_clicked(){
157
void SMScanner::on_calibrateButton_clicked(){
157
 
158
 
158
    // disable ui elements
159
    // disable ui elements
159
    ui->calibrateButton->setEnabled(false);
160
    ui->calibrateButton->setEnabled(false);
160
    ui->calibrationFrame->setEnabled(false);
161
    ui->calibrationFrame->setEnabled(false);
161
 
162
 
162
    // set checked flags
163
    // set checked flags
163
    for(int i=0; i<calibrationData.size(); i++){
164
    for(int i=0; i<calibrationData.size(); i++){
164
        calibrationData[i].checked = (ui->calibrationListWidget->item(i)->checkState() == Qt::Checked);
165
        calibrationData[i].checked = (ui->calibrationListWidget->item(i)->checkState() == Qt::Checked);
165
    }
166
    }
166
 
167
 
167
//    SMCalibrationWorker calibrationWorker;
168
//    SMCalibrationWorker calibrationWorker;
168
//    calibrationWorker.performCalibration(calibrationData);
169
//    calibrationWorker.performCalibration(calibrationData);
169
 
170
 
170
    // Set up calibration thread
171
    // Set up calibration thread
171
    calibrationWorker = new SMCalibrationWorker;
172
    calibrationWorker = new SMCalibrationWorker;
172
    calibrationWorkerThread = new QThread(this);
173
    calibrationWorkerThread = new QThread(this);
173
    calibrationWorkerThread->setObjectName("calibrationWorkerThread");
174
    calibrationWorkerThread->setObjectName("calibrationWorkerThread");
174
    calibrationWorker->moveToThread(captureWorkerThread);
175
    calibrationWorker->moveToThread(captureWorkerThread);
175
    calibrationWorkerThread->start();
176
    calibrationWorkerThread->start();
176
 
177
 
177
    // Connections
178
    // Connections
178
    connect(calibrationWorker, SIGNAL(newSetProcessed(int)), this, SLOT(onCalibrationSetProcessed(int)));
179
    connect(calibrationWorker, SIGNAL(newSetProcessed(int)), this, SLOT(onCalibrationSetProcessed(int)));
179
    connect(calibrationWorker, SIGNAL(newFrameResult(int,int,bool,cv::Mat)), this, SLOT(onCalibrationFrameResult(int,int,bool,cv::Mat)));
180
    connect(calibrationWorker, SIGNAL(newFrameResult(int,int,bool,cv::Mat)), this, SLOT(onCalibrationFrameResult(int,int,bool,cv::Mat)));
180
    connect(calibrationWorker, SIGNAL(done()), this, SLOT(onCalibrationDone()));
181
    connect(calibrationWorker, SIGNAL(done()), this, SLOT(onCalibrationDone()));
181
    connect(calibrationWorker, SIGNAL(done()), ui->pointCloudWidget, SLOT(updateCalibrationParameters()));
182
    connect(calibrationWorker, SIGNAL(done()), ui->pointCloudWidget, SLOT(updateCalibrationParameters()));
182
    connect(calibrationWorker, SIGNAL(done()), calibrationWorkerThread, SLOT(quit()));
183
    connect(calibrationWorker, SIGNAL(done()), calibrationWorkerThread, SLOT(quit()));
183
    connect(calibrationWorker, SIGNAL(done()), calibrationWorker, SLOT(deleteLater()));
184
    connect(calibrationWorker, SIGNAL(done()), calibrationWorker, SLOT(deleteLater()));
184
 
185
 
185
    // Start calibration
186
    // Start calibration
186
    QMetaObject::invokeMethod(calibrationWorker, "performCalibration", Q_ARG(std::vector<SMCalibrationSet>, calibrationData));
187
    QMetaObject::invokeMethod(calibrationWorker, "performCalibration", Q_ARG(std::vector<SMCalibrationSet>, calibrationData));
187
 
188
 
188
}
189
}
189
 
190
 
190
 
191
 
191
 
192
 
192
void SMScanner::onCalibrationSetProcessed(int idx){
193
void SMScanner::onCalibrationSetProcessed(int idx){
193
 
194
 
194
    ui->calibrationListWidget->setCurrentRow(idx);
195
    ui->calibrationListWidget->setCurrentRow(idx);
195
}
196
}
196
 
197
 
197
void SMScanner::onCalibrationDone(){
198
void SMScanner::onCalibrationDone(){
198
 
199
 
199
    std::cout << "Calibration done!" << std::endl;
200
    std::cout << "Calibration done!" << std::endl;
200
    ui->calibrateButton->setEnabled(true);
201
    ui->calibrateButton->setEnabled(true);
201
    ui->calibrationFrame->setEnabled(true);
202
    ui->calibrationFrame->setEnabled(true);
202
 
203
 
203
}
204
}
204
 
205
 
205
void SMScanner::on_calibrationListWidget_itemSelectionChanged(){
206
void SMScanner::on_calibrationListWidget_itemSelectionChanged(){
206
 
207
 
207
    // if selection is just cleared
208
    // if selection is just cleared
208
    if(ui->calibrationListWidget->selectedItems().empty())
209
    if(ui->calibrationListWidget->selectedItems().empty())
209
        return;
210
        return;
210
 
211
 
211
    int currentRow = ui->calibrationListWidget->currentRow();
212
    int currentRow = ui->calibrationListWidget->currentRow();
212
 
213
 
213
    calibrationReviewMode = true;
214
    calibrationReviewMode = true;
214
    ui->singleCalibrationButton->setText("Live View");
215
    ui->singleCalibrationButton->setText("Live View");
215
    ui->batchCalibrationButton->setText("Live View");
216
    ui->batchCalibrationButton->setText("Live View");
216
 
217
 
217
    if(!calibrationData[currentRow].frame0Result.empty())
218
    if(!calibrationData[currentRow].frame0Result.empty())
218
        ui->calibrationCamera0Widget->showImageCV(calibrationData[currentRow].frame0Result);
219
        ui->calibrationCamera0Widget->showImageCV(calibrationData[currentRow].frame0Result);
219
    else
220
    else
220
        ui->calibrationCamera0Widget->showImageCV(calibrationData[currentRow].frame0);
221
        ui->calibrationCamera0Widget->showImageCV(calibrationData[currentRow].frame0);
221
 
222
 
222
    if(!calibrationData[currentRow].frame1Result.empty())
223
    if(!calibrationData[currentRow].frame1Result.empty())
223
        ui->calibrationCamera1Widget->showImageCV(calibrationData[currentRow].frame1Result);
224
        ui->calibrationCamera1Widget->showImageCV(calibrationData[currentRow].frame1Result);
224
    else
225
    else
225
        ui->calibrationCamera1Widget->showImageCV(calibrationData[currentRow].frame1);
226
        ui->calibrationCamera1Widget->showImageCV(calibrationData[currentRow].frame1);
226
 
227
 
227
//     std::cout << "on_calibrationListWidget_itemSelectionChanged" << std::endl;
228
//     std::cout << "on_calibrationListWidget_itemSelectionChanged" << std::endl;
228
}
229
}
229
 
230
 
230
void SMScanner::onCalibrationFrameResult(int idx, int camID, bool success, cv::Mat result){
231
void SMScanner::onCalibrationFrameResult(int idx, int camID, bool success, cv::Mat result){
231
 
232
 
232
//    std::cout << "onCalibrationFrameResult " << idx << camID << std::endl;
233
//    std::cout << "onCalibrationFrameResult " << idx << camID << std::endl;
233
 
234
 
234
    if(!success)
235
    if(!success)
235
        ui->calibrationListWidget->item(idx)->setCheckState(Qt::Unchecked);
236
        ui->calibrationListWidget->item(idx)->setCheckState(Qt::Unchecked);
236
    else {
237
    else {
237
        if(camID == 0)
238
        if(camID == 0)
238
            calibrationData[idx].frame0Result = result;
239
            calibrationData[idx].frame0Result = result;
239
        else if(camID == 1)
240
        else if(camID == 1)
240
            calibrationData[idx].frame1Result = result;
241
            calibrationData[idx].frame1Result = result;
241
    }
242
    }
242
 
243
 
243
}
244
}
244
 
245
 
245
void SMScanner::on_singleCaptureButton_clicked(){
246
void SMScanner::on_singleCaptureButton_clicked(){
246
 
247
 
247
    // If in review mode, go back to aquisition mode
248
    // If in review mode, go back to aquisition mode
248
    if(captureReviewMode){
249
    if(captureReviewMode){
249
        ui->captureTreeWidget->clearSelection();
250
        ui->captureTreeWidget->clearSelection();
250
        ui->singleCaptureButton->setText("Single Aquisition");
251
        ui->singleCaptureButton->setText("Single Aquisition");
251
        ui->batchCaptureButton->setText("Batch Aquisition");
252
        ui->batchCaptureButton->setText("Batch Aquisition");
252
        captureReviewMode = false;
253
        captureReviewMode = false;
253
        return;
254
        return;
254
    }
255
    }
255
 
256
 
256
    QMetaObject::invokeMethod(captureWorker, "acquireFrameSequence", Q_ARG(float, -1.0));
257
    QMetaObject::invokeMethod(captureWorker, "acquireFrameSequence", Q_ARG(float, -1.0));
257
 
258
 
258
}
259
}
259
 
260
 
260
 
261
 
261
void SMScanner::on_batchCaptureButton_clicked(){
262
void SMScanner::on_batchCaptureButton_clicked(){
262
 
263
 
263
    // If in review mode, go back to aquisition mode
264
    // If in review mode, go back to aquisition mode
264
    if(captureReviewMode){
265
    if(captureReviewMode){
265
        ui->captureTreeWidget->clearSelection();
266
        ui->captureTreeWidget->clearSelection();
266
        ui->singleCaptureButton->setText("Single Aquisition");
267
        ui->singleCaptureButton->setText("Single Aquisition");
267
        ui->batchCaptureButton->setText("Batch Aquisition");
268
        ui->batchCaptureButton->setText("Batch Aquisition");
268
        captureReviewMode = false;
269
        captureReviewMode = false;
269
        return;
270
        return;
270
    }
271
    }
271
 
272
 
272
    // Construct vector of angles
273
    // Construct vector of angles
273
    int angleStart = ui->captureBatchStartSpinBox->value();
274
    int angleStart = ui->captureBatchStartSpinBox->value();
274
    int angleEnd = ui->captureBatchEndSpinBox->value();
275
    int angleEnd = ui->captureBatchEndSpinBox->value();
275
    int angleStep = ui->captureBatchStepSpinBox->value();
276
    int angleStep = ui->captureBatchStepSpinBox->value();
276
 
277
 
277
    if(angleStart > angleEnd)
278
    if(angleStart > angleEnd)
278
        angleEnd += 360;
279
        angleEnd += 360;
279
 
280
 
280
    std::vector<float> angles;
281
    std::vector<float> angles;
281
    for(int i=angleStart; i<=angleEnd; i+=angleStep)
282
    for(int i=angleStart; i<=angleEnd; i+=angleStep)
282
        angles.push_back(i % 360);
283
        angles.push_back(i % 360);
283
 
284
 
284
    std::cout << "Aquiring sequences at ";
285
    std::cout << "Aquiring sequences at ";
285
    for(int i=0; i<angles.size(); i++)
286
    for(int i=0; i<angles.size(); i++)
286
        std::cout << angles[i] << " ";
287
        std::cout << angles[i] << " ";
287
    std::cout << " degrees" <<std::endl;
288
    std::cout << " degrees" <<std::endl;
288
 
289
 
289
    QMetaObject::invokeMethod(captureWorker, "acquireFrameSequences", Q_ARG(std::vector<float>, angles));
290
    QMetaObject::invokeMethod(captureWorker, "acquireFrameSequences", Q_ARG(std::vector<float>, angles));
290
}
291
}
291
 
292
 
292
void SMScanner::on_captureRotationDial_sliderReleased(){
293
void SMScanner::on_captureRotationDial_sliderReleased(){
293
 
294
 
294
    float angle = ui->captureRotationDial->value();
295
    float angle = ui->captureRotationDial->value();
295
    std::cout << "Rotation stage target: " << angle << std::endl;
296
    std::cout << "Rotation stage target: " << angle << std::endl;
296
    QMetaObject::invokeMethod(captureWorker, "rotateTo", Q_ARG(float, angle));
297
    QMetaObject::invokeMethod(captureWorker, "rotateTo", Q_ARG(float, angle));
297
 
298
 
298
    ui->calibrationRotationDial->setValue(ui->captureRotationDial->value());
299
    ui->calibrationRotationDial->setValue(ui->captureRotationDial->value());
299
}
300
}
300
 
301
 
301
void SMScanner::onReceiveFrameSequence(SMFrameSequence frameSequence){
302
void SMScanner::onReceiveFrameSequence(SMFrameSequence frameSequence){
302
 
303
 
303
    captureData.push_back(frameSequence);
304
    captureData.push_back(frameSequence);
304
 
305
 
305
    int idx = captureData.size()-1;
306
    int idx = captureData.size()-1;
306
 
307
 
307
    // Add identifier to list
308
    // Add identifier to list
308
    QTreeWidgetItem* item = new QTreeWidgetItem(ui->captureTreeWidget);
309
    QTreeWidgetItem* item = new QTreeWidgetItem(ui->captureTreeWidget);
309
    item->setText(0, QString("Frame Sequence %1 -- %2 deg").arg(idx).arg(frameSequence.rotationAngle));
310
    item->setText(0, QString("Frame Sequence %1 -- %2 deg").arg(idx).arg(frameSequence.rotationAngle));
310
    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
311
    item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
311
    item->setData(0, Qt::UserRole, QPoint(idx, -1));
312
    item->setData(0, Qt::UserRole, QPoint(idx, -1));
312
    item->setCheckState(0, Qt::Checked);
313
    item->setCheckState(0, Qt::Checked);
313
    //ui->captureTreeWidget->addItem(item);
314
    //ui->captureTreeWidget->addItem(item);
314
 
315
 
315
    for(int i=0; i<frameSequence.frames0.size(); i++){
316
    for(int i=0; i<frameSequence.frames0.size(); i++){
316
        QTreeWidgetItem* subItem = new QTreeWidgetItem(item);
317
        QTreeWidgetItem* subItem = new QTreeWidgetItem(item);
317
        subItem->setText(0, QString("frames %1").arg(i));
318
        subItem->setText(0, QString("frames %1").arg(i));
318
        subItem->setData(0, Qt::UserRole, QPoint(idx, i));
319
        subItem->setData(0, Qt::UserRole, QPoint(idx, i));
319
    }
320
    }
-
 
321
 
-
 
322
    ui->reconstructButton->setEnabled(true);
320
}
323
}
321
 
324
 
322
void SMScanner::on_captureTreeWidget_itemSelectionChanged(){
325
void SMScanner::on_captureTreeWidget_itemSelectionChanged(){
323
 
326
 
324
    // if selection is just cleared
327
    // if selection is just cleared
325
    if(ui->captureTreeWidget->selectedItems().empty())
328
    if(ui->captureTreeWidget->selectedItems().empty())
326
        return;
329
        return;
327
 
330
 
328
    QTreeWidgetItem *item = ui->captureTreeWidget->currentItem();
331
    QTreeWidgetItem *item = ui->captureTreeWidget->currentItem();
329
 
332
 
330
    captureReviewMode = true;
333
    captureReviewMode = true;
331
 
334
 
332
    ui->singleCaptureButton->setText("Live View");
335
    ui->singleCaptureButton->setText("Live View");
333
    ui->batchCaptureButton->setText("Live View");
336
    ui->batchCaptureButton->setText("Live View");
334
 
337
 
335
    QPoint idx = item->data(0, Qt::UserRole).toPoint();
338
    QPoint idx = item->data(0, Qt::UserRole).toPoint();
336
 
339
 
337
    if(idx.y() != -1){
340
    if(idx.y() != -1){
338
        ui->captureCamera0Widget->showImageCV(captureData[idx.x()].frames0[idx.y()]);
341
        ui->captureCamera0Widget->showImageCV(captureData[idx.x()].frames0[idx.y()]);
339
        ui->captureCamera1Widget->showImageCV(captureData[idx.x()].frames1[idx.y()]);
342
        ui->captureCamera1Widget->showImageCV(captureData[idx.x()].frames1[idx.y()]);
340
    }
343
    }
341
 
344
 
342
//     std::cout << "on_captureTreeWidget_itemSelectionChanged" << std::endl;
345
//     std::cout << "on_captureTreeWidget_itemSelectionChanged" << std::endl;
343
}
346
}
344
 
347
 
345
 
348
 
346
void SMScanner::onReceiveRotatedTo(float angle){
349
void SMScanner::onReceiveRotatedTo(float angle){
347
 
350
 
348
    // update ui with new position
351
    // update ui with new position
349
    ui->calibrationRotationDial->setValue(angle);
352
    ui->calibrationRotationDial->setValue(angle);
350
    ui->captureRotationDial->setValue(angle);
353
    ui->captureRotationDial->setValue(angle);
351
 
354
 
352
}
355
}
353
 
356
 
354
void SMScanner::on_actionExport_Sets_triggered(){
357
void SMScanner::on_actionExport_Sets_triggered(){
355
 
358
 
356
    QString dirName = QFileDialog::getExistingDirectory(this, "Export calibration sets", QString());
359
    QString dirName = QFileDialog::getExistingDirectory(this, "Export calibration sets", QString());
357
    for(int i=0; i<calibrationData.size(); i++){
360
    for(int i=0; i<calibrationData.size(); i++){
358
        QString fileName = QString("%1/frame0_%2.png").arg(dirName).arg(i);
361
        QString fileName = QString("%1/frame0_%2.png").arg(dirName).arg(i);
359
        cv::Mat frameBGR;
362
        cv::Mat frameBGR;
360
        cv::cvtColor(calibrationData[i].frame0, frameBGR, CV_RGB2BGR);
363
        cv::cvtColor(calibrationData[i].frame0, frameBGR, CV_RGB2BGR);
361
        cv::imwrite(fileName.toStdString(), frameBGR);
364
        cv::imwrite(fileName.toStdString(), frameBGR);
362
        fileName = QString("%1/frame1_%2.png").arg(dirName).arg(i);
365
        fileName = QString("%1/frame1_%2.png").arg(dirName).arg(i);
363
        cv::cvtColor(calibrationData[i].frame1, frameBGR, CV_RGB2BGR);
366
        cv::cvtColor(calibrationData[i].frame1, frameBGR, CV_RGB2BGR);
364
        cv::imwrite(fileName.toStdString(), frameBGR);
367
        cv::imwrite(fileName.toStdString(), frameBGR);
365
    }
368
    }
366
 
369
 
367
}
370
}
368
 
371
 
369
void SMScanner::on_actionExport_Sequences_triggered(){
372
void SMScanner::on_actionExport_Sequences_triggered(){
370
 
373
 
371
    QString dirName = QFileDialog::getExistingDirectory(this, "Export frame sequences", QString());
374
    QString dirName = QFileDialog::getExistingDirectory(this, "Export frame sequences", QString());
372
 
375
 
373
    for(int i=0; i<captureData.size(); i++){
376
    for(int i=0; i<captureData.size(); i++){
374
        QString seqDirName = QString("%1/sequence_%2").arg(dirName).arg(i);
377
        QString seqDirName = QString("%1/sequence_%2").arg(dirName).arg(i);
375
        if(!QDir().mkdir(seqDirName))
378
        if(!QDir().mkdir(seqDirName))
376
            std::cerr << "Could not create directory " << seqDirName.toStdString() << std::endl;
379
            std::cerr << "Could not create directory " << seqDirName.toStdString() << std::endl;
377
        for(int j=0; j<captureData[i].frames0.size(); j++){
380
        for(int j=0; j<captureData[i].frames0.size(); j++){
378
            QString fileName = QString("%1/frames0_%2.png").arg(seqDirName).arg(j);
381
            QString fileName = QString("%1/frames0_%2.png").arg(seqDirName).arg(j);
379
            cv::Mat frameBGR;
382
            cv::Mat frameBGR;
380
            cv::cvtColor(captureData[i].frames0[j], frameBGR, CV_RGB2BGR);
383
            cv::cvtColor(captureData[i].frames0[j], frameBGR, CV_RGB2BGR);
381
            cv::imwrite(fileName.toStdString(), frameBGR);
384
            cv::imwrite(fileName.toStdString(), frameBGR);
382
        }
385
        }
383
        for(int j=0; j<captureData[i].frames1.size(); j++){
386
        for(int j=0; j<captureData[i].frames1.size(); j++){
384
            QString fileName = QString("%1/frames1_%2.png").arg(seqDirName).arg(j);
387
            QString fileName = QString("%1/frames1_%2.png").arg(seqDirName).arg(j);
385
            cv::Mat frameBGR;
388
            cv::Mat frameBGR;
386
            cv::cvtColor(captureData[i].frames1[j], frameBGR, CV_RGB2BGR);
389
            cv::cvtColor(captureData[i].frames1[j], frameBGR, CV_RGB2BGR);
387
            cv::imwrite(fileName.toStdString(), frameBGR);
390
            cv::imwrite(fileName.toStdString(), frameBGR);
388
        }
391
        }
389
    }
392
    }
390
}
393
}
-
 
394
 
-
 
395
void SMScanner::on_reconstructButton_clicked(){
-
 
396
 
-
 
397
//    // set checked flags
-
 
398
//    for(int i=0; i<captureData.size(); i++){
-
 
399
//        captureData[i].checked = (ui->captureTreeWidget->item(i)->checkState() == Qt::Checked);
-
 
400
//    }
-
 
401
 
-
 
402
 
-
 
403
    // Set up reconstruction thread
-
 
404
    reconstructionWorker = new SMReconstructionWorker;
-
 
405
    reconstructionWorkerThread = new QThread(this);
-
 
406
    reconstructionWorkerThread->setObjectName("reconstructionWorkerThread");
-
 
407
    reconstructionWorker->moveToThread(reconstructionWorkerThread);
-
 
408
    reconstructionWorkerThread->start();
-
 
409
 
-
 
410
    // Connections
-
 
411
    connect(reconstructionWorker, SIGNAL(newPointCloud(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr)), this, SLOT(onNewPointCloud(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr)));
-
 
412
    connect(reconstructionWorker, SIGNAL(done()), reconstructionWorkerThread, SLOT(quit()));
-
 
413
    connect(reconstructionWorker, SIGNAL(done()), reconstructionWorker, SLOT(deleteLater()));
-
 
414
 
-
 
415
    // Start reconstructing
-
 
416
    QMetaObject::invokeMethod(reconstructionWorker, "reconstruct", Q_ARG(std::vector<SMFrameSequence>, captureData));
-
 
417
 
-
 
418
}
-
 
419
 
-
 
420
void SMScanner::onNewPointCloud(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr pc){
-
 
421
 
-
 
422
    SMPointCloud smCloud;
-
 
423
    //smCloud.pointCloud = pc;
-
 
424
    pointCloudData.push_back(smCloud);
-
 
425
 
-
 
426
    ui->pointCloudWidget->updatePointCloud(pc);
-
 
427
}
391
 
428