Subversion Repositories seema-scanner

Rev

Rev 71 | Rev 97 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "SMCaptureWorker.h"

#include "AlgorithmGrayCode.h"
#include "AlgorithmPhaseShift.h"

#include <QCoreApplication>
#include <QTime>
#include <QSettings>
#include <QtTest/QTest>

void SMCaptureWorker::setup(){

    QSettings settings;

    // Create cameras
    int iNum0 = settings.value("camera0/interfaceNumber", 0).toInt();
    int cNum0 = settings.value("camera0/cameraNumber", 0).toInt();
    if(iNum0 != -1)
        camera0 = Camera::NewCamera(iNum0,cNum0,triggerModeSoftware);

    int iNum1 = settings.value("camera1/interfaceNumber", 0).toInt();
    int cNum1 = settings.value("camera1/cameraNumber", 1).toInt();
    if(iNum1 != -1)
        camera1 = Camera::NewCamera(iNum1,cNum1,triggerModeSoftware);

    // Set camera settings
    CameraSettings cameraSettings;
    cameraSettings.shutter = settings.value("camera/shutter", 16.666).toFloat();
    cameraSettings.gain = 0.0;

    camera0->setCameraSettings(cameraSettings);
    camera1->setCameraSettings(cameraSettings);

    // Start capturing
    camera0->startCapture();
    camera1->startCapture();

    // Create projector
    int screenNum = settings.value("projector/screenNumber", 1).toInt();
    if(screenNum != -1)
        projector = new ProjectorOpenGL(screenNum);

    unsigned int screenCols, screenRows;
    projector->getScreenRes(&screenCols, &screenRows);

    // Create rotation stage
    rotationStage = new RotationStage();

    // Create Algorithm
    codec = settings.value("algorithm", "GrayCode").toString();
    if(codec == "GrayCode")
        algorithm = new AlgorithmGrayCode(screenCols, screenRows);
    else if(codec == "PhaseShift")
        algorithm = new AlgorithmPhaseShift(screenCols, screenRows);
    else
        std::cerr << "SMCaptureWorker: invalid codec " << codec.toStdString() << std::endl;


    // Upload patterns to projector/GPU
    for(unsigned int i=0; i<algorithm->getNPatterns(); i++){
        cv::Mat pattern = algorithm->getEncodingPattern(i);
        projector->setPattern(i, pattern.ptr(), pattern.cols, pattern.rows);
    }

    delay = settings.value("trigger/delay", 50).toInt();
}


void SMCaptureWorker::doWork(){

    working = true;

    // Processing loop
    QTime time;
    time.start();
    while(working){

        projector->displayWhite();

        std::vector<cv::Mat> frameSet;

        CameraFrame frame;

        // trigger cameras
        camera0->trigger();
        camera1->trigger();

        // retrieve frames
        frame = camera0->getFrame();
        cv::Mat frameCV;
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
        frameCV = frameCV.clone();
        frameSet.push_back(frameCV);

        emit newFrame(0, frameCV);

        frame = camera1->getFrame();
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
        frameCV = frameCV.clone();
        frameSet.push_back(frameCV);

        emit newFrame(1, frameCV);

        //std::cout << "SMCaptureWorker idle " << time.restart() << "ms" << std::endl;

        // Process events e.g. perform a task
        QCoreApplication::processEvents();
    }

    emit finished();
}

void SMCaptureWorker::rotateTo(float angle){

    //std::cout << "Moving to: " << angle << std::endl;
    rotationStage->moveAbsolute(angle);
    rotationStage->wait();

    emit rotatedTo(angle);
}

void SMCaptureWorker::acquireCalibrationSet(float angle){

    if(angle != -1.0)
        rotateTo(angle);

    CameraFrame frame;
    SMCalibrationSet calibrationSet;

    // trigger cameras
    camera0->trigger();
    camera1->trigger();

    // retrieve frames
    frame = camera0->getFrame();
    cv::Mat frameCV;
    frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
    frameCV = frameCV.clone();

    emit newFrame(0, frameCV);
    calibrationSet.frame0 = frameCV;

    frame = camera1->getFrame();
    frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
    frameCV = frameCV.clone();

    emit newFrame(1, frameCV);
    calibrationSet.frame1 = frameCV;

    calibrationSet.rotationAngle = rotationStage->getAngle();

    emit newCalibrationSet(calibrationSet);
}

void SMCaptureWorker::acquireCalibrationSets(std::vector<float> angles){

    for(int i=0; i<angles.size(); i++)
        acquireCalibrationSet(angles[i]);
}

void SMCaptureWorker::acquireFrameSequence(float angle){

    if(angle != -1.0)
        rotateTo(angle);

    CameraFrame frame;

    SMFrameSequence frameSequence;

    for(unsigned int i=0; i<algorithm->getNPatterns(); i++){

        // display pattern
        projector->displayPattern(i);

        QTest::qSleep(delay);

        // trigger cameras
        camera0->trigger();
        camera1->trigger();

        // retrieve frames
        frame = camera0->getFrame();
        cv::Mat frameCV;
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
        frameCV = frameCV.clone();

        emit newFrame(0, frameCV);
        frameSequence.frames0.push_back(frameCV);

        frame = camera1->getFrame();
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC3, frame.memory);
        frameCV = frameCV.clone();

        emit newFrame(1, frameCV);
        frameSequence.frames1.push_back(frameCV);

    }

    frameSequence.rotationAngle = rotationStage->getAngle();
    frameSequence.codec = codec;

    emit newFrameSequence(frameSequence);

}


void SMCaptureWorker::acquireFrameSequences(std::vector<float> angles){

    for(int i=0; i<angles.size(); i++)
        acquireFrameSequence(angles[i]);
}

void SMCaptureWorker::abort(){}

void SMCaptureWorker::stopWork(){
    working = false;
}

SMCaptureWorker::~SMCaptureWorker(){
    delete projector;
//    delete camera0;
//    delete camera1;
    delete rotationStage;
}