diff options
Diffstat (limited to 'tracker-pt')
-rw-r--r-- | tracker-pt/module/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tracker-pt/module/camera_kinect_ir.cpp | 182 | ||||
-rw-r--r-- | tracker-pt/module/camera_kinect_ir.h | 70 | ||||
-rw-r--r-- | tracker-pt/module/module.cpp | 47 |
4 files changed, 297 insertions, 4 deletions
diff --git a/tracker-pt/module/CMakeLists.txt b/tracker-pt/module/CMakeLists.txt index 22b725c9..72d985c6 100644 --- a/tracker-pt/module/CMakeLists.txt +++ b/tracker-pt/module/CMakeLists.txt @@ -3,4 +3,6 @@ if(OpenCV_FOUND) otr_module(tracker-pt) target_link_libraries(${self} opentrack-tracker-pt-base) target_include_directories(${self} PUBLIC "${CMAKE_SOURCE_DIR}/tracker-pt") + # Add Kinect dependency if available + otr_kinect_setup() endif() diff --git a/tracker-pt/module/camera_kinect_ir.cpp b/tracker-pt/module/camera_kinect_ir.cpp new file mode 100644 index 00000000..ea5d2591 --- /dev/null +++ b/tracker-pt/module/camera_kinect_ir.cpp @@ -0,0 +1,182 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "camera_kinect_ir.h" +#include "frame.hpp" + +#include "compat/sleep.hpp" +#include "compat/camera-names.hpp" +#include "compat/math-imports.hpp" + +#include <opencv2/imgproc.hpp> + +#include "cv/video-property-page.hpp" + +#include <cstdlib> + +namespace pt_module { + +CameraKinectIr::CameraKinectIr(const QString& module_name) : s { module_name } +{ +} + +QString CameraKinectIr::get_desired_name() const +{ + return desired_name; +} + +QString CameraKinectIr::get_active_name() const +{ + return active_name; +} + +void CameraKinectIr::show_camera_settings() +{ + const int idx = camera_name_to_index(s.camera_name); + + if (cap && cap->isOpened()) + video_property_page::show_from_capture(*cap, idx); + else + video_property_page::show(idx); +} + +CameraKinectIr::result CameraKinectIr::get_info() const +{ + if (cam_info.res_x == 0 || cam_info.res_y == 0) + return { false, pt_camera_info() }; + else + return { true, cam_info }; +} + +CameraKinectIr::result CameraKinectIr::get_frame(pt_frame& frame_) +{ + cv::Mat& frame = frame_.as<Frame>()->mat; + + const bool new_frame = get_frame_(frame); + + if (new_frame) + { + const f dt = (f)t.elapsed_seconds(); + t.start(); + + // measure fps of valid frames + constexpr f RC = f{1}/10; // seconds + const f alpha = dt/(dt + RC); + + if (dt_mean < dt_eps) + dt_mean = dt; + else + dt_mean = (1-alpha) * dt_mean + alpha * dt; + + cam_info.fps = dt_mean > dt_eps ? 1 / dt_mean : 0; + cam_info.res_x = frame.cols; + cam_info.res_y = frame.rows; + cam_info.fov = fov; + + return { true, cam_info }; + } + else + return { false, {} }; +} + +bool CameraKinectIr::start(int idx, int fps, int res_x, int res_y) +{ + + if (idx >= 0 && fps >= 0 && res_x >= 0 && res_y >= 0) + { + if (cam_desired.idx != idx || + (int)cam_desired.fps != fps || + cam_desired.res_x != res_x || + cam_desired.res_y != res_y || + !cap || !cap->isOpened() || !cap->grab()) + { + stop(); + + desired_name = get_camera_names().value(idx); + bool kinectIRSensor = false; + if (desired_name.compare(KKinectIRSensor) == 0) + { + kinectIRSensor = true; + } + cam_desired.idx = idx; + cam_desired.fps = fps; + cam_desired.res_x = res_x; + cam_desired.res_y = res_y; + cam_desired.fov = fov; + + cap = camera_ptr(new cv::VideoCapture(idx)); + + if (cam_desired.res_x > 0 && cam_desired.res_y > 0) + { + cap->set(cv::CAP_PROP_FRAME_WIDTH, res_x); + cap->set(cv::CAP_PROP_FRAME_HEIGHT, res_y); + } + + if (fps > 0) + cap->set(cv::CAP_PROP_FPS, fps); + + if (cap->isOpened()) + { + cam_info = pt_camera_info(); + cam_info.idx = idx; + dt_mean = 0; + active_name = desired_name; + + cv::Mat tmp; + + if (get_frame_(tmp)) + { + t.start(); + return true; + } + } + + cap = nullptr; + return false; + } + + return true; + } + + stop(); + return false; +} + +void CameraKinectIr::stop() +{ + cap = nullptr; + desired_name = QString{}; + active_name = QString{}; + cam_info = {}; + cam_desired = {}; +} + +bool CameraKinectIr::get_frame_(cv::Mat& frame) +{ + if (cap && cap->isOpened()) + { + for (unsigned i = 0; i < 10; i++) + { + if (cap->read(frame)) + return true; + portable::sleep(50); + } + } + return false; +} + +void CameraKinectIr::camera_deleter::operator()(cv::VideoCapture* cap) +{ + if (cap) + { + if (cap->isOpened()) + cap->release(); + delete cap; + } +} + +} // ns pt_module diff --git a/tracker-pt/module/camera_kinect_ir.h b/tracker-pt/module/camera_kinect_ir.h new file mode 100644 index 00000000..93c3d75b --- /dev/null +++ b/tracker-pt/module/camera_kinect_ir.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#if __has_include(<Kinect.h>) + +#include "pt-api.hpp" +#include "compat/timer.hpp" + +#include <memory> + +#include <opencv2/core.hpp> +#include <opencv2/videoio.hpp> + +#include <QString> + +namespace pt_module { + +/// +/// Implement our camera interface using Kinect V2 SDK IR Sensor. +/// +struct CameraKinectIr final : pt_camera +{ + CameraKinectIr(const QString& module_name); + + bool start(int idx, int fps, int res_x, int res_y) override; + void stop() override; + + result get_frame(pt_frame& Frame) override; + result get_info() const override; + + pt_camera_info get_desired() const override { return cam_desired; } + QString get_desired_name() const override; + QString get_active_name() const override; + + void set_fov(f value) override { fov = value; } + void show_camera_settings() override; + +private: + [[nodiscard]] bool get_frame_(cv::Mat& frame); + + f dt_mean = 0, fov = 30; + Timer t; + pt_camera_info cam_info; + pt_camera_info cam_desired; + QString desired_name, active_name; + + struct camera_deleter final + { + void operator()(cv::VideoCapture* cap); + }; + + using camera_ptr = std::unique_ptr<cv::VideoCapture, camera_deleter>; + + camera_ptr cap; + + pt_settings s; + + static constexpr f dt_eps = f{1}/256; +}; + +} // ns pt_module + + +#endif diff --git a/tracker-pt/module/module.cpp b/tracker-pt/module/module.cpp index db3e8fac..c3b417a7 100644 --- a/tracker-pt/module/module.cpp +++ b/tracker-pt/module/module.cpp @@ -2,6 +2,7 @@ #include "module.hpp" #include "camera.h" +#include "camera_kinect_ir.h" #include "compat/camera-names.hpp" #include "frame.hpp" #include "point_extractor.h" @@ -19,7 +20,9 @@ static const QString module_name = "tracker-pt"; namespace pt_module { -// Traits for OpenCV VideoCapture camera +/// +/// Traits for OpenCV VideoCapture camera +/// struct pt_module_traits final : pt_runtime_traits { pointer<pt_camera> make_camera() const override @@ -48,6 +51,41 @@ struct pt_module_traits final : pt_runtime_traits } }; +#if __has_include(<Kinect.h>) +/// +/// Traits for Kinect V2 IR Sensor +/// +struct KinectIrTraits final : pt_runtime_traits +{ + pointer<pt_camera> make_camera() const override + { + return pointer<pt_camera>(new CameraKinectIr(module_name)); + } + + pointer<pt_point_extractor> make_point_extractor() const override + { + return pointer<pt_point_extractor>(new PointExtractor(module_name)); + } + + QString get_module_name() const override + { + return module_name; + } + + pointer<pt_frame> make_frame() const override + { + return pointer<pt_frame>(new Frame); + } + + pointer<pt_preview> make_preview(int w, int h) const override + { + return pointer<pt_preview>(new Preview(w, h)); + } +}; +#endif + + + struct tracker_pt : Tracker_PT { tracker_pt() : Tracker_PT(module_name) @@ -56,13 +94,14 @@ struct tracker_pt : Tracker_PT pointer<pt_runtime_traits> create_traits() override { - // Create different traits according to settings +#if __has_include(<Kinect.h>) + // Create Kinect traits according to settings if (s.camera_name().compare(KKinectIRSensor) == 0) { // Use Kinect IR trait - return pointer<pt_runtime_traits>(new pt_module_traits); + return pointer<pt_runtime_traits>(new KinectIrTraits); } - +#endif return pointer<pt_runtime_traits>(new pt_module_traits); } |