Subversion Repositories seema-scanner

Rev

Rev 226 | Rev 244 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9 jakw 1
#include "SMCaptureWorker.h"
2
 
41 jakw 3
#include "AlgorithmGrayCode.h"
99 jakw 4
#include "AlgorithmGrayCodeHorzVert.h"
128 jakw 5
#include "AlgorithmPhaseShiftTwoFreq.h"
200 jakw 6
#include "AlgorithmPhaseShiftTwoFreqHorzVert.h"
128 jakw 7
#include "AlgorithmPhaseShiftThreeFreq.h"
192 jakw 8
#include "AlgorithmPhaseShiftEmbedded.h"
123 jakw 9
#include "AlgorithmLineShift.h"
27 jakw 10
 
9 jakw 11
#include <QCoreApplication>
12
#include <QTime>
13
#include <QSettings>
27 jakw 14
#include <QtTest/QTest>
9 jakw 15
 
120 jakw 16
#include "cvtools.h"
17
 
9 jakw 18
void SMCaptureWorker::setup(){
19
 
23 jakw 20
    QSettings settings;
21
 
9 jakw 22
    // Create cameras
167 jakw 23
    int iNum0 = settings.value("camera0/interfaceNumber", -1).toInt();
24
    int cNum0 = settings.value("camera0/cameraNumber", -1).toInt();
207 flgw 25
    camera0.reset(CameraFactory::NewCamera(iNum0,cNum0,triggerModeSoftware));
169 jakw 26
 
27
    if(!camera0)
167 jakw 28
        return;
9 jakw 29
 
167 jakw 30
    int iNum1 = settings.value("camera1/interfaceNumber", -1).toInt();
31
    int cNum1 = settings.value("camera1/cameraNumber", -1).toInt();
207 flgw 32
    camera1.reset(CameraFactory::NewCamera(iNum1,cNum1,triggerModeSoftware));
169 jakw 33
 
34
    if(!camera1)
167 jakw 35
        return;
9 jakw 36
 
37
    // Set camera settings
38
    CameraSettings cameraSettings;
39
    cameraSettings.shutter = settings.value("camera/shutter", 16.666).toFloat();
40
    cameraSettings.gain = 0.0;
41
 
42
    camera0->setCameraSettings(cameraSettings);
43
    camera1->setCameraSettings(cameraSettings);
44
 
23 jakw 45
    // Start capturing
46
    camera0->startCapture();
47
    camera1->startCapture();
48
 
27 jakw 49
    // Create projector
164 raly 50
    //int screenNum = settings.value("projector/screenNumber", -1).toInt();
51
    int screenNum = settings.value("projector/screenNumber", 1).toInt();
27 jakw 52
    if(screenNum != -1)
207 flgw 53
        projector.reset(new ProjectorOpenGL(screenNum));
27 jakw 54
 
226 jakw 55
//    // Create rotation stage
56
//    for(int i = 0; i<10; i++){
57
//        try{
58
//            delete rotationStage.get();
59
//            rotationStage = std::make_shared<RotationStage>();
60
//            break;
61
//        }
62
//        catch (...){
63
//            std::cerr << "trying to setup rotation stage" << std::endl;
64
//        }
65
//    }
66
    rotationStage.reset();
67
    rotationStage.reset(new RotationStage());
51 jakw 68
 
41 jakw 69
    // Create Algorithm
137 jakw 70
    unsigned int screenCols, screenRows;
71
    projector->getScreenRes(&screenCols, &screenRows);
71 jakw 72
    codec = settings.value("algorithm", "GrayCode").toString();
73
    if(codec == "GrayCode")
207 flgw 74
        algorithm.reset(new AlgorithmGrayCode(screenCols, screenRows));
107 jakw 75
    else if(codec == "GrayCodeHorzVert")
207 flgw 76
        algorithm.reset(new AlgorithmGrayCodeHorzVert(screenCols, screenRows));
128 jakw 77
    else if(codec == "PhaseShiftTwoFreq")
207 flgw 78
        algorithm.reset(new AlgorithmPhaseShiftTwoFreq(screenCols, screenRows));
128 jakw 79
    else if(codec == "PhaseShiftThreeFreq")
207 flgw 80
        algorithm.reset(new AlgorithmPhaseShiftThreeFreq(screenCols, screenRows));
200 jakw 81
    else if(codec == "PhaseShiftTwoFreqHorzVert")
208 flgw 82
        algorithm.reset(new AlgorithmPhaseShiftTwoFreqHorzVert(screenCols, screenRows));
192 jakw 83
    else if(codec == "PhaseShiftEmbedded")
207 flgw 84
        algorithm.reset(new AlgorithmPhaseShiftEmbedded(screenCols, screenRows));
123 jakw 85
    else if(codec == "LineShift")
207 flgw 86
        algorithm.reset(new AlgorithmLineShift(screenCols, screenRows));
27 jakw 87
    else
74 jakw 88
        std::cerr << "SMCaptureWorker: invalid codec " << codec.toStdString() << std::endl;
27 jakw 89
 
90
    // Upload patterns to projector/GPU
41 jakw 91
    for(unsigned int i=0; i<algorithm->getNPatterns(); i++){
92
        cv::Mat pattern = algorithm->getEncodingPattern(i);
27 jakw 93
        projector->setPattern(i, pattern.ptr(), pattern.cols, pattern.rows);
94
    }
95
 
96
    delay = settings.value("trigger/delay", 50).toInt();
139 jakw 97
    stackingCalibration = settings.value("stacking/calibration", 1).toInt();
98
    stackingAcquisition= settings.value("stacking/acquisition", 1).toInt();
167 jakw 99
 
100
    setupSuccessful = true;
9 jakw 101
}
102
 
