diff options
-rw-r--r-- | cv/video-widget.cpp | 54 | ||||
-rw-r--r-- | cv/video-widget.hpp | 13 | ||||
-rw-r--r-- | tracker-pt/camera.cpp | 11 | ||||
-rw-r--r-- | tracker-pt/camera.h | 17 | ||||
-rw-r--r-- | tracker-pt/frame.cpp | 85 | ||||
-rw-r--r-- | tracker-pt/frame.hpp | 36 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt.cpp | 39 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt.h | 8 | ||||
-rw-r--r-- | tracker-pt/module.cpp | 29 | ||||
-rw-r--r-- | tracker-pt/point_extractor.cpp | 25 | ||||
-rw-r--r-- | tracker-pt/point_extractor.h | 5 | ||||
-rw-r--r-- | tracker-pt/point_tracker.h | 6 | ||||
-rw-r--r-- | tracker-pt/pt-api.cpp | 19 | ||||
-rw-r--r-- | tracker-pt/pt-api.hpp | 46 |
14 files changed, 307 insertions, 86 deletions
diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index bad81905..4c9a73e6 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -9,11 +9,13 @@ #include "video-widget.hpp" #include "compat/check-visible.hpp" +#include "compat/util.hpp" + +#include <cstring> + #include <opencv2/imgproc.hpp> -cv_video_widget::cv_video_widget(QWidget* parent) : QWidget(parent), - mtx(QMutex::Recursive), - freshp(false) +cv_video_widget::cv_video_widget(QWidget* parent) : QWidget(parent) { connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()), Qt::DirectConnection); timer.start(65); @@ -25,9 +27,7 @@ void cv_video_widget::update_image(const cv::Mat& frame) if (!freshp) { - const int w = preview_size.width(), h = preview_size.height(); - - if (w < 1 || h < 1) + if (width < 1 || height < 1) return; if (_frame.cols != frame.cols || _frame.rows != frame.rows) @@ -38,28 +38,50 @@ void cv_video_widget::update_image(const cv::Mat& frame) if (_frame2.cols != _frame.cols || _frame2.rows != _frame.rows) _frame2 = cv::Mat(_frame.rows, _frame.cols, CV_8UC4); - if (_frame3.cols != w || _frame3.rows != h) - _frame3 = cv::Mat(h, w, CV_8UC4); + if (_frame3.cols != width || _frame3.rows != height) + _frame3 = cv::Mat(height, width, CV_8UC4); cv::cvtColor(_frame, _frame2, cv::COLOR_BGR2BGRA); - const cv::Mat* img_; + const cv::Mat* img; - if (_frame.cols != w || _frame.rows != h) + if (_frame.cols != width || _frame.rows != height) { - cv::resize(_frame2, _frame3, cv::Size(w, h), 0, 0, cv::INTER_NEAREST); + cv::resize(_frame2, _frame3, cv::Size(width, height), 0, 0, cv::INTER_NEAREST); - img_ = &_frame3; + img = &_frame3; } else - img_ = &_frame2; + img = &_frame2; + + const unsigned nbytes = 4 * img->rows * img->cols; + + vec.resize(nbytes); - const cv::Mat& img = *img_; + std::memcpy(vec.data(), img->data, nbytes); - texture = QImage((const unsigned char*) img.data, w, h, QImage::Format_ARGB32); + texture = QImage((const unsigned char*) vec.data(), width, height, QImage::Format_ARGB32); } } +void cv_video_widget::update_image(const QImage& img) +{ + QMutexLocker l(&mtx); + + if (freshp) + return; + + const unsigned nbytes = img.sizeInBytes(); + + vec.resize(nbytes); + + std::memcpy(vec.data(), img.constBits(), nbytes); + + texture = QImage((const unsigned char*) vec.data(), img.width(), img.height(), img.format()); + + freshp = true; +} + void cv_video_widget::paintEvent(QPaintEvent*) { QMutexLocker foo(&mtx); @@ -74,8 +96,6 @@ void cv_video_widget::update_and_repaint() QMutexLocker l(&mtx); - preview_size = size(); - if (freshp) { freshp = false; diff --git a/cv/video-widget.hpp b/cv/video-widget.hpp index 5dd70815..7faddb49 100644 --- a/cv/video-widget.hpp +++ b/cv/video-widget.hpp @@ -9,6 +9,7 @@ #pragma once #include <memory> +#include <vector> #include <opencv2/core.hpp> @@ -25,17 +26,21 @@ class cv_video_widget final : public QWidget { Q_OBJECT + public: cv_video_widget(QWidget *parent); - void update_image(const cv::Mat &frame); + void update_image(const cv::Mat& frame); + void update_image(const QImage& image); + + static constexpr inline int width = 320, height = 240; protected slots: void paintEvent(QPaintEvent*) override; void update_and_repaint(); private: - QMutex mtx; + QMutex mtx { QMutex::Recursive }; QImage texture; + std::vector<unsigned char> vec; QTimer timer; - QSize preview_size; cv::Mat _frame, _frame2, _frame3; - bool freshp; + bool freshp = false; }; diff --git a/tracker-pt/camera.cpp b/tracker-pt/camera.cpp index bbc37cb1..20acf27a 100644 --- a/tracker-pt/camera.cpp +++ b/tracker-pt/camera.cpp @@ -6,13 +6,17 @@ */ #include "camera.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" -constexpr double Camera::dt_eps; +using namespace pt_module; Camera::Camera(const QString& module_name) : dt_mean(0), fov(0), s(module_name) {} @@ -45,8 +49,10 @@ Camera::result Camera::get_info() const return result(true, cam_info); } -Camera::result Camera::get_frame(cv::Mat& frame) +Camera::result Camera::get_frame(pt_frame& frame_) { + cv::Mat& frame = frame_.as<Frame>()->mat; + const bool new_frame = _get_frame(frame); if (new_frame) @@ -160,3 +166,4 @@ void Camera::camera_deleter::operator()(cv::VideoCapture* cap) delete cap; } } + diff --git a/tracker-pt/camera.h b/tracker-pt/camera.h index f5fd8f81..35e887ad 100644 --- a/tracker-pt/camera.h +++ b/tracker-pt/camera.h @@ -13,13 +13,17 @@ #include "compat/util.hpp" #include "compat/timer.hpp" +#include <functional> +#include <memory> +#include <tuple> + #include <opencv2/core.hpp> #include <opencv2/videoio.hpp> -#include <memory> -#include <tuple> #include <QString> +namespace pt_module { + struct Camera final : pt_camera { Camera(const QString& module_name); @@ -27,7 +31,7 @@ struct Camera final : pt_camera pt_camera_open_status start(int idx, int fps, int res_x, int res_y) override; void stop() override; - result get_frame(cv::Mat& frame) override; + result get_frame(pt_frame& Frame) override; result get_info() const override; pt_camera_info get_desired() const override { return cam_desired; } @@ -37,11 +41,10 @@ struct Camera final : pt_camera operator bool() const override { return cap && cap->isOpened(); } void set_fov(double value) override { fov = value; } - void show_camera_settings() override; private: - warn_result_unused bool _get_frame(cv::Mat& frame); + warn_result_unused bool _get_frame(cv::Mat& Frame); double dt_mean, fov; @@ -62,5 +65,7 @@ private: pt_settings s; - static constexpr double dt_eps = 1./384; + static constexpr inline double dt_eps = 1./384; }; + +} // ns pt_module diff --git a/tracker-pt/frame.cpp b/tracker-pt/frame.cpp new file mode 100644 index 00000000..ca72bd16 --- /dev/null +++ b/tracker-pt/frame.cpp @@ -0,0 +1,85 @@ +#include "frame.hpp" + +#include <cstring> +#include <tuple> + +#include <opencv2/imgproc.hpp> + +#pragma strict_gs_check(on) + +using namespace pt_module; + +Preview& Preview::operator=(const pt_frame& frame_) +{ + const cv::Mat& frame = frame_.as_const<const Frame>()->mat; + const int w = frame.cols, h = frame.rows; + ensure_size(frame_copy, w, h, CV_8UC3); + + if (frame.channels() != 3) + { + once_only(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels()); + return *this; + } + + const bool need_resize = w != frame_out.cols || h != frame_out.rows; + if (need_resize) + cv::resize(frame, frame_copy, cv::Size(frame_resize.cols, frame_resize.rows), 0, 0, cv::INTER_NEAREST); + else + frame.copyTo(frame_copy); + + return *this; +} + +Preview::Preview(int w, int h) +{ + ensure_size(frame_resize, w, h, CV_8UC4); + ensure_size(frame_out, w, h, CV_8UC4); + + frame_out.setTo(cv::Scalar(0, 0, 0, 0)); +} + +QImage Preview::get_bitmap() +{ + int stride = frame_out.step.p[0]; + + if (stride < 64 || stride < frame_out.cols * 4) + { + once_only(qDebug() << "bad stride" << stride + << "for bitmap size" << frame_copy.cols << frame_copy.rows); + return QImage(); + } + + cv::cvtColor(frame_copy, frame_out, cv::COLOR_BGR2BGRA); + + return QImage((const unsigned char*) frame_out.data, + frame_out.cols, frame_out.rows, + stride, + QImage::Format_ARGB32); +} + +void Preview::draw_head_center(double x, double y) +{ + double px_, py_; + + std::tie(px_, py_) = to_pixel_pos(x, y, frame_copy.cols, frame_copy.rows); + + int px = iround(px_), py = iround(py_); + + constexpr int len = 9; + + static const cv::Scalar color(0, 255, 255); + cv::line(frame_copy, + cv::Point(px - len, py), + cv::Point(px + len, py), + color, 1); + cv::line(frame_copy, + cv::Point(px, py - len), + cv::Point(px, py + len), + color, 1); +} + +void Preview::ensure_size(cv::Mat& frame, int w, int h, int type) +{ + if (frame.cols != w || frame.rows != h) + frame = cv::Mat(h, w, type); +} diff --git a/tracker-pt/frame.hpp b/tracker-pt/frame.hpp new file mode 100644 index 00000000..f8c33ebe --- /dev/null +++ b/tracker-pt/frame.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "pt-api.hpp" + +#include <opencv2/core.hpp> +#include <QImage> + +namespace pt_module { + +struct Frame final : pt_frame +{ + cv::Mat mat; + + operator const cv::Mat&() const& { return mat; } + operator cv::Mat&() & { return mat; } +}; + +struct Preview final : pt_preview +{ + Preview(int w, int h); + + Preview& operator=(const pt_frame& frame) override; + QImage get_bitmap() override; + void draw_head_center(double x, double y) override; + + operator cv::Mat&() { return frame_copy; } + operator cv::Mat const&() const { return frame_copy; } + +private: + static void ensure_size(cv::Mat& frame, int w, int h, int type); + + bool fresh = true; + cv::Mat frame_copy, frame_color, frame_resize, frame_out; +}; + +} // ns pt_module diff --git a/tracker-pt/ftnoir_tracker_pt.cpp b/tracker-pt/ftnoir_tracker_pt.cpp index b2d9bcbe..bded07d3 100644 --- a/tracker-pt/ftnoir_tracker_pt.cpp +++ b/tracker-pt/ftnoir_tracker_pt.cpp @@ -24,10 +24,14 @@ using namespace types; +static constexpr inline int preview_width = 320, preview_height = 240; + Tracker_PT::Tracker_PT(const pt_runtime_traits& traits) : s(traits.get_module_name()), point_extractor(std::move(traits.make_point_extractor())), - camera(std::move(traits.make_camera())) + camera(std::move(traits.make_camera())), + frame(std::move(traits.make_frame())), + preview_frame(std::move(traits.make_preview(preview_width, preview_height))) { cv::setBreakOnError(true); @@ -64,16 +68,14 @@ void Tracker_PT::run() QMutexLocker l(&camera_mtx); if (camera) - std::tie(new_frame, cam_info) = camera->get_frame(frame); + std::tie(new_frame, cam_info) = camera->get_frame(*frame); } if (new_frame) { - cv::resize(frame, preview_frame, - cv::Size(preview_size.width(), preview_size.height()), - 0, 0, cv::INTER_NEAREST); + *preview_frame = *frame; - point_extractor->extract_points(frame, preview_frame, points); + point_extractor->extract_points(*frame, *preview_frame, points); point_count = points.size(); const double fx = cam_info.get_focal_length(); @@ -100,26 +102,11 @@ void Tracker_PT::run() Affine X_MH(mat33::eye(), vec3(s.t_MH_x, s.t_MH_y, s.t_MH_z)); Affine X_GH = X_CM * X_MH; vec3 p = X_GH.t; // head (center?) position in global space - vec2 p_((p[0] * fx) / p[2], (p[1] * fx) / p[2]); // projected to screen - - constexpr int len = 9; - - cv::Point p2(iround(p_[0] * preview_frame.cols + preview_frame.cols/2), - iround(-p_[1] * preview_frame.cols + preview_frame.rows/2)); - static const cv::Scalar color(0, 255, 255); - cv::line(preview_frame, - cv::Point(p2.x - len, p2.y), - cv::Point(p2.x + len, p2.y), - color, - 1); - cv::line(preview_frame, - cv::Point(p2.x, p2.y - len), - cv::Point(p2.x, p2.y + len), - color, - 1); + + preview_frame->draw_head_center((p[0] * fx) / p[2], (p[1] * fx) / p[2]); } - video_widget->update_image(preview_frame); + video_widget->update_image(preview_frame->get_bitmap()); } } qDebug() << "pt: thread stopped"; @@ -137,7 +124,6 @@ void Tracker_PT::maybe_reopen_camera() case cam_open_error: break; case cam_open_ok_change: - frame = cv::Mat(); break; case cam_open_ok_no_change: break; @@ -155,9 +141,6 @@ module_status Tracker_PT::start_tracker(QFrame* video_frame) //video_frame->setAttribute(Qt::WA_NativeWindow); preview_size = video_frame->size(); - preview_frame = cv::Mat(video_frame->height(), video_frame->width(), CV_8UC3); - preview_frame.setTo(cv::Scalar(0, 0, 0)); - video_widget = std::make_unique<cv_video_widget>(video_frame); layout = std::make_unique<QHBoxLayout>(video_frame); layout->setContentsMargins(0, 0, 0, 0); diff --git a/tracker-pt/ftnoir_tracker_pt.h b/tracker-pt/ftnoir_tracker_pt.h index 9cf14cfd..deddeea8 100644 --- a/tracker-pt/ftnoir_tracker_pt.h +++ b/tracker-pt/ftnoir_tracker_pt.h @@ -26,10 +26,11 @@ #include <QThread> #include <QMutex> #include <QLayout> +#include <QTimer> class TrackerDialog_PT; -namespace pt_impl { +namespace pt_module { using namespace types; @@ -67,8 +68,9 @@ private: std::unique_ptr<cv_video_widget> video_widget; std::unique_ptr<QLayout> layout; - cv::Mat frame, preview_frame; std::vector<vec2> points; + std::unique_ptr<pt_frame> frame; + std::unique_ptr<pt_preview> preview_frame; QSize preview_size; @@ -81,4 +83,4 @@ private: } // ns pt_impl -using pt_impl::Tracker_PT; +using pt_module::Tracker_PT; diff --git a/tracker-pt/module.cpp b/tracker-pt/module.cpp index d0f097b9..d977aa16 100644 --- a/tracker-pt/module.cpp +++ b/tracker-pt/module.cpp @@ -2,6 +2,7 @@ #include "api/plugin-api.hpp" #include "camera.h" +#include "frame.hpp" #include "point_extractor.h" #include "ftnoir_tracker_pt_dialog.h" @@ -11,6 +12,8 @@ static const QString module_name = "tracker-pt"; +using namespace pt_module; + struct pt_module_traits final : pt_runtime_traits { std::unique_ptr<pt_camera> make_camera() const override @@ -27,24 +30,38 @@ struct pt_module_traits final : pt_runtime_traits { return module_name; } + + std::unique_ptr<pt_frame> make_frame() const override + { + return std::unique_ptr<pt_frame>(new Frame); + } + + std::unique_ptr<pt_preview> make_preview(int w, int h) const override + { + return std::unique_ptr<pt_preview>(new Preview(w, h)); + } }; -struct pt_tracker_module : Tracker_PT +struct tracker_pt : Tracker_PT { - pt_tracker_module() : Tracker_PT(pt_module_traits()) + tracker_pt() : Tracker_PT(pt_module_traits()) { } }; -struct pt_tracker_dialog_module : TrackerDialog_PT +struct dialog_pt : TrackerDialog_PT { - pt_tracker_dialog_module() : TrackerDialog_PT(module_name) {} + dialog_pt() : TrackerDialog_PT(module_name) {} }; -class pt_module_metadata : public Metadata +class metadata_pt : public Metadata { QString name() { return _("PointTracker 1.1"); } QIcon icon() { return QIcon(":/Resources/Logo_IR.png"); } }; -OPENTRACK_DECLARE_TRACKER(pt_tracker_module, pt_tracker_dialog_module, pt_module_metadata) +// ns pt_module + +using namespace pt_module; + +OPENTRACK_DECLARE_TRACKER(tracker_pt, dialog_pt, metadata_pt) diff --git a/tracker-pt/point_extractor.cpp b/tracker-pt/point_extractor.cpp index 464c25db..0904d9cb 100644 --- a/tracker-pt/point_extractor.cpp +++ b/tracker-pt/point_extractor.cpp @@ -9,6 +9,8 @@ #include "point_extractor.h" #include "compat/util.hpp" #include "point_tracker.h" +#include "frame.hpp" + #include <QDebug> #include "cv/numeric.hpp" @@ -29,7 +31,7 @@ #include <QDebug> using namespace types; -using namespace pt_impl; +using namespace pt_module; /* http://en.wikipedia.org/wiki/Mean-shift @@ -195,8 +197,11 @@ void PointExtractor::threshold_image(const cv::Mat& frame_gray, cv::Mat1b& outpu } } -void PointExtractor::extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) +void PointExtractor::extract_points(const pt_frame& frame_, pt_preview& preview_frame_, std::vector<vec2>& points) { + const cv::Mat& frame = frame_.as_const<Frame>()->mat; + cv::Mat& preview_frame = *preview_frame_.as<Preview>(); + ensure_buffers(frame); color_to_grayscale(frame, frame_gray); @@ -335,20 +340,17 @@ end: cv::circle(preview_frame, p, iround((b.radius + 3.3) * c_ * c_fract), circle_color, 1, cv::LINE_AA, fract_bits); char buf[16]; - std::snprintf(buf, sizeof(buf), "%.2fpx", b.radius); buf[sizeof(buf)-1] = '\0'; + std::snprintf(buf, sizeof(buf) - 1, "%.2fpx", b.radius); auto text_color = k >= PointModel::N_POINTS ? cv::Scalar(160, 160, 160) : cv::Scalar(0, 0, 255); - cv::putText(preview_frame, - buf, - cv::Point(iround(b.pos[0]*cx+offx), iround(b.pos[1]*cy+offy)), - cv::FONT_HERSHEY_PLAIN, - 1, - text_color, - 1); + cv::Point pos(iround(b.pos[0]*cx+offx), iround(b.pos[1]*cy+offy)); + cv::putText(preview_frame, buf, pos, + cv::FONT_HERSHEY_PLAIN, + 1, text_color, 1); } // End of mean shift code. At this point, blob positions are updated with hopefully less noisy less biased values. @@ -359,7 +361,8 @@ end: { // note: H/W is equal to fx/fy - vec2 p((b.pos[0] - W/2)/W, -(b.pos[1] - H/2)/W); + vec2 p; + std::tie(p[0], p[1]) = to_screen_pos(b.pos[0], b.pos[1], W, H); points.push_back(p); } } diff --git a/tracker-pt/point_extractor.h b/tracker-pt/point_extractor.h index 266964e5..1b6f55a2 100644 --- a/tracker-pt/point_extractor.h +++ b/tracker-pt/point_extractor.h @@ -15,7 +15,7 @@ #include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> -namespace pt_impl { +namespace pt_module { using namespace types; @@ -33,7 +33,7 @@ class PointExtractor final : public pt_point_extractor public: // extracts points from frame and draws some processing info into frame, if draw_output is set // dt: time since last call in seconds - void extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) override; + void extract_points(const pt_frame& frame, pt_preview& preview_frame, std::vector<vec2>& points) override; PointExtractor(const QString& module_name); private: static constexpr int max_blobs = 16; @@ -57,4 +57,3 @@ private: } // ns impl -using pt_impl::PointExtractor; diff --git a/tracker-pt/point_tracker.h b/tracker-pt/point_tracker.h index 816e02de..26677042 100644 --- a/tracker-pt/point_tracker.h +++ b/tracker-pt/point_tracker.h @@ -19,7 +19,7 @@ #include <array> #include <QObject> -namespace pt_impl { +namespace pt_module { // ---------------------------------------------------------------------------- // Describes a 3-point model @@ -82,5 +82,5 @@ private: } // ns pt_impl -using pt_impl::PointTracker; -using pt_impl::PointModel; +using pt_module::PointTracker; +using pt_module::PointModel; diff --git a/tracker-pt/pt-api.cpp b/tracker-pt/pt-api.cpp index c11f372f..0a6c8e2b 100644 --- a/tracker-pt/pt-api.cpp +++ b/tracker-pt/pt-api.cpp @@ -60,3 +60,22 @@ double pt_point_extractor::threshold_radius_value(int w, int h, int threshold) return radius; } + + +std::tuple<double, double> pt_pixel_pos_mixin::to_pixel_pos(double x, double y, int w, int h) +{ + return std::make_tuple(w*(x+.5), .5*(h - 2*y*w)); +} + +std::tuple<double, double> pt_pixel_pos_mixin::to_screen_pos(double px, double py, int w, int h) +{ + return std::make_tuple((px - w/2.)/w, -(py - h/2.)/w); +} + +pt_frame::pt_frame() +{ +} + +pt_frame::~pt_frame() +{ +} diff --git a/tracker-pt/pt-api.hpp b/tracker-pt/pt-api.hpp index 79a47526..833a640e 100644 --- a/tracker-pt/pt-api.hpp +++ b/tracker-pt/pt-api.hpp @@ -5,10 +5,14 @@ #include "cv/numeric.hpp" #include "options/options.hpp" +#include <tuple> +#include <type_traits> #include <memory> #include <opencv2/core.hpp> +#include <QImage> + struct OTR_PT_EXPORT pt_camera_info final { pt_camera_info(); @@ -34,6 +38,40 @@ enum pt_color_type pt_color_blue_only = 6, }; +struct OTR_PT_EXPORT pt_frame +{ + pt_frame(); + virtual ~pt_frame(); + + template<typename t> + t* as() & + { + using u = std::decay_t<t>; + static_assert(std::is_convertible_v<u*, pt_frame*>, "must be derived from pt_image"); + + return static_cast<t*>(this); + } + + template<typename t> + t const* as_const() const& + { + return const_cast<pt_frame*>(this)->as<const t>(); + } +}; + +struct OTR_PT_EXPORT pt_pixel_pos_mixin +{ + static std::tuple<double, double> to_pixel_pos(double x, double y, int w, int h); + static std::tuple<double, double> to_screen_pos(double px, double py, int w, int h); +}; + +struct OTR_PT_EXPORT pt_preview : pt_frame, pt_pixel_pos_mixin +{ + virtual pt_preview& operator=(const pt_frame&) = 0; + virtual QImage get_bitmap() = 0; + virtual void draw_head_center(double x, double y) = 0; +}; + struct OTR_PT_EXPORT pt_camera { using result = std::tuple<bool, pt_camera_info>; @@ -43,7 +81,7 @@ struct OTR_PT_EXPORT pt_camera virtual warn_result_unused pt_camera_open_status start(int idx, int fps, int res_x, int res_y) = 0; virtual void stop() = 0; - virtual warn_result_unused result get_frame(cv::Mat& frame) = 0; + virtual warn_result_unused result get_frame(pt_frame& frame) = 0; virtual warn_result_unused result get_info() const = 0; virtual pt_camera_info get_desired() const = 0; @@ -57,13 +95,13 @@ struct OTR_PT_EXPORT pt_camera virtual void show_camera_settings() = 0; }; -struct OTR_PT_EXPORT pt_point_extractor +struct OTR_PT_EXPORT pt_point_extractor : pt_pixel_pos_mixin { using vec2 = types::vec2; pt_point_extractor(); virtual ~pt_point_extractor(); - virtual void extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) = 0; + virtual void extract_points(const pt_frame& image, pt_preview& preview_frame, std::vector<vec2>& points) = 0; static double threshold_radius_value(int w, int h, int threshold); }; @@ -115,5 +153,7 @@ struct OTR_PT_EXPORT pt_runtime_traits virtual std::unique_ptr<pt_camera> make_camera() const = 0; virtual std::unique_ptr<pt_point_extractor> make_point_extractor() const = 0; + virtual std::unique_ptr<pt_frame> make_frame() const = 0; + virtual std::unique_ptr<pt_preview> make_preview(int w, int h) const = 0; virtual QString get_module_name() const = 0; }; |