diff options
Diffstat (limited to 'tracker-ht/ftnoir_tracker_ht.cpp')
| -rw-r--r-- | tracker-ht/ftnoir_tracker_ht.cpp | 225 | 
1 files changed, 225 insertions, 0 deletions
diff --git a/tracker-ht/ftnoir_tracker_ht.cpp b/tracker-ht/ftnoir_tracker_ht.cpp new file mode 100644 index 00000000..cc9d2ba1 --- /dev/null +++ b/tracker-ht/ftnoir_tracker_ht.cpp @@ -0,0 +1,225 @@ +#include "headtracker-ftnoir.h" +#include "ftnoir_tracker_ht.h" +#include "ui_ht-trackercontrols.h" +#include "opentrack/plugin-api.hpp" +#include <cmath> +#include "opentrack/camera-names.hpp" +#include "opentrack-compat/sleep.hpp" + +typedef struct { +	int width; +	int height; +} resolution_tuple; + +static resolution_tuple resolution_choices[] = { +	{ 640, 480 }, +	{ 320, 240 }, +	{ 320, 200 }, +	{ 0, 0 } +}; + +void Tracker::load_settings(ht_config_t* config) +{ +    int nframes = 0; +    switch (static_cast<int>(s.fps)) +    { +    default: +    case 0: +        nframes = 0; +        break; +    case 1: +        nframes = 30; +        break; +    case 2: +        nframes = 60; +        break; +    case 3: +        nframes = 120; +        break; +    case 4: +        nframes = 180; +        break; +    } + +    config->classification_delay = 500; +    config->field_of_view = s.fov; +    config->max_keypoints = 150; +    config->keypoint_distance = 3.5; +    config->force_fps = nframes; +    config->camera_index = camera_name_to_index(s.camera_name); + +    config->ransac_max_reprojection_error = 25; +    config->ransac_max_inlier_error = config->ransac_max_reprojection_error; + +    config->pyrlk_pyramids = 0; +    config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21; + +    config->ransac_max_mean_error = 999; +    config->ransac_abs_max_mean_error = 999; + +    config->debug = 1; +    config->ransac_min_features = 0.95; +    config->ransac_num_iters = 300; + +    int res = s.resolution; +    if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple))) +		res = 0; +	resolution_tuple r = resolution_choices[res]; +	config->force_width = r.width; +    config->force_height = r.height; +    config->flandmark_delay = 50; +    for (int i = 0; i < 5; i++) +        config->dist_coeffs[i] = 0; +} + +Tracker::Tracker() : +    ht(nullptr), +    ypr {0,0,0, 0,0,0}, +    videoWidget(nullptr), +    layout(nullptr), +    should_stop(false) +{ +} + +Tracker::~Tracker() +{ +    should_stop = true; +    wait(); +    ht_free_context(ht); +	if (layout) +		delete layout; +	if (videoWidget) +		delete videoWidget; +} + +void Tracker::start_tracker(QFrame* videoframe) +{ +    videoframe->show(); +    videoWidget = new HTVideoWidget(videoframe); +    QHBoxLayout* layout = new QHBoxLayout(); +    layout->setContentsMargins(0, 0, 0, 0); +    layout->addWidget(videoWidget); +    if (videoframe->layout()) +        delete videoframe->layout(); +    videoframe->setLayout(layout); +    videoWidget->show(); +    this->layout = layout; + +    load_settings(&conf); +    ht = ht_make_context(&conf, nullptr); +    start(); +} + +void Tracker::run() +{ +    while (!should_stop) +    { +        ht_result_t euler; +        euler.filled = false; +        { +            QMutexLocker l(&camera_mtx); + +            if (!ht_cycle(ht, &euler)) +                break; +        } +        if (euler.filled) +        { +            QMutexLocker l(&ypr_mtx); +            ypr[TX] = euler.tx; +            ypr[TY] = euler.ty; +            ypr[TZ] = euler.tz; +            ypr[Yaw] = euler.rotx; +            ypr[Pitch] = euler.roty; +            ypr[Roll] = euler.rotz; +        } +        { +            const cv::Mat frame_ = ht_get_bgr_frame(ht); +            if (frame_.cols <= HT_MAX_VIDEO_WIDTH && frame_.rows <= HT_MAX_VIDEO_HEIGHT && frame_.channels() <= HT_MAX_VIDEO_CHANNELS) +            { +                QMutexLocker l(&frame_mtx); + +                const int cols = frame_.cols; +                const int rows = frame_.rows; +                const int pitch = cols * 3; +                for (int y = 0; y < rows; y++) +                { +                    for (int x = 0; x < cols; x++) +                    { +                        unsigned char* dest = &frame.frame[y * pitch + 3 * x]; +                        const cv::Vec3b& elt = frame_.at<cv::Vec3b>(y, x); +                        const cv::Scalar elt2 = static_cast<cv::Scalar>(elt); +                        dest[0] = elt2.val[0]; +                        dest[1] = elt2.val[1]; +                        dest[2] = elt2.val[2]; +                    } +                } +                frame.channels = frame_.channels(); +                frame.width = frame_.cols; +                frame.height = frame_.rows; +            } +        } +    } +    // give opencv time to exit camera threads, etc. +    portable::sleep(500); +} + +void Tracker::data(double* data) +{ +    { +        QMutexLocker l(&frame_mtx); + +        if (frame.width > 0) +        { +            videoWidget->update_image(frame.frame, frame.width, frame.height); +            frame.width = 0; +        } +    } + +    { +        QMutexLocker l(&ypr_mtx); + +        for (int i = 0; i < 6; i++) +            data[i] = ypr[i]; +    } +} + +TrackerControls::TrackerControls() : tracker(nullptr) +{ +	ui.setupUi(this); +    ui.cameraName->clear(); +    QList<QString> names = get_camera_names(); +    names.prepend("Any available"); +    ui.cameraName->addItems(names); +    tie_setting(s.camera_name, ui.cameraName); +    tie_setting(s.fps, ui.cameraFPS); +    tie_setting(s.fov, ui.cameraFOV); +    tie_setting(s.resolution, ui.resolution); +    connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); +    connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); +    connect(ui.camera_settings, SIGNAL(pressed()), this, SLOT(camera_settings())); +} + +void TrackerControls::doOK() +{ +    s.b->save(); +	this->close(); +} + +void TrackerControls::doCancel() +{ +    s.b->reload(); +    this->close(); +} + +void TrackerControls::camera_settings() +{ +    if (tracker) +    { +        cv::VideoCapture* cap = ht_capture(tracker->ht); +        open_camera_settings(cap, s.camera_name, &tracker->camera_mtx); +    } +    else +        open_camera_settings(nullptr, s.camera_name, nullptr); +} + +OPENTRACK_DECLARE_TRACKER(Tracker, TrackerControls, TrackerDll)  | 
