diff options
Diffstat (limited to 'cv')
-rw-r--r-- | cv/CMakeLists.txt | 2 | ||||
-rw-r--r-- | cv/affine.cpp | 5 | ||||
-rw-r--r-- | cv/affine.hpp | 10 | ||||
-rw-r--r-- | cv/numeric.hpp | 12 | ||||
-rw-r--r-- | cv/translation-calibrator.cpp | 4 | ||||
-rw-r--r-- | cv/translation-calibrator.hpp | 8 | ||||
-rw-r--r-- | cv/video-property-page.cpp | 34 | ||||
-rw-r--r-- | cv/video-property-page.hpp | 6 | ||||
-rw-r--r-- | cv/video-widget.cpp | 153 | ||||
-rw-r--r-- | cv/video-widget.hpp | 38 |
10 files changed, 94 insertions, 178 deletions
diff --git a/cv/CMakeLists.txt b/cv/CMakeLists.txt index 1007344c..dfc983aa 100644 --- a/cv/CMakeLists.txt +++ b/cv/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(OpenCV QUIET) if(OpenCV_FOUND) otr_module(cv STATIC) - target_link_libraries(${self} opencv_core opencv_videoio) + target_link_libraries(${self} opencv_videoio opencv_core opentrack-video) target_include_directories(${self} SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS}) endif() diff --git a/cv/affine.cpp b/cv/affine.cpp index 4ec63e57..66e21aa6 100644 --- a/cv/affine.cpp +++ b/cv/affine.cpp @@ -9,9 +9,8 @@ namespace affine_impl { -Affine::Affine() : R(mat33::eye()), t(0,0,0) {} - -Affine::Affine(const mat33& R, const vec3& t) : R(R),t(t) {} +Affine::Affine() = default; +Affine::Affine(const mat33& R, const vec3& t) : R(R), t(t) {} Affine operator*(const Affine& X, const Affine& Y) { diff --git a/cv/affine.hpp b/cv/affine.hpp index 3bc85c95..882a1145 100644 --- a/cv/affine.hpp +++ b/cv/affine.hpp @@ -12,7 +12,7 @@ namespace affine_impl { -using namespace types; +using namespace numeric_types; class Affine final { @@ -20,8 +20,8 @@ public: Affine(); Affine(const mat33& R, const vec3& t); - mat33 R; - vec3 t; + mat33 R { mat33::eye() }; + vec3 t { 0, 0, 0 }; }; Affine operator*(const Affine& X, const Affine& Y); @@ -31,5 +31,5 @@ vec3 operator*(const Affine& X, const vec3& v); } // ns affine_impl -using affine_impl::Affine; -using affine_impl::operator *; +using Affine = affine_impl::Affine; +//using affine_impl::operator *; diff --git a/cv/numeric.hpp b/cv/numeric.hpp index 0edb7f58..ce8f7e82 100644 --- a/cv/numeric.hpp +++ b/cv/numeric.hpp @@ -1,13 +1,15 @@ #pragma once +#include <type_traits> #include <opencv2/core.hpp> -namespace types { - using f = double; +namespace numeric_types { + using f = float; - namespace constants { - static constexpr inline f eps = f(1e-8); - } + static_assert(std::is_floating_point_v<f>); + + static constexpr f eps = f(1e-8); + static constexpr f pi = f(M_PI); template<int n> using vec = cv::Vec<f, n>; using vec2 = vec<2>; diff --git a/cv/translation-calibrator.cpp b/cv/translation-calibrator.cpp index 708cc593..8117b1e7 100644 --- a/cv/translation-calibrator.cpp +++ b/cv/translation-calibrator.cpp @@ -80,7 +80,7 @@ tt TranslationCalibrator::get_estimate() }; } -static constexpr inline double r2d = 180/M_PI; +static constexpr double r2d = 180/M_PI; bool TranslationCalibrator::check_bucket(const cv::Matx33d& R_CM_k) { @@ -94,7 +94,7 @@ bool TranslationCalibrator::check_bucket(const cv::Matx33d& R_CM_k) const euler_t ypr = rmat_to_euler(r) * r2d; auto array_index = [](double val, double spacing) { - return iround((val + 180)/spacing); + return (unsigned)iround((val + 180)/spacing); }; const unsigned yaw_k = array_index(ypr(yaw_rdof), yaw_spacing_in_degrees); diff --git a/cv/translation-calibrator.hpp b/cv/translation-calibrator.hpp index da052526..406edb72 100644 --- a/cv/translation-calibrator.hpp +++ b/cv/translation-calibrator.hpp @@ -41,8 +41,8 @@ public: // we're bringing in 3DOF samples but the calibrator only // checks yaw and pitch - static constexpr inline unsigned num_cal_axis = 3; - static constexpr inline unsigned num_nsample_axis = 2; + static constexpr unsigned num_cal_axis = 3; + static constexpr unsigned num_nsample_axis = 2; using cv_cal_vec = cv::Vec<float, num_cal_axis>; using cv_nsample_vec = cv::Vec<unsigned, num_nsample_axis>; @@ -51,6 +51,6 @@ public: // get the current estimate for t_MH tt get_estimate(); - static constexpr inline double yaw_spacing_in_degrees = 2; - static constexpr inline double pitch_spacing_in_degrees = 1.5; + static constexpr double yaw_spacing_in_degrees = 2; + static constexpr double pitch_spacing_in_degrees = 1.5; }; diff --git a/cv/video-property-page.cpp b/cv/video-property-page.cpp index e76f8bc3..bae5e8b3 100644 --- a/cv/video-property-page.cpp +++ b/cv/video-property-page.cpp @@ -25,11 +25,6 @@ #include <QDebug> -#include <dshow.h> - -#define CHECK(expr) if (FAILED(hr = (expr))) { qDebug() << QLatin1String(#expr) << hr; goto done; } -#define CHECK2(expr) if (!(expr)) { qDebug() << QLatin1String(#expr); goto done; } - bool video_property_page::show_from_capture(cv::VideoCapture& cap, int /*index */) { return cap.set(cv::CAP_PROP_SETTINGS, 0); @@ -39,16 +34,18 @@ struct prop_settings_worker final : QThread { explicit prop_settings_worker(int idx); ~prop_settings_worker() override; - void _open_prop_page(); + +private: + void open_prop_page(); void run() override; cv::VideoCapture cap; - int _idx = -1; + int idx = -1; }; -prop_settings_worker::prop_settings_worker(int idx) +prop_settings_worker::prop_settings_worker(int idx_) { - int ret = cap.get(cv::CAP_PROP_SETTINGS); + int ret = (int)cap.get(cv::CAP_PROP_SETTINGS); if (ret != 0) run_in_thread_async(qApp, [] { @@ -60,16 +57,16 @@ prop_settings_worker::prop_settings_worker(int idx) }); else { - _idx = idx; + idx = idx_; // DON'T MOVE IT // ps3 eye will reset to default settings if done from another thread - _open_prop_page(); + open_prop_page(); } } -void prop_settings_worker::_open_prop_page() +void prop_settings_worker::open_prop_page() { - cap.open(_idx); + cap.open(idx); if (cap.isOpened()) { @@ -87,14 +84,14 @@ void prop_settings_worker::_open_prop_page() } qDebug() << "property-page: can't open camera"; - _idx = -1; + idx = -1; return; ok: portable::sleep(100); - qDebug() << "property-page: opening for" << _idx; + qDebug() << "property-page: opening for" << idx; if (!cap.set(cv::CAP_PROP_SETTINGS, 0)) { @@ -110,7 +107,7 @@ ok: prop_settings_worker::~prop_settings_worker() { - if (_idx != -1) + if (idx != -1) { // ax filter is race condition-prone portable::sleep(250); @@ -118,13 +115,13 @@ prop_settings_worker::~prop_settings_worker() // idem portable::sleep(250); - qDebug() << "property-page: closed" << _idx; + qDebug() << "property-page: closed" << idx; } } void prop_settings_worker::run() { - if (_idx != -1) + if (idx != -1) { while (cap.get(cv::CAP_PROP_SETTINGS) > 0) portable::sleep(1000); @@ -166,4 +163,3 @@ bool video_property_page::show_from_capture(cv::VideoCapture&, int idx) bool video_property_page::show(int) { return false; } bool video_property_page::show_from_capture(cv::VideoCapture&, int) { return false; } #endif - diff --git a/cv/video-property-page.hpp b/cv/video-property-page.hpp index 9e6b596f..c2b9525d 100644 --- a/cv/video-property-page.hpp +++ b/cv/video-property-page.hpp @@ -1,11 +1,6 @@ #pragma once #include <QString> - -#ifdef _WIN32 -# include <windows.h> -#endif - #include <opencv2/videoio.hpp> struct video_property_page final @@ -15,3 +10,4 @@ struct video_property_page final static bool show_from_capture(cv::VideoCapture& cap, int index); private: }; + diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index d93429cb..7cc6ca2d 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -1,129 +1,78 @@ -/* Copyright (c) 2012 Patrick Ruoff - * Copyright (c) 2014-2016 Stanislaw Halik <sthalik@misaki.pl> - * - * 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 "video-widget.hpp" -#include "compat/check-visible.hpp" -#include "compat/math.hpp" - -#include <cstring> #include <opencv2/imgproc.hpp> -cv_video_widget::cv_video_widget(QWidget* parent) : QWidget(parent) -{ - connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint()), Qt::DirectConnection); - timer.start(65); -} - void cv_video_widget::update_image(const cv::Mat& frame) { QMutexLocker l(&mtx); - if (!freshp) - { - if (width < 1 || height < 1) - return; - - if (_frame.cols != frame.cols || _frame.rows != frame.rows) - _frame = cv::Mat(frame.rows, frame.cols, CV_8UC3); - frame.copyTo(_frame); - freshp = true; - - if (_frame2.cols != _frame.cols || _frame2.rows != _frame.rows) - _frame2 = cv::Mat(_frame.rows, _frame.cols, 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; - - if (_frame.cols != width || _frame.rows != height) - { - cv::resize(_frame2, _frame3, cv::Size(width, height), 0, 0, cv::INTER_NEAREST); - - img = &_frame3; - } - else - img = &_frame2; - - const unsigned nbytes = 4 * img->rows * img->cols; - - vec.resize(nbytes); - - std::memcpy(vec.data(), img->data, nbytes); - - 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.bytesPerLine() * img.height(); - - vec.resize(nbytes); - - std::memcpy(vec.data(), img.constBits(), nbytes); - - texture = QImage((const unsigned char*) vec.data(), img.width(), img.height(), img.format()); + if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1) + return; - freshp = true; -} + cv::Mat const* __restrict frame_scaled = nullptr; -void cv_video_widget::paintEvent(QPaintEvent*) -{ - QMutexLocker foo(&mtx); + if (frame3.cols != W || frame3.rows != H) + { + frame3 = cv::Mat(H, W, frame.type()); + frame2 = cv::Mat(H, W, CV_8UC4); - QPainter painter(this); + if (!frame2.isContinuous() || !frame3.isContinuous()) + std::abort(); + } - double dpr = devicePixelRatioF(); + if (frame.cols != W || frame.rows != H) + { + cv::resize(frame, frame3, { W, H }, 0, 0, cv::INTER_NEAREST); + frame_scaled = &frame3; + } + else if (!frame.isContinuous()) + { + frame.copyTo(frame3); + frame_scaled = &frame3; + } + else + frame_scaled = &frame; - int W = iround(QWidget::width() * dpr); - int H = iround(QWidget::height() * dpr); + freshp = true; - painter.drawImage(rect(), texture); + int color_cvt = 0; + constexpr int nchannels = 4; - if (texture.width() != W || texture.height() != H) + switch (frame_scaled->channels()) { - texture = QImage(W, H, QImage::Format_ARGB32); - texture.setDevicePixelRatio(dpr); - - width = W, height = H; - - _frame = cv::Mat(); - _frame2 = cv::Mat(); - _frame3 = cv::Mat(); + case 1: + color_cvt = cv::COLOR_GRAY2BGRA; + break; + case 3: + color_cvt = cv::COLOR_BGR2BGRA; + break; + case nchannels: + break; + default: + unreachable(); + break; } -} - -void cv_video_widget::update_and_repaint() -{ - if (!check_is_visible()) - return; - QMutexLocker l(&mtx); + cv::Mat const* frame_color; - if (freshp) + if (color_cvt != cv::COLOR_COLORCVT_MAX) { - freshp = false; - repaint(); + cv::cvtColor(*frame_scaled, frame2, color_cvt); + frame_color = &frame2; } -} + else + frame_color = frame_scaled; -void cv_video_widget::get_preview_size(int& w, int& h) -{ - QMutexLocker l(&mtx); + int stride = frame_color->step.p[0], rows = frame_color->rows; + int nbytes = rows * stride; + vec.resize(nbytes); vec.shrink_to_fit(); + std::memcpy(vec.data(), frame_color->data, nbytes); - w = width, h = height; + texture = QImage((const unsigned char*) vec.data(), W, H, stride, QImage::Format_ARGB32); + texture.setDevicePixelRatio(devicePixelRatioF()); } + +cv_video_widget::cv_video_widget(QWidget* parent) : video_widget(parent) {} diff --git a/cv/video-widget.hpp b/cv/video-widget.hpp index 8ad62a3c..9d62f19e 100644 --- a/cv/video-widget.hpp +++ b/cv/video-widget.hpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2012 Patrick Ruoff - * Copyright (c) 2014-2016 Stanislaw Halik <sthalik@misaki.pl> +/* Copyright (c) 2019 Stanislaw Halik <sthalik@misaki.pl> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -8,39 +7,14 @@ #pragma once -#include <memory> -#include <vector> - +#include "video/video-widget.hpp" #include <opencv2/core.hpp> -#include <QObject> -#include <QWidget> -#include <QPainter> -#include <QtEvents> -#include <QTimer> -#include <QMutex> -#include <QMutexLocker> -#include <QSize> -#include <QDebug> - -class cv_video_widget final : public QWidget +struct cv_video_widget final : video_widget { - Q_OBJECT - -public: - cv_video_widget(QWidget *parent); + cv_video_widget(QWidget* parent = nullptr); void update_image(const cv::Mat& frame); - void update_image(const QImage& image); - void get_preview_size(int& w, int& h); -private slots: - void paintEvent(QPaintEvent*) override; - void update_and_repaint(); + private: - QMutex mtx { QMutex::Recursive }; - QImage texture; - std::vector<unsigned char> vec; - QTimer timer; - cv::Mat _frame, _frame2, _frame3; - int width = 320, height = 240; - bool freshp = false; + cv::Mat frame2, frame3; }; |