diff options
Diffstat (limited to 'ftnoir_tracker_aruco')
-rw-r--r-- | ftnoir_tracker_aruco/ar_video_widget.cpp | 42 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/ar_video_widget.h (renamed from ftnoir_tracker_aruco/video_widget.h) | 20 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/aruco-trackercontrols.ui | 782 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp | 530 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/ftnoir_tracker_aruco.h | 90 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h | 3 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/include/boarddetector.h | 2 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/include/cvdrawingutils.h | 2 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/include/markerdetector.h | 11 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/video_widget.cpp | 30 |
10 files changed, 701 insertions, 811 deletions
diff --git a/ftnoir_tracker_aruco/ar_video_widget.cpp b/ftnoir_tracker_aruco/ar_video_widget.cpp new file mode 100644 index 00000000..9a089213 --- /dev/null +++ b/ftnoir_tracker_aruco/ar_video_widget.cpp @@ -0,0 +1,42 @@ +/* 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 "ar_video_widget.h" + +#include <QDebug> + +using namespace std; + +void ArucoVideoWidget::update_image(const cv::Mat& frame) +{ + QMutexLocker foo(&mtx); + _frame = frame.clone(); +} + +void ArucoVideoWidget::update_and_repaint() +{ + QMutexLocker foo(&mtx); + if (_frame.cols*_frame.rows <= 0) + return; + QImage qframe = QImage(_frame.cols, _frame.rows, QImage::Format_RGB888); + uchar* data = qframe.bits(); + const int pitch = qframe.bytesPerLine(); + for (int y = 0; y < _frame.rows; y++) + { + for (int x = 0; x < _frame.cols; x++) + { + const auto& elt = _frame.at<cv::Vec3b>(y, x); + const cv::Scalar elt2 = static_cast<cv::Scalar>(elt); + data[y * pitch + x * 3 + 0] = elt2.val[2]; + data[y * pitch + x * 3 + 1] = elt2.val[1]; + data[y * pitch + x * 3 + 2] = elt2.val[0]; + } + } + auto qframe2 = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); + texture = qframe2; + update(); +} diff --git a/ftnoir_tracker_aruco/video_widget.h b/ftnoir_tracker_aruco/ar_video_widget.h index 87b6278a..e2cf4d9f 100644 --- a/ftnoir_tracker_aruco/video_widget.h +++ b/ftnoir_tracker_aruco/ar_video_widget.h @@ -8,32 +8,40 @@ #ifndef VIDEOWIDGET_H #define VIDEOWIDGET_H -#include <QTime> +#include <QTimer> #include <QWidget> #include <QMutex> #include <QMutexLocker> #include <QLabel> #include <QPainter> #include <QPaintEvent> +#include <QTimer> +#include <opencv/cv.hpp> // ---------------------------------------------------------------------------- -class VideoWidget : public QWidget +class ArucoVideoWidget : public QWidget { Q_OBJECT public: - VideoWidget(QWidget *parent) : QWidget(parent), mtx() { + ArucoVideoWidget(QWidget *parent) : QWidget(parent) { + connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint())); + timer.start(60); } - void update_image(unsigned char* frame, int width, int height); + void update_image(const cv::Mat& frame); protected slots: void paintEvent( QPaintEvent* e ) { QMutexLocker foo(&mtx); QPainter painter(this); - painter.drawPixmap(e->rect(), pixmap, e->rect()); + painter.drawImage(e->rect(), texture); } + void update_and_repaint(); + private: QMutex mtx; - QPixmap pixmap; + QImage texture; + QTimer timer; + cv::Mat _frame; }; #endif // VIDEOWIDGET_H diff --git a/ftnoir_tracker_aruco/aruco-trackercontrols.ui b/ftnoir_tracker_aruco/aruco-trackercontrols.ui index 3ad9fa40..1d5a4241 100644 --- a/ftnoir_tracker_aruco/aruco-trackercontrols.ui +++ b/ftnoir_tracker_aruco/aruco-trackercontrols.ui @@ -9,475 +9,365 @@ <rect> <x>0</x> <y>0</y> - <width>593</width> - <height>280</height> + <width>615</width> + <height>326</height> </rect> </property> <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="maximumSize"> <size> - <width>750</width> - <height>280</height> + <width>6666</width> + <height>6666</height> </size> </property> <property name="windowTitle"> <string>HT tracker settings</string> </property> - <widget class="QLabel" name="label"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>141</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Horizontal FOV</string> - </property> - </widget> - <widget class="QDoubleSpinBox" name="cameraFOV"> - <property name="geometry"> - <rect> - <x>130</x> - <y>10</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <property name="minimum"> - <double>35.000000000000000</double> - </property> - <property name="maximum"> - <double>180.000000000000000</double> - </property> - <property name="value"> - <double>52.000000000000000</double> - </property> - </widget> - <widget class="QLabel" name="label_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>137</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Frames per second</string> - </property> - </widget> - <widget class="QComboBox" name="cameraFPS"> - <property name="geometry"> - <rect> - <x>130</x> - <y>40</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <item> - <property name="text"> - <string notr="true">Default</string> - </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="spacing"> + <number>7</number> + </property> + <item row="9" column="1" rowspan="3"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Head position</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="2" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>TY</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>TX</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDoubleSpinBox" name="cx"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <double>-10000.000000000000000</double> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>TZ</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QDoubleSpinBox" name="cz"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <double>-10000.000000000000000</double> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDoubleSpinBox" name="cy"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <double>-10000.000000000000000</double> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> </item> - <item> - <property name="text"> - <string>30</string> - </property> + <item row="0" column="3" rowspan="3" colspan="2"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Enable axes</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <property name="horizontalSpacing"> + <number>7</number> + </property> + <property name="leftMargin"> + <number>6</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>6</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item row="0" column="0"> + <widget class="QCheckBox" name="rx"> + <property name="text"> + <string>RX</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="tx"> + <property name="text"> + <string>TX</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="ry"> + <property name="text"> + <string>RY</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="ty"> + <property name="text"> + <string>TY</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="rz"> + <property name="text"> + <string>RZ</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="tz"> + <property name="text"> + <string>TZ</string> + </property> + </widget> + </item> + </layout> + </widget> </item> - <item> - <property name="text"> - <string>60</string> - </property> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Frames per second</string> + </property> + </widget> </item> - <item> - <property name="text"> - <string>120</string> - </property> + <item row="2" column="1" colspan="2"> + <widget class="QComboBox" name="cameraName"/> </item> - </widget> - <widget class="QLabel" name="label_3"> - <property name="geometry"> - <rect> - <x>10</x> - <y>70</y> - <width>133</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Camera name</string> - </property> - </widget> - <widget class="QPushButton" name="buttonOK"> - <property name="geometry"> - <rect> - <x>430</x> - <y>250</y> - <width>75</width> - <height>23</height> - </rect> - </property> - <property name="text"> - <string>OK</string> - </property> - </widget> - <widget class="QPushButton" name="buttonCancel"> - <property name="geometry"> - <rect> - <x>510</x> - <y>250</y> - <width>75</width> - <height>23</height> - </rect> - </property> - <property name="text"> - <string>Cancel</string> - </property> - </widget> - <widget class="QGroupBox" name="groupBox"> - <property name="geometry"> - <rect> - <x>390</x> - <y>10</y> - <width>101</width> - <height>81</height> - </rect> - </property> - <property name="title"> - <string>Enable axes</string> - </property> - <widget class="QCheckBox" name="rx"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RX</string> - </property> - </widget> - <widget class="QCheckBox" name="ry"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RY</string> - </property> - </widget> - <widget class="QCheckBox" name="rz"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RZ</string> - </property> - </widget> - <widget class="QCheckBox" name="tx"> - <property name="geometry"> - <rect> - <x>60</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TX</string> - </property> - </widget> - <widget class="QCheckBox" name="ty"> - <property name="geometry"> - <rect> - <x>60</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TY</string> - </property> - </widget> - <widget class="QCheckBox" name="tz"> - <property name="geometry"> - <rect> - <x>60</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TZ</string> - </property> - </widget> - </widget> - <widget class="QComboBox" name="cameraName"> - <property name="geometry"> - <rect> - <x>130</x> - <y>70</y> - <width>251</width> - <height>22</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="label_4"> - <property name="geometry"> - <rect> - <x>10</x> - <y>100</y> - <width>128</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Resolution</string> - </property> - </widget> - <widget class="QComboBox" name="resolution"> - <property name="geometry"> - <rect> - <x>130</x> - <y>100</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <item> - <property name="text"> - <string>640x480</string> - </property> + <item row="1" column="1" colspan="2"> + <widget class="QComboBox" name="cameraFPS"> + <item> + <property name="text"> + <string notr="true">Default</string> + </property> + </item> + <item> + <property name="text"> + <string>30</string> + </property> + </item> + <item> + <property name="text"> + <string>60</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>180</string> + </property> + </item> + </widget> </item> - <item> - <property name="text"> - <string>320x240</string> - </property> + <item row="7" column="1"> + <widget class="QCheckBox" name="red_only"> + <property name="text"> + <string>Recommended!</string> + </property> + </widget> </item> - <item> - <property name="text"> - <string>320x200</string> - </property> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Camera name</string> + </property> + </widget> </item> - <item> - <property name="text"> - <string>Default (not recommended!)</string> - </property> + <item row="0" column="1" colspan="2"> + <widget class="QDoubleSpinBox" name="cameraFOV"> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <property name="minimum"> + <double>35.000000000000000</double> + </property> + <property name="maximum"> + <double>180.000000000000000</double> + </property> + <property name="value"> + <double>52.000000000000000</double> + </property> + </widget> </item> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox"> - <property name="geometry"> - <rect> - <x>130</x> - <y>130</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QLabel" name="label_5"> - <property name="geometry"> - <rect> - <x>10</x> - <y>130</y> - <width>111</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Distortion coefficients</string> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_2"> - <property name="geometry"> - <rect> - <x>130</x> - <y>160</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_3"> - <property name="geometry"> - <rect> - <x>130</x> - <y>190</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_4"> - <property name="geometry"> - <rect> - <x>130</x> - <y>220</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_5"> - <property name="geometry"> - <rect> - <x>130</x> - <y>250</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QLabel" name="label_6"> - <property name="geometry"> - <rect> - <x>325</x> - <y>133</y> - <width>253</width> - <height>60</height> - </rect> - </property> - <property name="text"> - <string>The ARUCO Library has been developed by -the Ava group of the Univeristy of Cordoba(Spain) -Contact to -Rafael Muñoz Salinas <rmsalinas@uco.es></string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - <widget class="QLineEdit" name="lineEdit"> - <property name="geometry"> - <rect> - <x>370</x> - <y>200</y> - <width>181</width> - <height>20</height> - </rect> - </property> - <property name="text"> - <string>https://github.com/rmsalinas/aruco</string> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> + <item row="6" column="2" rowspan="5" colspan="3"> + <widget class="QLabel" name="label_6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><html><head/><body><p>The ARUCO Library has been developed by the Ava group of the Univeristy of Cordoba, Spain</p><p>Rafael Muñoz Salinas &lt;<a href="mailto:rmsalinas@uco.es"><span style=" text-decoration: underline; color:#0057ae;">rmsalinas@uco.es</span></a>&gt;</p><p>&lt;<a href="https://github.com/rmsalinas/aruco"><span style=" text-decoration: underline; color:#0057ae;">https://github.com/rmsalinas/aruco</span></a>&gt;</p></body></html></string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Red channel only</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QComboBox" name="resolution"> + <item> + <property name="text"> + <string>640x480</string> + </property> + </item> + <item> + <property name="text"> + <string>320x240</string> + </property> + </item> + <item> + <property name="text"> + <string>320x200</string> + </property> + </item> + <item> + <property name="text"> + <string>Default (not recommended!)</string> + </property> + </item> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Horizontal FOV</string> + </property> + </widget> + </item> + <item row="11" column="4"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QDoubleSpinBox" name="marker_pitch"> + <property name="minimum"> + <double>-180.000000000000000</double> + </property> + <property name="maximum"> + <double>180.000000000000000</double> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Resolution</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Marker pitch</string> + </property> + </widget> + </item> + </layout> </widget> + <tabstops> + <tabstop>cameraFOV</tabstop> + <tabstop>cameraFPS</tabstop> + <tabstop>cameraName</tabstop> + <tabstop>resolution</tabstop> + <tabstop>red_only</tabstop> + <tabstop>marker_pitch</tabstop> + <tabstop>cx</tabstop> + <tabstop>cy</tabstop> + <tabstop>cz</tabstop> + <tabstop>rx</tabstop> + <tabstop>ry</tabstop> + <tabstop>rz</tabstop> + <tabstop>tx</tabstop> + <tabstop>ty</tabstop> + <tabstop>tz</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> <resources/> <connections/> <designerdata> diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp index 152c1e32..ae7ca0b5 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp @@ -15,17 +15,21 @@ #include <opencv2/opencv.hpp> #include <opencv/highgui.h> #include <vector> +#include <cstdio> -#if defined(_WIN32) || defined(__WIN32) -#include <dshow.h> +#if defined(_WIN32) +# undef NOMINMAX +# define NOMINMAX +# define NO_DSHOW_STRSAFE +# include <dshow.h> #else -#include <unistd.h> +# include <unistd.h> #endif // delicious copypasta static QList<QString> get_camera_names(void) { QList<QString> ret; -#if defined(_WIN32) || defined(__WIN32) +#if defined(_WIN32) // Create the System Device Enumerator. HRESULT hr; ICreateDevEnum *pSysDevEnum = NULL; @@ -78,7 +82,7 @@ static QList<QString> get_camera_names(void) { if (access(buf, R_OK | W_OK) == 0) { ret.append(buf); } else { - break; + continue; } } #endif @@ -97,55 +101,27 @@ static resolution_tuple resolution_choices[] = { { 0, 0 } }; -void Tracker::load_settings() +Tracker::Tracker() : stop(false), layout(nullptr), videoWidget(nullptr) { - QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - - iniFile.beginGroup( "aruco-Tracker" ); - fov = iniFile.value("fov", 56).toFloat(); - force_fps = iniFile.value("fps", 0).toInt(); - camera_index = iniFile.value("camera-index", -1).toInt(); - int res = iniFile.value("resolution", 0).toInt(); - if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple))) - res = 0; - resolution_tuple r = resolution_choices[res]; - force_width = r.width; - force_height = r.height; - enableRX = iniFile.value("enable-rx", true).toBool(); - enableRY = iniFile.value("enable-ry", true).toBool(); - enableRZ = iniFile.value("enable-rz", true).toBool(); - enableTX = iniFile.value("enable-tx", true).toBool(); - enableTY = iniFile.value("enable-ty", true).toBool(); - enableTZ = iniFile.value("enable-tz", true).toBool(); - for (int i = 0; i < 5; i++) - dc[i] = iniFile.value(QString("dc%1").arg(i), 0).toFloat(); - iniFile.endGroup(); -} - -Tracker::Tracker() -{ - fresh = false; - stop = false; - videoWidget = NULL; - layout = NULL; - enableRX = enableRY = enableRZ = enableTX = enableTY = enableTZ = true; - load_settings(); } Tracker::~Tracker() { - if (layout) - delete layout; + stop = true; + wait(); if (videoWidget) delete videoWidget; + if(layout) + delete layout; + qDebug() << "releasing camera, brace for impact"; + camera.release(); + qDebug() << "all done!"; } void Tracker::StartTracker(QFrame* videoframe) { videoframe->show(); - videoWidget = new VideoWidget(videoframe); + videoWidget = new ArucoVideoWidget(videoframe); QHBoxLayout* layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(videoWidget); @@ -153,143 +129,263 @@ void Tracker::StartTracker(QFrame* videoframe) delete videoframe->layout(); videoframe->setLayout(layout); videoWidget->show(); - this->layout = layout; - load_settings(); - connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget())); - timer.start(50); start(); for (int i = 0; i < 6; i++) pose[i] = 0; -} - -void Tracker::paint_widget() { - if (fresh) { - fresh = false; - videoWidget->update(); - } + this->layout = layout; } #define HT_PI 3.1415926535 void Tracker::run() { - cv::VideoCapture camera(camera_index); - - if (force_width) - camera.set(CV_CAP_PROP_FRAME_WIDTH, force_width); - if (force_height) - camera.set(CV_CAP_PROP_FRAME_HEIGHT, force_height); - if (force_fps) - camera.set(CV_CAP_PROP_FPS, force_fps); + int res = s.resolution; + if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple))) + res = 0; + resolution_tuple r = resolution_choices[res]; + int fps; + switch (static_cast<int>(s.force_fps)) + { + default: + case 0: + fps = 0; + break; + case 1: + fps = 30; + break; + case 2: + fps = 60; + break; + case 3: + fps = 120; + break; + case 4: + fps = 180; + break; + } + camera = cv::VideoCapture(s.camera_index); + if (r.width) + { + camera.set(CV_CAP_PROP_FRAME_WIDTH, r.width); + camera.set(CV_CAP_PROP_FRAME_HEIGHT, r.height); + } + if (fps) + camera.set(CV_CAP_PROP_FPS, fps); aruco::MarkerDetector detector; detector.setDesiredSpeed(3); - detector.setThresholdParams(11, 5); - cv::Mat color, grayscale, rvec, tvec; - + + cv::Rect last_roi(65535, 65535, 0, 0); + + cv::Mat color, color_, grayscale, rvec, tvec; + + const double stateful_coeff = 0.88; + + if (!camera.isOpened()) + { + fprintf(stderr, "aruco tracker: can't open camera\n"); + return; + } + + auto freq = cv::getTickFrequency(); + auto last_time = cv::getTickCount(); + int cur_fps = 0; + int last_fps = 0; + cv::Point2f last_centroid; + bool first = true; + while (!stop) { - if (!camera.read(color)) - break; - cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY); - const float focal_length_w = 0.5 * grayscale.cols / tan(0.5 * fov * HT_PI / 180); - const float focal_length_h = 0.5 * grayscale.rows / tan(0.5 * fov * grayscale.rows / grayscale.cols * HT_PI / 180.0); + if (!camera.read(color_)) + continue; + auto tm = cv::getTickCount(); + color_.copyTo(color); + if (s.red_only) + { + cv::Mat channel[3]; + cv::split(color, channel); + grayscale = channel[2]; + } else + cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY); + + const int scale = frame.cols > 480 ? 2 : 1; + detector.setThresholdParams(scale > 1 ? 11 : 7, 4); + + const float focal_length_w = 0.5 * grayscale.cols / tan(0.5 * s.fov * HT_PI / 180); + const float focal_length_h = 0.5 * grayscale.rows / tan(0.5 * s.fov * grayscale.rows / grayscale.cols * HT_PI / 180.0); cv::Mat intrinsics = cv::Mat::eye(3, 3, CV_32FC1); intrinsics.at<float> (0, 0) = focal_length_w; intrinsics.at<float> (1, 1) = focal_length_h; intrinsics.at<float> (0, 2) = grayscale.cols/2; intrinsics.at<float> (1, 2) = grayscale.rows/2; - + cv::Mat dist_coeffs = cv::Mat::zeros(5, 1, CV_32FC1); - - for (int i = 0; i < 5; i++) - dist_coeffs.at<float>(i) = dc[i]; - + std::vector< aruco::Marker > markers; - - detector.detect(grayscale, markers, cv::Mat(), cv::Mat(), -1, false); - + + const double size_min = 0.04; + const double size_max = 0.38; + + if (last_roi.width > 0 && + (detector.detect(grayscale(last_roi), markers, cv::Mat(), cv::Mat(), -1, false), + markers.size() == 1 && markers[0].size() == 4)) + { + detector.setMinMaxSize(std::max(0.01, size_min * grayscale.cols / last_roi.width), + std::min(1.0, size_max * grayscale.cols / last_roi.width)); + auto& m = markers.at(0); + for (int i = 0; i < 4; i++) + { + auto& p = m.at(i); + p.x += last_roi.x; + p.y += last_roi.y; + } + } + else + { + detector.setMinMaxSize(size_min, size_max); + detector.detect(grayscale, markers, cv::Mat(), cv::Mat(), -1, false); + } + if (markers.size() == 1 && markers[0].size() == 4) { - const aruco::Marker& m = markers.at(0); + const auto& m = markers.at(0); for (int i = 0; i < 4; i++) - cv::line(color, m[i], m[(i+1)%4], cv::Scalar(0, 0, 255), 4); + cv::line(color, m[i], m[(i+1)%4], cv::Scalar(0, 0, 255), scale, 8); } - - frame = color; - - if (frame.rows > 0 && !fresh) + + auto time = cv::getTickCount(); + + if ((long) (time / freq) != (long) (last_time / freq)) { - videoWidget->update_image(frame.data, frame.cols, frame.rows); - fresh = true; + last_fps = cur_fps; + cur_fps = 0; + last_time = time; } + + cur_fps++; + + char buf[128]; + + frame = color.clone(); + + ::sprintf(buf, "Hz: %d", last_fps); + cv::putText(frame, buf, cv::Point(10, 32), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(0, 255, 0), scale); + ::sprintf(buf, "Jiffies: %ld", (long) (10000 * (time - tm) / freq)); + cv::putText(frame, buf, cv::Point(10, 54), cv::FONT_HERSHEY_PLAIN, scale, cv::Scalar(80, 255, 0), scale); if (markers.size() == 1 && markers[0].size() == 4) { - const aruco::Marker& m = markers.at(0); - const float size = 7; + const auto& m = markers.at(0); + const float size = 40; + const double p = s.marker_pitch; + const double sq = sin(p * HT_PI / 180); + const double cq = cos(p * HT_PI / 180); + cv::Mat obj_points(4,3,CV_32FC1); - obj_points.at<float>(1,0)=-size; - obj_points.at<float>(1,1)=-size; - obj_points.at<float>(1,2)=0; - obj_points.at<float>(2,0)=size; - obj_points.at<float>(2,1)=-size; - obj_points.at<float>(2,2)=0; - obj_points.at<float>(3,0)=size; - obj_points.at<float>(3,1)=size; - obj_points.at<float>(3,2)=0; - obj_points.at<float>(0,0)=-size; - obj_points.at<float>(0,1)=size; - obj_points.at<float>(0,2)=0; - - cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, false, cv::ITERATIVE); - + obj_points.at<float>(1,0)=-size + s.headpos_x; + obj_points.at<float>(1,1)=-size * cq + s.headpos_y; + obj_points.at<float>(1,2)=-size * sq + s.headpos_z; + obj_points.at<float>(2,0)=size + s.headpos_x; + obj_points.at<float>(2,1)=-size * cq + s.headpos_y; + obj_points.at<float>(2,2)=-size * sq + s.headpos_z; + obj_points.at<float>(3,0)=size + s.headpos_x; + obj_points.at<float>(3,1)=size * cq + s.headpos_y; + obj_points.at<float>(3,2)=size * sq + s.headpos_z; + obj_points.at<float>(0,0)=-size + s.headpos_x; + obj_points.at<float>(0,1)=size * cq + s.headpos_y; + obj_points.at<float>(0,2)=size * sq + s.headpos_z; + + last_roi = cv::Rect(65535, 65535, 0, 0); + + for (int i = 0; i < 4; i++) + { + auto foo = m.at(i); + last_roi.x = std::min<int>(foo.x, last_roi.x); + last_roi.y = std::min<int>(foo.y, last_roi.y); + last_roi.width = std::max<int>(foo.x, last_roi.width); + last_roi.height = std::max<int>(foo.y, last_roi.height); + } + { + last_roi.width -= last_roi.x; + last_roi.height -= last_roi.y; + last_roi.x -= last_roi.width * stateful_coeff; + last_roi.y -= last_roi.height * stateful_coeff; + last_roi.width *= stateful_coeff * 3; + last_roi.height *= stateful_coeff * 3; + last_roi.x = std::max<int>(0, last_roi.x); + last_roi.y = std::max<int>(0, last_roi.y); + last_roi.width = std::min<int>(grayscale.cols - last_roi.x, last_roi.width); + last_roi.height = std::min<int>(grayscale.rows - last_roi.y, last_roi.height); + } + + cv::solvePnP(obj_points, m, intrinsics, dist_coeffs, rvec, tvec, !first, cv::ITERATIVE); + first = false; cv::Mat rotation_matrix = cv::Mat::zeros(3, 3, CV_64FC1); - cv::Mat junk1(3, 3, CV_64FC1), junk2(3, 3, CV_64FC1); - cv::Rodrigues(rvec, rotation_matrix); - - cv::Vec3d foo = cv::RQDecomp3x3(rotation_matrix, junk1, junk2); - - QMutexLocker lck(&mtx); - - for (int i = 0; i < 3; i++) - pose[i] = tvec.at<double>(i); - - pose[Yaw] = foo[1]; - pose[Pitch] = -foo[0]; - pose[Roll] = foo[2]; - - pose[Yaw] -= atan(pose[TX] / pose[TZ]) * 180 / HT_PI; - pose[Pitch] -= atan(pose[TY] / pose[TZ]) * 180 / HT_PI; + + { + cv::Vec3d euler = cv::RQDecomp3x3(rotation_matrix, junk1, junk2); + + if (fabs(euler[0]) + fabs(s.marker_pitch) > 60) + { + first = true; + qDebug() << "reset levmarq due to pitch breakage"; + } + + QMutexLocker lck(&mtx); + + for (int i = 0; i < 3; i++) + pose[i] = tvec.at<double>(i); + + pose[Yaw] = euler[1]; + pose[Pitch] = -euler[0]; + pose[Roll] = euler[2]; + } + + std::vector<cv::Point2f> repr2; + std::vector<cv::Point3f> centroid; + centroid.push_back(cv::Point3f(0, 0, 0)); + cv::projectPoints(centroid, rvec, tvec, intrinsics, dist_coeffs, repr2); + + { + auto s = cv::Scalar(255, 0, 255); + cv::circle(frame, repr2.at(0), 4, s, -1); + } + + last_centroid = repr2[0]; + } + else + { + last_roi = cv::Rect(65535, 65535, 0, 0); + first = true; } + + if (frame.rows > 0) + videoWidget->update_image(frame); } } -bool Tracker::GiveHeadPoseData(double *data) +void Tracker::GetHeadPoseData(double *data) { QMutexLocker lck(&mtx); - if (enableRX) + if (s.eyaw) data[Yaw] = pose[Yaw]; - if (enableRY) + if (s.epitch) data[Pitch] = pose[Pitch]; - if (enableRZ) + if (s.eroll) data[Roll] = pose[Roll]; - if (enableTX) - data[TX] = pose[TX]; - if (enableTY) - data[TY] = pose[TY]; - if (enableTZ) - data[TZ] = pose[TZ]; - - return true; + if (s.ex) + data[TX] = pose[TX] * .1; + if (s.ey) + data[TY] = pose[TY] * .1; + if (s.ez) + data[TZ] = pose[TZ] * .1; } class TrackerDll : public Metadata { // ITrackerDll interface - void Initialize() {} void getFullName(QString *strToBeFilled); void getShortName(QString *strToBeFilled); void getDescription(QString *strToBeFilled); @@ -349,163 +445,39 @@ extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDial TrackerControls::TrackerControls() { + tracker = nullptr; ui.setupUi(this); setAttribute(Qt::WA_NativeWindow, true); - connect(ui.cameraName, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.cameraFPS, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.cameraFOV, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(double))); - connect(ui.rx, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.ry, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.rz, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.tx, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.ty, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.tz, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int))); - connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.buttonOK, SIGNAL(clicked()), this, SLOT(doOK())); - //connect(ui.buttonSettings, SIGNAL(clicked()), this, SLOT(cameraSettings())); - loadSettings(); - settingsDirty = false; -} - -TrackerControls::~TrackerControls() -{ -} - -void TrackerControls::showEvent(QShowEvent *event) -{ -} - -void TrackerControls::Initialize(QWidget* parent) -{ - loadSettings(); - show(); -} - -void TrackerControls::loadSettings() -{ - ui.cameraName->clear(); - QList<QString> names = get_camera_names(); - names.prepend("Any available"); - ui.cameraName->addItems(names); - QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - iniFile.beginGroup( "aruco-Tracker" ); - ui.cameraName->setCurrentIndex(iniFile.value("camera-index", -1).toInt() + 1); - ui.cameraFOV->setValue(iniFile.value("fov", 56).toFloat()); - int fps; - switch (iniFile.value("fps", 0).toInt()) - { - default: - case 0: - fps = 0; - break; - case 30: - fps = 1; - break; - case 60: - fps = 2; - break; - case 120: - fps = 3; - break; - } - ui.cameraFPS->setCurrentIndex(fps); - ui.rx->setCheckState(iniFile.value("enable-rx", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.ry->setCheckState(iniFile.value("enable-ry", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.rz->setCheckState(iniFile.value("enable-rz", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.tx->setCheckState(iniFile.value("enable-tx", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.ty->setCheckState(iniFile.value("enable-ty", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.tz->setCheckState(iniFile.value("enable-tz", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.resolution->setCurrentIndex(iniFile.value("resolution", 0).toInt()); - - ui.doubleSpinBox->setValue(iniFile.value("dc0").toDouble()); - ui.doubleSpinBox_2->setValue(iniFile.value("dc1").toDouble()); - ui.doubleSpinBox_3->setValue(iniFile.value("dc2").toDouble()); - ui.doubleSpinBox_4->setValue(iniFile.value("dc3").toDouble()); - ui.doubleSpinBox_5->setValue(iniFile.value("dc4").toDouble()); - - iniFile.endGroup(); - settingsDirty = false; -} - -void TrackerControls::save() -{ - QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - - iniFile.beginGroup( "aruco-Tracker" ); - iniFile.setValue("fov", ui.cameraFOV->value()); - int fps; - switch (ui.cameraFPS->currentIndex()) - { - case 0: - default: - fps = 0; - break; - case 1: - fps = 30; - break; - case 2: - fps = 60; - break; - case 3: - fps = 120; - break; - } - iniFile.setValue("fps", fps); - iniFile.setValue("camera-index", ui.cameraName->currentIndex() - 1); - iniFile.setValue("enable-rx", ui.rx->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-ry", ui.ry->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-rz", ui.rz->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-tx", ui.tx->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-ty", ui.ty->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-tz", ui.tz->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("resolution", ui.resolution->currentIndex()); - - iniFile.setValue("dc0", ui.doubleSpinBox->value()); - iniFile.setValue("dc1", ui.doubleSpinBox_2->value()); - iniFile.setValue("dc2", ui.doubleSpinBox_3->value()); - iniFile.setValue("dc3", ui.doubleSpinBox_4->value()); - iniFile.setValue("dc4", ui.doubleSpinBox_5->value()); - - iniFile.endGroup(); - settingsDirty = false; + tie_setting(s.camera_index, ui.cameraName); + tie_setting(s.resolution, ui.resolution); + tie_setting(s.force_fps, ui.cameraFPS); + tie_setting(s.fov, ui.cameraFOV); + tie_setting(s.eyaw, ui.rx); + tie_setting(s.epitch, ui.ry); + tie_setting(s.eroll, ui.rz); + tie_setting(s.ex, ui.tx); + tie_setting(s.ey, ui.ty); + tie_setting(s.ez, ui.tz); + tie_setting(s.headpos_x, ui.cx); + tie_setting(s.headpos_y, ui.cy); + tie_setting(s.headpos_z, ui.cz); + tie_setting(s.red_only, ui.red_only); + tie_setting(s.marker_pitch, ui.marker_pitch); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + ui.cameraName->addItems(get_camera_names()); } void TrackerControls::doOK() { - save(); + s.b->save(); + if (tracker) + tracker->reload(); this->close(); } void TrackerControls::doCancel() { - if (settingsDirty) { - int ret = QMessageBox::question ( this, - "Settings have changed", - "Do you want to save the settings?", - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, - QMessageBox::Discard ); - - switch (ret) { - case QMessageBox::Save: - save(); - this->close(); - break; - case QMessageBox::Discard: - this->close(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; - } - } - else { - this->close(); - } + s.b->revert(); + this->close(); } diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h index 7f21f020..4cab84b5 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h @@ -10,46 +10,63 @@ #include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "ui_aruco-trackercontrols.h" -#include "video_widget.h" +#include "ar_video_widget.h" #include <QObject> -#include <QTimer> #include <QThread> #include <QMutex> #include <QHBoxLayout> +#include <QDialog> #include <opencv2/opencv.hpp> +#include <opencv/highgui.h> +#include "facetracknoir/options.h" +using namespace options; -class Tracker : public QThread, public ITracker +struct settings { + pbundle b; + value<double> fov, headpos_x, headpos_y, headpos_z; + value<int> camera_index, force_fps, resolution; + value<bool> red_only; + value<bool> eyaw, epitch, eroll, ex, ey, ez; + value<double> marker_pitch; + settings() : + b(bundle("aruco-tracker")), + fov(b, "field-of-view", 56), + headpos_x(b, "headpos-x", 0), + headpos_y(b, "headpos-y", 0), + headpos_z(b, "headpos-z", 0), + camera_index(b, "camera-index", 0), + force_fps(b, "force-fps", 0), + resolution(b, "force-resolution", 0), + red_only(b, "red-only", false), + eyaw(b, "enable-y", true), + epitch(b, "enable-p", true), + eroll(b, "enable-r", true), + ex(b, "enable-x", true), + ey(b, "enable-y", true), + ez(b, "enable-z", true), + marker_pitch(b, "marker-pitch", 0) + {} +}; + +class Tracker : protected QThread, public ITracker { Q_OBJECT public: Tracker(); - ~Tracker(); + virtual ~Tracker(); void StartTracker(QFrame* frame); - bool GiveHeadPoseData(double *data); - bool enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ; - bool NeedsTimeToFinish() { - return true; - } - void WaitForExit() { - stop = true; - wait(); - } + void GetHeadPoseData(double *data); void run(); + void reload() { s.b->reload(); } private: QMutex mtx; - QTimer timer; - VideoWidget* videoWidget; - QHBoxLayout* layout; - volatile bool fresh, stop; - float fov; - int camera_index; - float dc[5]; - int force_fps, force_width, force_height; - void load_settings(); + volatile bool stop; + QHBoxLayout* layout; + ArucoVideoWidget* videoWidget; + settings s; double pose[6]; cv::Mat frame; -private slots: - void paint_widget(); + cv::VideoCapture camera; }; // Widget that has controls for FTNoIR protocol client-settings. @@ -57,27 +74,20 @@ class TrackerControls : public QWidget, public ITrackerDialog { Q_OBJECT public: - - explicit TrackerControls(); - virtual ~TrackerControls(); - void showEvent ( QShowEvent * event ); - - void Initialize(QWidget *parent); - void registerTracker(ITracker *tracker) {} - void unRegisterTracker() {} - + TrackerControls(); + void registerTracker(ITracker * x) { + tracker = dynamic_cast<Tracker*>(x); + } + void unRegisterTracker() { + tracker = nullptr; + } private: Ui::Form ui; - void loadSettings(); - void save(); - bool settingsDirty; - + Tracker* tracker; + settings s; private slots: void doOK(); void doCancel(); - void settingChanged() { settingsDirty = true; } - void settingChanged(int) { settingsDirty = true; } - void settingChanged(double) { settingsDirty = true; } }; #endif diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h index 1e53f802..ffdc5262 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco_dll.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 Stanis³aw Halik <sthalik@misaki.pl> +/* Copyright (c) 2013 StanisÅ‚aw 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 @@ -12,7 +12,6 @@ class TrackerDll : public Metadata { // ITrackerDll interface - void Initialize() {} void getFullName(QString *strToBeFilled); void getShortName(QString *strToBeFilled); void getDescription(QString *strToBeFilled); diff --git a/ftnoir_tracker_aruco/include/boarddetector.h b/ftnoir_tracker_aruco/include/boarddetector.h index a0ee2361..4770b5c9 100644 --- a/ftnoir_tracker_aruco/include/boarddetector.h +++ b/ftnoir_tracker_aruco/include/boarddetector.h @@ -134,6 +134,6 @@ private: }; -}; +} #endif diff --git a/ftnoir_tracker_aruco/include/cvdrawingutils.h b/ftnoir_tracker_aruco/include/cvdrawingutils.h index ff67242f..38e9986e 100644 --- a/ftnoir_tracker_aruco/include/cvdrawingutils.h +++ b/ftnoir_tracker_aruco/include/cvdrawingutils.h @@ -46,7 +46,7 @@ namespace aruco static void draw3dCube(cv::Mat &Image,Board &m,const CameraParameters &CP); }; -}; +} #endif diff --git a/ftnoir_tracker_aruco/include/markerdetector.h b/ftnoir_tracker_aruco/include/markerdetector.h index 35369cea..4d6e7b90 100644 --- a/ftnoir_tracker_aruco/include/markerdetector.h +++ b/ftnoir_tracker_aruco/include/markerdetector.h @@ -52,10 +52,13 @@ class ARUCO_EXPORTS MarkerDetector contour=M.contour; idx=M.idx; } - MarkerCandidate & operator=(const MarkerCandidate &M){ + MarkerCandidate operator=(const MarkerCandidate &M){ + if (this == &M) + return *this; (*(Marker*)this)=(*(Marker*)&M); contour=M.contour; idx=M.idx; + return M; } vector<cv::Point> contour;//all the points of its contour @@ -350,9 +353,5 @@ private: void draw(cv::Mat out,const std::vector<Marker> &markers ); }; - - - - -}; +} #endif diff --git a/ftnoir_tracker_aruco/video_widget.cpp b/ftnoir_tracker_aruco/video_widget.cpp deleted file mode 100644 index 84cba6a3..00000000 --- a/ftnoir_tracker_aruco/video_widget.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 "video_widget.h" - -#include <QDebug> - -using namespace std; - -void VideoWidget::update_image(unsigned char *frame, int width, int height) -{ - QMutexLocker foo(&mtx); - QImage qframe = QImage(width, height, QImage::Format_RGB888); - uchar* data = qframe.bits(); - const int pitch = qframe.bytesPerLine(); - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - const int pos = 3 * (y*width + x); - data[y * pitch + x * 3 + 0] = frame[pos + 2]; - data[y * pitch + x * 3 + 1] = frame[pos + 1]; - data[y * pitch + x * 3 + 2] = frame[pos + 0]; - } - qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); - pixmap = QPixmap::fromImage(qframe); -} |