103
 
104
void SMCaptureWorker::doWork(){
105
 
167 jakw 106
    if(!setupSuccessful)
107
        return;
108
 
23 jakw 109
    working = true;
9 jakw 110
 
199 jakw 111
    cv::Mat checkerboard(8, 8, CV_8UC3);
112
    checkerboard.setTo(0);
113
    checkerboard.rowRange(0, 4).colRange(0, 4).setTo(cv::Vec3b(255,255,255));
114
    checkerboard.rowRange(4, 8).colRange(4, 8).setTo(cv::Vec3b(255,255,255));
115
 
9 jakw 116
    // Processing loop
113 jakw 117
//    QTime time;
118
//    time.start();
23 jakw 119
    while(working){
9 jakw 120
 
199 jakw 121
        if(focusingPattern)
122
            projector->displayTexture(checkerboard.ptr(), checkerboard.cols, checkerboard.rows);
123
        else
124
            projector->displayWhite();
27 jakw 125
 
199 jakw 126
 
159 jakw 127
        // prevent image acquisition timeout
207 flgw 128
        QTest::qSleep(100);
134 jakw 129
 
9 jakw 130
        CameraFrame frame;
131
 
23 jakw 132
        // trigger cameras
133
        camera0->trigger();
134
        camera1->trigger();
9 jakw 135
 
113 jakw 136
        // retrieve raw frames
23 jakw 137
        frame = camera0->getFrame();
138
        cv::Mat frameCV;
121 jakw 139
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
23 jakw 140
        frameCV = frameCV.clone();
121 jakw 141
//        cvtools::rshift(frameCV, 8);
142
//        frameCV.convertTo(frameCV, CV_8UC1);
23 jakw 143
        emit newFrame(0, frameCV);
9 jakw 144
 
23 jakw 145
        frame = camera1->getFrame();
121 jakw 146
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
23 jakw 147
        frameCV = frameCV.clone();
121 jakw 148
//        cvtools::rshift(frameCV, 8);
149
//        frameCV.convertTo(frameCV, CV_8UC1);
23 jakw 150
        emit newFrame(1, frameCV);
9 jakw 151
 
23 jakw 152
        //std::cout << "SMCaptureWorker idle " << time.restart() << "ms" << std::endl;
9 jakw 153
 
23 jakw 154
        // Process events e.g. perform a task
9 jakw 155
        QCoreApplication::processEvents();
156
    }
157
 
158
    emit finished();
23 jakw 159
}
9 jakw 160
 
