Subversion Repositories seema-scanner

Rev

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

#include "SMCaptureWorker.h"

#include "AlgorithmGrayCode.h"
#include "AlgorithmGrayCodeHorzVert.h"
#include "AlgorithmPhaseShiftTwoFreq.h"
#include "AlgorithmPhaseShiftThreeFreq.h"
#include "AlgorithmLineShift.h"

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

#include "cvtools.h"

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 = CameraFactory::NewCamera(iNum0,cNum0,triggerModeSoftware);

    int iNum1 = settings.value("camera1/interfaceNumber", 0).toInt();
    int cNum1 = settings.value("camera1/cameraNumber", 1).toInt();
    if(iNum1 != -1)
        camera1 = CameraFactory::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);

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

    // Create Algorithm
    unsigned int screenCols, screenRows;
    projector->getScreenRes(&screenCols, &screenRows);
    codec = settings.value("algorithm", "GrayCode").toString();
    if(codec == "GrayCode")
        algorithm = new AlgorithmGrayCode(screenCols, screenRows);
    else if(codec == "GrayCodeHorzVert")
        algorithm = new AlgorithmGrayCodeHorzVert(screenCols, screenRows);
    else if(codec == "PhaseShiftTwoFreq")
        algorithm = new AlgorithmPhaseShiftTwoFreq(screenCols, screenRows);
    else if(codec == "PhaseShiftThreeFreq")
        algorithm = new AlgorithmPhaseShiftThreeFreq(screenCols, screenRows);
    else if(codec == "LineShift")
        algorithm = new AlgorithmLineShift(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();
    stackingCalibration = settings.value("stacking/calibration", 1).toInt();
    stackingAcquisition= settings.value("stacking/acquisition", 1).toInt();
}


void SMCaptureWorker::doWork(){

    working = true;

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

        projector->displayWhite();

        // prevent image acquisition timeout
        QTest::qSleep(10);

        CameraFrame frame;

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

        // retrieve raw frames
        frame = camera0->getFrame();
        cv::Mat frameCV;
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
//        cvtools::rshift(frameCV, 8);
//        frameCV.convertTo(frameCV, CV_8UC1);
        emit newFrame(0, frameCV);

        frame = camera1->getFrame();
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
//        cvtools::rshift(frameCV, 8);
//        frameCV.convertTo(frameCV, CV_8UC1);
        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){

    rotationStage->moveAbsolute(angle);

    while(rotationStage->isMoving()){

        // prevent grab timeout in flycapture
        QTest::qSleep(10);

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

        // retrieve frames
        CameraFrame frame;
        frame = camera0->getFrame();
        cv::Mat frameCV;
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
        emit newFrame(0, frameCV);
        frame = camera1->getFrame();
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
        emit newFrame(1, frameCV);
    }

    emit rotatedTo(angle);
}

void SMCaptureWorker::acquireCalibrationSet(float angle){

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

    // just for safe measures
    QTest::qSleep(500);

    CameraFrame frame;
    SMCalibrationSet calibrationSet;
    cv::Mat frameCVStacked0(camera0->getFrameHeight(), camera0->getFrameWidth(), CV_32SC1, cv::Scalar(0));
    cv::Mat frameCVStacked1(camera1->getFrameHeight(), camera1->getFrameWidth(), CV_32SC1, cv::Scalar(0));

    for(int i=0; i<stackingCalibration; i++){
        // trigger cameras
        camera0->trigger();
        camera1->trigger();

        // retrieve frames
        frame = camera0->getFrame();
        cv::Mat frameCV;
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
        cv::add(frameCV, frameCVStacked0, frameCVStacked0, cv::noArray(), CV_32SC1);
//cvtools::writeMat(frameCV, "frameCV.mat", "frameCV");
//cvtools::writeMat(frameCVStacked0, "frameCVStacked0.mat", "frameCVStacked0");
        emit newFrame(0, frameCV);

        frame = camera1->getFrame();
        frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
        frameCV = frameCV.clone();
        cv::add(frameCV, frameCVStacked1, frameCVStacked1, cv::noArray(), CV_32SC1);

        emit newFrame(1, frameCV);

    }

    frameCVStacked0.convertTo(frameCVStacked0, CV_8UC1, 1.0/stackingCalibration);
//cvtools::writeMat(frameCVStacked0, "frameCVStacked0a.mat", "frameCVStacked0a");
    frameCVStacked1.convertTo(frameCVStacked1, CV_8UC1, 1.0/stackingCalibration);

    calibrationSet.frame0 = frameCVStacked0;
    calibrationSet.frame1 = frameCVStacked1;

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

        cv::Mat frameCVStacked0(camera0->getFrameHeight(), camera0->getFrameWidth(), CV_32SC1, cv::Scalar(0));
        cv::Mat frameCVStacked1(camera1->getFrameHeight(), camera1->getFrameWidth(), CV_32SC1, cv::Scalar(0));
        for(int i=0; i<stackingAcquisition; i++){
            // trigger cameras
            camera0->trigger();
            camera1->trigger();

            // retrieve frames
            frame = camera0->getFrame();
            cv::Mat frameCV;
            frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
            frameCV = frameCV.clone();
            cv::add(frameCV, frameCVStacked0, frameCVStacked0, cv::noArray(), CV_32SC1);

            emit newFrame(0, frameCV);

            frame = camera1->getFrame();
            frameCV  = cv::Mat(frame.height, frame.width, CV_8UC1, frame.memory);
            frameCV = frameCV.clone();
            cv::add(frameCV, frameCVStacked1, frameCVStacked1, cv::noArray(), CV_32SC1);

            emit newFrame(1, frameCV);

        }

        frameCVStacked0.convertTo(frameCVStacked0, CV_8UC1, 1.0/stackingAcquisition);
        frameCVStacked1.convertTo(frameCVStacked1, CV_8UC1, 1.0/stackingAcquisition);

        frameSequence.frames0.push_back(frameCVStacked0);
        frameSequence.frames1.push_back(frameCVStacked1);

    }

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

    emit newFrameSequence(frameSequence);

    projector->displayWhite();
}


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;
}