diff options
-rw-r--r-- | tracker-pt/camera.cpp | 88 | ||||
-rw-r--r-- | tracker-pt/camera.h | 86 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt_dialog.cpp | 10 |
3 files changed, 79 insertions, 105 deletions
diff --git a/tracker-pt/camera.cpp b/tracker-pt/camera.cpp index 82f4a6fe..435348b1 100644 --- a/tracker-pt/camera.cpp +++ b/tracker-pt/camera.cpp @@ -10,7 +10,10 @@ #include <string> #include <QDebug> -Camera::~Camera() {} +Camera::~Camera() +{ + stop(); +} void Camera::set_device(const QString& name) { @@ -18,15 +21,14 @@ void Camera::set_device(const QString& name) desired_name = name; - if (desired_index != index) + if (index != cam_desired.idx || desired_name != active_name) { - desired_index = index; - _set_device_index(); + stop(); + cam_desired.idx = index; // reset fps dt_valid = 0; dt_mean = 0; - active_index = index; } } @@ -35,12 +37,18 @@ QString Camera::get_desired_name() const return desired_name; } +QString Camera::get_active_name() const +{ + return active_name; +} + void Camera::set_fps(int fps) { if (cam_desired.fps != fps) { cam_desired.fps = fps; - _set_fps(); + if (cap) + cap->set(cv::CAP_PROP_FPS, cam_desired.fps); } } @@ -50,16 +58,18 @@ void Camera::set_res(int x_res, int y_res) { cam_desired.res_x = x_res; cam_desired.res_y = y_res; - _set_res(); + if (cap) + { + cap->set(cv::CAP_PROP_FRAME_WIDTH, cam_desired.res_x); + cap->set(cv::CAP_PROP_FRAME_HEIGHT, cam_desired.res_y); + } } } DEFUN_WARN_UNUSED bool Camera::get_info(CamInfo& ret) { if (cam_info.res_x == 0 || cam_info.res_y == 0) - { return false; - } ret = cam_info; return true; } @@ -68,7 +78,7 @@ bool Camera::get_frame(double dt, cv::Mat* frame) { bool new_frame = _get_frame(frame); // measure fps of valid frames - static constexpr double RC = 1; // second + static constexpr double RC = 1; // seconds const double alpha = dt/(dt + RC); dt_valid += dt; if (new_frame) @@ -85,40 +95,33 @@ bool Camera::get_frame(double dt, cv::Mat* frame) return new_frame; } -void CVCamera::start() +void Camera::start() { - stop(); - cap = new cv::VideoCapture(desired_index); - _set_res(); - _set_fps(); - // extract camera info + cap = camera_ptr(new cv::VideoCapture(cam_desired.idx)); + + set_res(cam_desired.res_x, cam_desired.res_y); + set_fps(cam_desired.fps); + if (cap->isOpened()) { - active_index = desired_index; + cam_info.idx = cam_desired.idx; cam_info.res_x = 0; cam_info.res_y = 0; - } else { - stop(); + active_name = desired_name; } + else + stop(); } -void CVCamera::stop() +void Camera::stop() { - if (cap) - { - const bool opened = cap->isOpened(); - if (opened) - { - qDebug() << "pt: freeing camera"; - cap->release(); - } - delete cap; - cap = nullptr; - qDebug() << "pt camera: stopped"; - } + cap = nullptr; + desired_name = QString(); + active_name = QString(); + cam_info = CamInfo(); } -bool CVCamera::_get_frame(cv::Mat* frame) +bool Camera::_get_frame(cv::Mat* frame) { if (cap && cap->isOpened()) { @@ -134,22 +137,3 @@ bool CVCamera::_get_frame(cv::Mat* frame) } return false; } - -void CVCamera::_set_fps() -{ - if (cap) cap->set(cv::CAP_PROP_FPS, cam_desired.fps); -} - -void CVCamera::_set_res() -{ - if (cap) - { - cap->set(cv::CAP_PROP_FRAME_WIDTH, cam_desired.res_x); - cap->set(cv::CAP_PROP_FRAME_HEIGHT, cam_desired.res_y); - } -} -void CVCamera::_set_device_index() -{ - if (desired_index != active_index) - stop(); -} diff --git a/tracker-pt/camera.h b/tracker-pt/camera.h index be7d35c4..75c5faa4 100644 --- a/tracker-pt/camera.h +++ b/tracker-pt/camera.h @@ -17,24 +17,22 @@ struct CamInfo { - CamInfo() : res_x(0), res_y(0), fps(0) {} + CamInfo() : res_x(0), res_y(0), fps(0), idx(-1) {} int res_x; int res_y; int fps; + int idx; }; -// ---------------------------------------------------------------------------- -// Base class for cameras, calculates the frame rate -class Camera +class Camera final { public: - Camera() : dt_valid(0), dt_mean(0), desired_index(0), active_index(-1) {} - virtual ~Camera() = 0; + Camera() : dt_valid(0), dt_mean(0) {} + ~Camera(); - // start/stop capturing - virtual void start() = 0; - virtual void stop() = 0; + void start(); + void stop(); void restart() { stop(); start(); } // calls corresponding template methods and reinitializes frame rate calculation @@ -42,56 +40,44 @@ public: void set_fps(int fps); void set_res(int x_res, int y_res); - // gets a frame from the camera, dt: time since last call in seconds DEFUN_WARN_UNUSED bool get_frame(double dt, cv::Mat* frame); - - // WARNING: returned references are valid as long as object DEFUN_WARN_UNUSED bool get_info(CamInfo &ret); + CamInfo get_desired() const { return cam_desired; } QString get_desired_name() const; -protected: - // get a frame from the camera - DEFUN_WARN_UNUSED virtual bool _get_frame(cv::Mat* frame) = 0; - - // update the camera using cam_desired, write res and f to cam_info if successful - virtual void _set_device_index() = 0; - virtual void _set_fps() = 0; - virtual void _set_res() = 0; + QString get_active_name() const; + + cv::VideoCapture& operator*() { return *cap; } + const cv::VideoCapture& operator*() const { return *cap; } + cv::VideoCapture* operator->() { return cap.get(); } + const cv::VideoCapture* operator->() const { return cap.get(); } + operator bool() const { return cap && cap->isOpened(); } + private: + DEFUN_WARN_UNUSED bool _get_frame(cv::Mat* frame); + double dt_valid; double dt_mean; -protected: + CamInfo cam_info; CamInfo cam_desired; - QString desired_name; - int desired_index; - int active_index; -}; + QString desired_name, active_name; -// ---------------------------------------------------------------------------- -// camera based on OpenCV's videoCapture -class CVCamera final : public Camera -{ -public: - CVCamera() : cap(NULL) {} - ~CVCamera() { stop(); } - - void start() override; - void stop() override; - - operator cv::VideoCapture*() { return cap; } -protected: - bool _get_frame(cv::Mat* frame) override; - void _set_fps() override; - void _set_res() override; - void _set_device_index() override; -private: - cv::VideoCapture* cap; -}; + struct camera_deleter final + { + void operator()(cv::VideoCapture* cap) + { + if (cap) + { + if (cap->isOpened()) + cap->release(); + static const std::default_delete<cv::VideoCapture> deleter; + deleter(cap); + } + } + }; -enum RotationType -{ - CLOCKWISE = 0, - ZERO = 1, - COUNTER_CLOCKWISE = 2 + using camera_ptr = std::unique_ptr<cv::VideoCapture, camera_deleter>; + + std::unique_ptr<cv::VideoCapture, camera_deleter> cap; }; diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.cpp b/tracker-pt/ftnoir_tracker_pt_dialog.cpp index 749ea1ff..d3951bd9 100644 --- a/tracker-pt/ftnoir_tracker_pt_dialog.cpp +++ b/tracker-pt/ftnoir_tracker_pt_dialog.cpp @@ -142,12 +142,16 @@ void TrackerDialog_PT::set_camera_settings_available(const QString& camera_name) void TrackerDialog_PT::show_camera_settings() { const int idx = ui.camdevice_combo->currentIndex(); + if (tracker) { - cv::VideoCapture* cap = tracker->camera; - if (cap && cap->isOpened()) + if (tracker->camera) { - video_property_page::show_from_capture(*cap, idx); + cv::VideoCapture& cap = *tracker->camera; + + CamInfo info; + if (tracker->camera.get_info(info)) + video_property_page::show_from_capture(cap, info.idx); } } else |