23 jakw 161
void SMCaptureWorker::rotateTo(float angle){
223 flgw 162
    // TODO is this the right check
163
    if(!setupSuccessful || !rotationStage || !rotationStage->Handle)
167 jakw 164
        return;
165
 
223 flgw 166
    rotationStage->moveAbsolute(angle);
92 jakw 167
    while(rotationStage->isMoving()){
168
 
134 jakw 169
        // prevent grab timeout in flycapture
170
        QTest::qSleep(10);
171
 
92 jakw 172
        // trigger cameras
173
        camera0->trigger();
174
        camera1->trigger();
175
 
176
        // retrieve frames
177
        CameraFrame frame;
178
        frame = camera0->getFrame();
179
        cv::Mat frameCV;
121 jakw 180
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
92 jakw 181
        frameCV = frameCV.clone();
182
        emit newFrame(0, frameCV);
183
        frame = camera1->getFrame();
121 jakw 184
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
92 jakw 185
        frameCV = frameCV.clone();
186
        emit newFrame(1, frameCV);
187
    }
188
 
30 jakw 189
    emit rotatedTo(angle);
9 jakw 190
}
191
 
23 jakw 192
void SMCaptureWorker::acquireCalibrationSet(float angle){
223 flgw 193
    if(!setupSuccessful || !rotationStage || !rotationStage->Handle)
167 jakw 194
        return;
195
 
27 jakw 196
    if(angle != -1.0)
197
        rotateTo(angle);
198
 
199 jakw 199
    projector->displayWhite();
200
 
134 jakw 201
    // just for safe measures
202
    QTest::qSleep(500);
203
 
23 jakw 204
    CameraFrame frame;
27 jakw 205
    SMCalibrationSet calibrationSet;
120 jakw 206
    cv::Mat frameCVStacked0(camera0->getFrameHeight(), camera0->getFrameWidth(), CV_32SC1, cv::Scalar(0));
207
    cv::Mat frameCVStacked1(camera1->getFrameHeight(), camera1->getFrameWidth(), CV_32SC1, cv::Scalar(0));
23 jakw 208
 
139 jakw 209
    for(int i=0; i<stackingCalibration; i++){
113 jakw 210
        // trigger cameras
211
        camera0->trigger();
212
        camera1->trigger();
23 jakw 213
 
113 jakw 214
        // retrieve frames
215
        frame = camera0->getFrame();
216
        cv::Mat frameCV;
121 jakw 217
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
113 jakw 218
        frameCV = frameCV.clone();
120 jakw 219
        cv::add(frameCV, frameCVStacked0, frameCVStacked0, cv::noArray(), CV_32SC1);
121 jakw 220
//cvtools::writeMat(frameCV, "frameCV.mat", "frameCV");
221
//cvtools::writeMat(frameCVStacked0, "frameCVStacked0.mat", "frameCVStacked0");
113 jakw 222
        emit newFrame(0, frameCV);
23 jakw 223
 
113 jakw 224
        frame = camera1->getFrame();
121 jakw 225
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
113 jakw 226
        frameCV = frameCV.clone();
120 jakw 227
        cv::add(frameCV, frameCVStacked1, frameCVStacked1, cv::noArray(), CV_32SC1);
23 jakw 228
 
113 jakw 229
        emit newFrame(1, frameCV);
23 jakw 230
 
113 jakw 231
    }
232
 
139 jakw 233
    frameCVStacked0.convertTo(frameCVStacked0, CV_8UC1, 1.0/stackingCalibration);
134 jakw 234
//cvtools::writeMat(frameCVStacked0, "frameCVStacked0a.mat", "frameCVStacked0a");
139 jakw 235
    frameCVStacked1.convertTo(frameCVStacked1, CV_8UC1, 1.0/stackingCalibration);
113 jakw 236
 
237
    calibrationSet.frame0 = frameCVStacked0;
238
    calibrationSet.frame1 = frameCVStacked1;
239
 
27 jakw 240
    calibrationSet.rotationAngle = rotationStage->getAngle();
23 jakw 241
 
242
    emit newCalibrationSet(calibrationSet);
9 jakw 243
}
244
 
30 jakw 245
void SMCaptureWorker::acquireCalibrationSets(std::vector<float> angles){
9 jakw 246
 
167 jakw 247
    if(!setupSuccessful)
248
        return;
249
 
250
    for(unsigned int i=0; i<angles.size(); i++)
30 jakw 251
        acquireCalibrationSet(angles[i]);
252
}
253
 
242 jakw 254
void SMCaptureWorker::acquireFrameSequenceLDR(SMFrameSequence &frameSequence){
27 jakw 255
 
256
    CameraFrame frame;
257
 
41 jakw 258
    for(unsigned int i=0; i<algorithm->getNPatterns(); i++){
27 jakw 259
 
260
        // display pattern
261
        projector->displayPattern(i);
262
 
263
        QTest::qSleep(delay);
264
 
120 jakw 265
        cv::Mat frameCVStacked0(camera0->getFrameHeight(), camera0->getFrameWidth(), CV_32SC1, cv::Scalar(0));
266
        cv::Mat frameCVStacked1(camera1->getFrameHeight(), camera1->getFrameWidth(), CV_32SC1, cv::Scalar(0));
139 jakw 267
        for(int i=0; i<stackingAcquisition; i++){
113 jakw 268
            // trigger cameras
269
            camera0->trigger();
270
            camera1->trigger();
27 jakw 271
 
113 jakw 272
            // retrieve frames
273
            frame = camera0->getFrame();
274
            cv::Mat frameCV;
121 jakw 275
            frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
113 jakw 276
            frameCV = frameCV.clone();
120 jakw 277
            cv::add(frameCV, frameCVStacked0, frameCVStacked0, cv::noArray(), CV_32SC1);
27 jakw 278
 
113 jakw 279
            emit newFrame(0, frameCV);
27 jakw 280
 
113 jakw 281
            frame = camera1->getFrame();
121 jakw 282
            frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
113 jakw 283
            frameCV = frameCV.clone();
120 jakw 284
            cv::add(frameCV, frameCVStacked1, frameCVStacked1, cv::noArray(), CV_32SC1);
27 jakw 285
 
113 jakw 286
            emit newFrame(1, frameCV);
27 jakw 287
 
113 jakw 288
        }
289
 
139 jakw 290
        frameCVStacked0.convertTo(frameCVStacked0, CV_8UC1, 1.0/stackingAcquisition);
291
        frameCVStacked1.convertTo(frameCVStacked1, CV_8UC1, 1.0/stackingAcquisition);
113 jakw 292
 
293
        frameSequence.frames0.push_back(frameCVStacked0);
294
        frameSequence.frames1.push_back(frameCVStacked1);
295
 
27 jakw 296
    }
297
 
242 jakw 298
 
299
}
300
 
301
void SMCaptureWorker::acquireFrameSequenceHDR(SMFrameSequence &frameSequence){
302
 
303
    QSettings settings;
304
    QString shuttersString = settings.value("camera/shuttersHDR").toString();
305
    QStringList list = shuttersString.split("/");
306
    std::vector<float> shutters(list.size());
307
    for(int i=0; i<list.size(); i++)
308
        shutters[i] = list[i].toFloat();
309
    if(shutters.empty()){
310
        std::cerr << "Could not read HDR shutter times" << std::endl;
311
        return;
312
    }
313
 
314
    int nShutters = shutters.size();
315
 
316
    std::vector<SMFrameSequence> frameSequences(nShutters);
317
 
318
    CameraSettings cameraSettings;
319
 
320
    for(int i=0; i<nShutters; i++){
321
 
322
        // Set camera shutter
323
        cameraSettings.shutter = shutters[i];
324
 
325
        // assert that shutter is given in ms
326
        assert(cameraSettings.shutter < 2000.0);
327
 
328
        camera0->setCameraSettings(cameraSettings);
329
        camera1->setCameraSettings(cameraSettings);
330
 
331
        // Project/acquire sequence
332
        acquireFrameSequenceLDR(frameSequences[i]);
333
 
334
    }
335
 
336
    unsigned int nFrames = frameSequences[0].frames0.size();
337
    int nRows = frameSequences[0].frames0[0].rows;
338
    int nCols = frameSequences[0].frames0[0].cols;
339
 
340
    // Merge into HDR
341
    frameSequence.frames0.resize(nFrames);
342
    frameSequence.frames1.resize(nFrames);
343
 
344
    float shutterMean = 0.0;
345
    for(unsigned int i=0; i<shutters.size(); i++)
346
        shutterMean += shutters[i]/shutters.size();
347
 
348
    for(unsigned int i=0; i<nFrames; i++){
349
        frameSequence.frames0[i].create(nRows, nCols, CV_32F);
350
        frameSequence.frames1[i].create(nRows, nCols, CV_32F);
351
 
352
    }
353
 
354
    #pragma omp parallel for
355
    for(int r=0; r<nRows; r++){
356
        for(int c=0; c<nCols; c++){
357
 
358
            for(int j=nShutters-1; j>=0; j--){
359
 
360
                uchar s0 = frameSequences[j].frames0[0].at<uchar>(r,c);
361
 
362
                if(s0 < 250){
363
                    for(unsigned int i=0; i<nFrames; i++)
364
                        frameSequence.frames0[i].at<float>(r,c) = (shutterMean/shutters[j]) * frameSequences[j].frames0[i].at<uchar>(r,c);
365
 
366
                    break;
367
                }
368
            }
369
 
370
            for(int j=nShutters-1; j>=0; j--){
371
 
372
                uchar s1 = frameSequences[j].frames1[0].at<uchar>(r,c);
373
 
374
                if(s1 < 250){
375
                    for(unsigned int i=0; i<nFrames; i++)
376
                        frameSequence.frames1[i].at<float>(r,c) = (shutterMean/shutters[j]) * frameSequences[j].frames1[i].at<uchar>(r,c);
377
 
378
                    break;
379
                }
380
            }
381
        }
382
        //cvtools::writeMat(frame0i, QString("frame0_%1.mat").arg(i).toLatin1(),  QString("frame0_%1").arg(i).toLatin1());
383
    }
384
 
385
    // Set camera shutter back to default
386
    cameraSettings.shutter = settings.value("shutter", 66.666).toFloat();
387
 
388
    camera0->setCameraSettings(cameraSettings);
389
    camera1->setCameraSettings(cameraSettings);
390
 
391
    // TODO: we need to somehow make the debayer function cvtColor accept floating point images...
392
}
393
 
394
 
395
void SMCaptureWorker::acquireFrameSequence(float angle){
396
 
397
    if(!setupSuccessful)
398
        return;
399
 
400
    if(int(angle) != -1.0)
401
        rotateTo(angle);
402
 
403
    SMFrameSequence frameSequence;
404
 
405
    QSettings settings;
406
    if(settings.contains("camera/shuttersHDR"))
407
        acquireFrameSequenceHDR(frameSequence);
408
    else
409
        acquireFrameSequenceLDR(frameSequence);
410
 
411
 
223 flgw 412
    if(rotationStage && rotationStage->Handle)// TODO is this the right check
207 flgw 413
        frameSequence.rotationAngle = rotationStage->getAngle();
414
    else
415
        frameSequence.rotationAngle = 0;
416
 
27 jakw 417
    frameSequence.codec = codec;
418
 
419
    emit newFrameSequence(frameSequence);
420
 
92 jakw 421
    projector->displayWhite();
27 jakw 422
}
423
 
424
 
30 jakw 425
void SMCaptureWorker::acquireFrameSequences(std::vector<float> angles){
23 jakw 426
 
167 jakw 427
    if(!setupSuccessful)
428
        return;
429
 
430
    for(unsigned int i=0; i<angles.size(); i++)
30 jakw 431
        acquireFrameSequence(angles[i]);
432
}
433
 
23 jakw 434
void SMCaptureWorker::abort(){}
435
 
436
void SMCaptureWorker::stopWork(){
437
    working = false;
438
}
439