a huge commit of everything else which doesn't fit in a previous one
This commit is contained in:
parent
aeae6770d9
commit
e5a1f099b9
25 changed files with 531 additions and 326 deletions
36
Pastie.pro
36
Pastie.pro
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
QT += core gui opengl multimedia
|
QT += core gui opengl multimedia serialport
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
@ -31,11 +31,20 @@ SOURCES += main.cpp\
|
||||||
painter.cpp \
|
painter.cpp \
|
||||||
filters/maxchannel.cpp \
|
filters/maxchannel.cpp \
|
||||||
filters/normalize.cpp \
|
filters/normalize.cpp \
|
||||||
filters/shapedetect.cpp \
|
|
||||||
filters/setting.cpp \
|
filters/setting.cpp \
|
||||||
filters/result.cpp \
|
|
||||||
filters/blur.cpp \
|
filters/blur.cpp \
|
||||||
filters/watershed.cpp
|
filters/watershed.cpp \
|
||||||
|
filters/derivative.cpp \
|
||||||
|
robot.cpp \
|
||||||
|
tabrobot.cpp \
|
||||||
|
filters/pathplanner.cpp \
|
||||||
|
filters/paddetect.cpp \
|
||||||
|
pad.cpp \
|
||||||
|
filters/resize.cpp \
|
||||||
|
filters/padfilter.cpp \
|
||||||
|
rangeslider.cpp \
|
||||||
|
filters/rectify.cpp \
|
||||||
|
filters/rotate.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
camera.h \
|
camera.h \
|
||||||
|
@ -56,11 +65,22 @@ HEADERS += mainwindow.h \
|
||||||
filters.h \
|
filters.h \
|
||||||
filters/maxchannel.h \
|
filters/maxchannel.h \
|
||||||
filters/normalize.h \
|
filters/normalize.h \
|
||||||
filters/shapedetect.h \
|
|
||||||
filters/setting.h \
|
filters/setting.h \
|
||||||
filters/result.h \
|
filters/result.h \
|
||||||
filters/blur.h \
|
filters/blur.h \
|
||||||
filters/watershed.h
|
filters/watershed.h \
|
||||||
|
filters/derivative.h \
|
||||||
|
robot.h \
|
||||||
|
tabrobot.h \
|
||||||
|
filters/pathplanner.h \
|
||||||
|
filters/paddetect.h \
|
||||||
|
pad.h \
|
||||||
|
filters/resize.h \
|
||||||
|
qspanslider.h \
|
||||||
|
rangeslider.h \
|
||||||
|
range.h \
|
||||||
|
filters/rectify.h \
|
||||||
|
filters/rotate.h
|
||||||
|
|
||||||
SOURCES += filters/filter.cpp \
|
SOURCES += filters/filter.cpp \
|
||||||
filters/undistort.cpp \
|
filters/undistort.cpp \
|
||||||
|
@ -70,7 +90,6 @@ SOURCES += filters/filter.cpp \
|
||||||
filters/morph.cpp \
|
filters/morph.cpp \
|
||||||
filters/convert.cpp \
|
filters/convert.cpp \
|
||||||
filters/pattern.cpp \
|
filters/pattern.cpp \
|
||||||
filters/padfilter.cpp \
|
|
||||||
filters/edgedetect.cpp \
|
filters/edgedetect.cpp \
|
||||||
filters/channel.cpp \
|
filters/channel.cpp \
|
||||||
filters/perspective.cpp
|
filters/perspective.cpp
|
||||||
|
@ -95,7 +114,8 @@ FORMS += mainwindow.ui \
|
||||||
tabimages.ui \
|
tabimages.ui \
|
||||||
tabcamera.ui \
|
tabcamera.ui \
|
||||||
tabfilters.ui \
|
tabfilters.ui \
|
||||||
tabpads.ui
|
tabpads.ui \
|
||||||
|
tabrobot.ui
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
INCLUDEPATH += /usr/local/include
|
INCLUDEPATH += /usr/local/include
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 3.3.0, 2014-12-20T13:25:42. -->
|
<!-- Written by QtCreator 3.3.0, 2015-01-15T11:48:54. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/stv0g/workspace/rwth-dbv/code/build-Pastie-Desktop_Qt_5_4_0_clang_64bit-Debug</value>
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/stv0g/workspace/rwth/dbv/code/build-Pastie-Desktop_Qt_5_4_0_clang_64bit-Debug</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
@ -210,7 +210,7 @@
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">/usr/local/bin/valgrind</value>
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||||
<value type="int">0</value>
|
<value type="int">0</value>
|
||||||
<value type="int">1</value>
|
<value type="int">1</value>
|
||||||
|
@ -231,13 +231,13 @@
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Pastie</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Pastie</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Pastie2</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/stv0g/workspace/rwth-dbv/code/pastie/Pastie.pro</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/stv0g/workspace/rwth/dbv/code/pastie/Pastie.pro</value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">google/*</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">~/workspace/rwth/dbv/data/omd3/*</value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">Pastie.pro</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">Pastie.pro</value>
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory">/Users/stv0g/workspace/rwth-dbv/data</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
|
||||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
|
|
@ -21,7 +21,7 @@ void Camera::reset()
|
||||||
matrix = Mat::eye(3, 3, CV_32F);
|
matrix = Mat::eye(3, 3, CV_32F);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::calibrate(list<Image *> imgs, Pattern *pattern)
|
bool Camera::calibrate(QList<Image *> imgs, Pattern *pattern)
|
||||||
{
|
{
|
||||||
vector<vector<Point2f>> imagePoints;
|
vector<vector<Point2f>> imagePoints;
|
||||||
vector<vector<Point3f>> objectPoints;
|
vector<vector<Point3f>> objectPoints;
|
||||||
|
|
2
camera.h
2
camera.h
|
@ -18,7 +18,7 @@ class Camera
|
||||||
public:
|
public:
|
||||||
Camera(Source *s);
|
Camera(Source *s);
|
||||||
|
|
||||||
bool calibrate(list<Image *> imgs, Pattern *pattern);
|
bool calibrate(QList<Image *> imgs, Pattern *pattern);
|
||||||
|
|
||||||
/* Getters */
|
/* Getters */
|
||||||
const Mat & getDistCoeffs() { return distCoeffs; }
|
const Mat & getDistCoeffs() { return distCoeffs; }
|
||||||
|
|
45
cast.h
45
cast.h
|
@ -18,41 +18,48 @@ inline QImage toQImage(const Mat &mat)
|
||||||
{
|
{
|
||||||
Mat *conv = new Mat;
|
Mat *conv = new Mat;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (mat.channels()) {
|
switch (mat.channels()) {
|
||||||
case 3: cvtColor(mat, *conv, COLOR_RGB2RGBA); break;
|
case 3: cvtColor(mat, *conv, COLOR_RGB2RGBA); break;
|
||||||
case 1: cvtColor(mat, *conv, COLOR_GRAY2RGBA); break;
|
case 1: cvtColor(mat, *conv, COLOR_GRAY2RGBA); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QImage((const unsigned char *) conv->data, conv->cols, conv->rows, conv->step,
|
return QImage((const unsigned char *) conv->data, conv->cols, conv->rows, conv->step,
|
||||||
QImage::Format_RGB32, [] (void * data) { ((Mat *) data)->release(); }, conv);
|
QImage::Format_RGB32, [](void * data) { ((Mat *) data)->release(); }, conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QTransform toQTransform(const Mat &m)
|
inline QTransform toQTransform(const Mat &m)
|
||||||
{
|
{
|
||||||
return QTransform(
|
if (m.size() == Size(3, 3))
|
||||||
m.at<float>(0,0), m.at<float>(0,1), m.at<float>(0,2),
|
return QTransform( m.at<float>(0,0), m.at<float>(0,1), m.at<float>(0,2),
|
||||||
m.at<float>(1,0), m.at<float>(1,1), m.at<float>(1,2),
|
m.at<float>(1,0), m.at<float>(1,1), m.at<float>(1,2),
|
||||||
m.at<float>(2,0), m.at<float>(2,1), m.at<float>(2,2));
|
m.at<float>(2,0), m.at<float>(2,1), m.at<float>(2,2) );
|
||||||
|
else if (m.size() == Size(2, 3))
|
||||||
|
return QTransform( m.at<float>(0,0), m.at<float>(0,1),
|
||||||
|
m.at<float>(1,0), m.at<float>(1,1),
|
||||||
|
m.at<float>(0,2), m.at<float>(1,2) );
|
||||||
|
else if (m.size() == Size(2, 2))
|
||||||
|
return QTransform( m.at<float>(0,0), m.at<float>(0,1),
|
||||||
|
m.at<float>(1,0), m.at<float>(1,1), 0, 0 );
|
||||||
|
else
|
||||||
|
return QTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QSize toQt(const Size2i &s) { return QSize (s.width, s.height); }
|
inline QSize toQt(const Size2i &s) { return QSize (s.width, s.height); }
|
||||||
inline QSizeF toQt(const Size2d &s) { return QSizeF(s.width, s.height); }
|
inline QSizeF toQt(const Size2f &s) { return QSizeF(s.width, s.height); }
|
||||||
|
|
||||||
inline QPoint toQt(const Point2i &p) { return QPoint (p.x, p.y); }
|
inline QPoint toQt(const Point2i &p) { return QPoint (p.x, p.y); }
|
||||||
inline QPointF toQt(const Point2d &p) { return QPointF(p.x, p.y); }
|
inline QPointF toQt(const Point2f &p) { return QPointF(p.x, p.y); }
|
||||||
|
|
||||||
inline QRect toQt(const Rect2i &r) { return QRect (r.x, r.y, r.width, r.height); }
|
inline QRect toQt(const Rect2i &r) { return QRect (r.x, r.y, r.width, r.height); }
|
||||||
inline QRectF toQt(const Rect2d &r) { return QRectF(r.x, r.y, r.width, r.height); }
|
inline QRectF toQt(const Rect2f &r) { return QRectF(r.x, r.y, r.width, r.height); }
|
||||||
|
|
||||||
inline Size2i toCv(const QSize &s) { return Size2i(s.width(), s.height()); }
|
inline Size2i toCv(const QSize &s) { return Size2i(s.width(), s.height()); }
|
||||||
inline Size2d toCv(const QSizeF &s) { return Size2d(s.width(), s.height()); }
|
inline Size2d toCv(const QSizeF &s) { return Size2d(s.width(), s.height()); }
|
||||||
|
|
||||||
inline Point2i toCv(const QPoint &p) { return Point2i(p.x(), p.y()); }
|
inline Point2i toCv(const QPoint &p) { return Point2i(p.x(), p.y()); }
|
||||||
inline Point2d toCv(const QPointF &p) { return Point2d(p.x(), p.y()); }
|
inline Point2d toCv(const QPointF &p) { return Point2d(p.x(), p.y()); }
|
||||||
|
|
||||||
inline Rect2i toCv(const QRect &r) { return Rect2i(r.x(), r.y(), r.width(), r.height()); }
|
inline Rect2i toCv(const QRect &r) { return Rect2i(r.x(), r.y(), r.width(), r.height()); }
|
||||||
inline Rect2d toCv(const QRectF &r) { return Rect2d(r.x(), r.y(), r.width(), r.height()); }
|
inline Rect2d toCv(const QRectF &r) { return Rect2d(r.x(), r.y(), r.width(), r.height()); }
|
||||||
|
|
||||||
#endif // CAST_H
|
#endif // CAST_H
|
||||||
|
|
|
@ -6,8 +6,8 @@ FilterList::FilterList(QObject *parent) :
|
||||||
QAbstractTableModel(parent),
|
QAbstractTableModel(parent),
|
||||||
selection(this)
|
selection(this)
|
||||||
{
|
{
|
||||||
connect(&selection, &QItemSelectionModel::currentChanged, [&] (QModelIndex i, QModelIndex) {
|
connect(&selection, &QItemSelectionModel::currentChanged, [&] (QModelIndex current, QModelIndex) {
|
||||||
emit filterSelected(at(i.row()));
|
emit filterSelected(at(current.row()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ QVariant FilterList::data(const QModelIndex &index, int role) const
|
||||||
case 0: return (filter->isEnabled()) ? Qt::Checked: Qt::Unchecked;
|
case 0: return (filter->isEnabled()) ? Qt::Checked: Qt::Unchecked;
|
||||||
case 1: return (filter->isShown()) ? Qt::Checked: Qt::Unchecked;
|
case 1: return (filter->isShown()) ? Qt::Checked: Qt::Unchecked;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -56,11 +57,11 @@ bool FilterList::setData(const QModelIndex &index, const QVariant &value, int ro
|
||||||
case 0: filter->setEnabled(value == Qt::Checked);
|
case 0: filter->setEnabled(value == Qt::Checked);
|
||||||
case 1: filter->setShow(value == Qt::Checked); break;
|
case 1: filter->setShow(value == Qt::Checked); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit filtersChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit filtersChanged();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +108,11 @@ void FilterList::add(Filter *filter)
|
||||||
|
|
||||||
void FilterList::execute(Image *img)
|
void FilterList::execute(Image *img)
|
||||||
{
|
{
|
||||||
img->filtered = img->original.clone();
|
img->getMat().release();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (auto filter : *this) {
|
for (auto filter : *this)
|
||||||
img->applyFilter(filter);
|
img->applyFilter(filter);
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
qCritical("%s", e.msg.c_str());
|
qCritical("%s", e.msg.c_str());
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,14 @@ void FilterList::execute(Image *img)
|
||||||
|
|
||||||
void FilterList::reset()
|
void FilterList::reset()
|
||||||
{
|
{
|
||||||
|
qDebug() << "Reset filters";
|
||||||
for (Filter *filter : *this)
|
for (Filter *filter : *this)
|
||||||
filter->reset();
|
filter->reset();
|
||||||
|
|
||||||
|
emit filtersChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter * FilterList::getCurrent()
|
||||||
|
{
|
||||||
|
return value(selection.currentIndex().row());
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ class FilterList :
|
||||||
void add(Filter *filt);
|
void add(Filter *filt);
|
||||||
void execute(Image *img);
|
void execute(Image *img);
|
||||||
|
|
||||||
|
Filter * getCurrent();
|
||||||
|
|
||||||
QItemSelectionModel selection;
|
QItemSelectionModel selection;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -13,10 +13,16 @@
|
||||||
#include "filters/normalize.h"
|
#include "filters/normalize.h"
|
||||||
#include "filters/pattern.h"
|
#include "filters/pattern.h"
|
||||||
#include "filters/perspective.h"
|
#include "filters/perspective.h"
|
||||||
#include "filters/shapedetect.h"
|
#include "filters/paddetect.h"
|
||||||
|
#include "filters/padfilter.h"
|
||||||
#include "filters/threshold.h"
|
#include "filters/threshold.h"
|
||||||
#include "filters/undistort.h"
|
#include "filters/undistort.h"
|
||||||
#include "filters/watershed.h"
|
#include "filters/watershed.h"
|
||||||
|
#include "filters/derivative.h"
|
||||||
|
#include "filters/rectify.h"
|
||||||
|
#include "filters/pathplanner.h"
|
||||||
|
#include "filters/resize.h"
|
||||||
|
#include "filters/rotate.h"
|
||||||
|
|
||||||
#endif // FILTERS_H
|
#endif // FILTERS_H
|
||||||
|
|
||||||
|
|
40
image.cpp
40
image.cpp
|
@ -7,17 +7,16 @@ using namespace cv;
|
||||||
|
|
||||||
Image::Image(Mat m, QString p) :
|
Image::Image(Mat m, QString p) :
|
||||||
path(p),
|
path(p),
|
||||||
original(m.clone()),
|
source(m),
|
||||||
loaded(false),
|
loaded(true),
|
||||||
saved(false)
|
saved(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Image::Image(QString p) :
|
Image::Image(QString p) :
|
||||||
path(p),
|
path(p),
|
||||||
|
loaded(false),
|
||||||
saved(false)
|
saved(false)
|
||||||
{
|
{ }
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
Image::~Image()
|
Image::~Image()
|
||||||
{
|
{
|
||||||
|
@ -30,8 +29,8 @@ void Image::load(QString p)
|
||||||
if (p != "")
|
if (p != "")
|
||||||
path = p;
|
path = p;
|
||||||
|
|
||||||
original = cv::imread(path.toStdString());
|
source = cv::imread(path.toStdString());
|
||||||
loaded = (bool) original.data;
|
loaded = (bool) source.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::save(QString p)
|
void Image::save(QString p)
|
||||||
|
@ -39,16 +38,33 @@ void Image::save(QString p)
|
||||||
if (p != "")
|
if (p != "")
|
||||||
path = p;
|
path = p;
|
||||||
|
|
||||||
saved = imwrite(path.toStdString(), original);
|
saved = imwrite(path.toStdString(), getMat());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::applyFilter(Filter *filter)
|
void Image::applyFilter(Filter *filter)
|
||||||
{
|
{
|
||||||
// FIXME!
|
|
||||||
// if (results.contains(filter))
|
|
||||||
// delete results[filter];
|
|
||||||
|
|
||||||
Result *result = filter->apply(this);
|
Result *result = filter->apply(this);
|
||||||
if (result)
|
if (result)
|
||||||
results[filter] = result;
|
results[filter] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mat & Image::getMat()
|
||||||
|
{
|
||||||
|
if (!filtered.data)
|
||||||
|
filtered = getSourceMat().clone();
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Mat & Image::getSourceMat()
|
||||||
|
{
|
||||||
|
if (!loaded)
|
||||||
|
load();
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::setSourceMat(const Mat &m)
|
||||||
|
{
|
||||||
|
source = m;
|
||||||
|
}
|
||||||
|
|
39
image.h
39
image.h
|
@ -15,29 +15,36 @@ class Result;
|
||||||
|
|
||||||
class Image
|
class Image
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Image(Mat mat = Mat(), QString path = "");
|
Image(Mat mat = Mat(), QString path = QString());
|
||||||
Image(QString p);
|
Image(QString p);
|
||||||
~Image();
|
~Image();
|
||||||
|
|
||||||
void save(QString path = "");
|
void save(QString path = QString());
|
||||||
void load(QString path = "");
|
void load(QString path = QString());
|
||||||
|
|
||||||
QString path;
|
void applyFilter(Filter *filter);
|
||||||
|
|
||||||
Mat original;
|
/* Getter */
|
||||||
Mat filtered;
|
bool isLoaded() const { return loaded; }
|
||||||
|
bool isSaved() const { return saved; }
|
||||||
|
|
||||||
void applyFilter(Filter *filter);
|
Result * getResult(Filter *f) { return results[f]; }
|
||||||
|
QString getPath() { return path; }
|
||||||
|
Mat & getMat();
|
||||||
|
|
||||||
/* Getter */
|
const Mat & getSourceMat();
|
||||||
Result * getResult(Filter *f) { return results[f]; }
|
void setSourceMat(const Mat &m);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QMap<Filter*, Result*> results;
|
QMap<Filter*, Result*> results;
|
||||||
|
|
||||||
bool loaded;
|
QString path;
|
||||||
bool saved;
|
Mat source;
|
||||||
|
Mat filtered;
|
||||||
|
|
||||||
|
bool loaded;
|
||||||
|
bool saved;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGE_H
|
#endif // IMAGE_H
|
||||||
|
|
|
@ -10,7 +10,9 @@ ImageList::ImageList(QObject *parent) :
|
||||||
QAbstractTableModel(parent),
|
QAbstractTableModel(parent),
|
||||||
selection(this)
|
selection(this)
|
||||||
{
|
{
|
||||||
connect(&selection, &QItemSelectionModel::currentChanged, this, &ImageList::currentImage);
|
connect(&selection, &QItemSelectionModel::currentChanged, [&](QModelIndex current, QModelIndex) {
|
||||||
|
emit newImage(at(current.row()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageList::~ImageList()
|
ImageList::~ImageList()
|
||||||
|
@ -20,26 +22,32 @@ ImageList::~ImageList()
|
||||||
|
|
||||||
int ImageList::rowCount(const QModelIndex &) const {
|
int ImageList::rowCount(const QModelIndex &) const {
|
||||||
return count();
|
return count();
|
||||||
};
|
}
|
||||||
|
|
||||||
int ImageList::columnCount(const QModelIndex &) const {
|
int ImageList::columnCount(const QModelIndex &) const {
|
||||||
return 6;
|
return 6;
|
||||||
};
|
}
|
||||||
|
|
||||||
QVariant ImageList::data(const QModelIndex &index, int role) const
|
QVariant ImageList::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
Image *img = at(index.row());
|
Image *img = at(index.row());
|
||||||
QFileInfo fi = QFileInfo(img->path);
|
QFileInfo fi = QFileInfo(img->getPath());
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0: return fi.baseName();
|
case 0: return fi.baseName();
|
||||||
case 1: return fi.suffix();
|
case 1: return fi.suffix().toLower();
|
||||||
case 2: return fi.size();
|
case 2: return QString("%1 kB").arg(fi.size() / 1024.0, 0, 'f', 2);
|
||||||
case 3: return img->original.cols;
|
case 3: if (img->isLoaded()) return img->getSourceMat().channels();
|
||||||
case 4: return img->original.rows;
|
case 4: if (img->isLoaded()) return img->getSourceMat().cols;
|
||||||
case 5: return img->original.channels();
|
case 5: if (img->isLoaded()) return img->getSourceMat().rows;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (role ==Qt::TextAlignmentRole) {
|
||||||
|
switch (index.column()) {
|
||||||
|
case 4: return Qt::AlignRight;
|
||||||
|
default: return Qt::AlignLeft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -51,11 +59,11 @@ QVariant ImageList::headerData(int section, Qt::Orientation orientation, int rol
|
||||||
if (orientation == Qt::Horizontal) {
|
if (orientation == Qt::Horizontal) {
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case 0: return QString(tr("Name"));
|
case 0: return QString(tr("Name"));
|
||||||
case 1: return QString(tr("Typ"));
|
case 1: return QString(tr("Type"));
|
||||||
case 2: return QString(tr("Size"));
|
case 2: return QString(tr("Size"));
|
||||||
case 3: return QString(tr("Width"));
|
case 3: return QString(tr("Channels"));
|
||||||
case 4: return QString(tr("Height"));
|
case 4: return QString(tr("Width"));
|
||||||
case 5: return QString(tr("Channels"));
|
case 5: return QString(tr("Height"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,69 +79,60 @@ void ImageList::clear() {
|
||||||
delete img;
|
delete img;
|
||||||
removeOne(img);
|
removeOne(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Image *> ImageList::selectedImages()
|
QList<Image *> ImageList::getSelected()
|
||||||
{
|
{
|
||||||
QList<Image *> sel;
|
QList<Image *> sel;
|
||||||
|
|
||||||
for (QModelIndex index : selection.selectedRows())
|
for (QModelIndex index : selection.selectedRows())
|
||||||
sel.append(at(index.row()));
|
sel.append(at(index.row()));
|
||||||
|
|
||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image * ImageList::currentImage()
|
Image * ImageList::getCurrent()
|
||||||
{
|
{
|
||||||
current = at(selection.currentIndex().row());
|
if (!selection.currentIndex().isValid())
|
||||||
emit newImage(current);
|
selection.select(createIndex(0, 0), QItemSelectionModel::Current);
|
||||||
return current;
|
|
||||||
|
return value(selection.currentIndex().row());
|
||||||
}
|
}
|
||||||
|
|
||||||
Image * ImageList::nextImage()
|
void ImageList::nextImage()
|
||||||
{
|
{
|
||||||
QModelIndex oldIdx = selection.currentIndex();
|
QModelIndex oldIdx = selection.currentIndex();
|
||||||
QModelIndex newIdx = index(oldIdx.row()-1, oldIdx.column());
|
QModelIndex newIdx = index(oldIdx.row()-1, oldIdx.column());
|
||||||
|
|
||||||
if (newIdx.isValid()) {
|
if (newIdx.isValid())
|
||||||
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
||||||
|
|
||||||
current = at(newIdx.row());
|
|
||||||
emit newImage(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
return current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image * ImageList::prevImage()
|
void ImageList::prevImage()
|
||||||
{
|
{
|
||||||
QModelIndex oldIdx = selection.currentIndex();
|
QModelIndex oldIdx = selection.currentIndex();
|
||||||
QModelIndex newIdx = index(oldIdx.row()+1, oldIdx.column());
|
QModelIndex newIdx = index(oldIdx.row()+1, oldIdx.column());
|
||||||
|
|
||||||
if (newIdx.isValid()) {
|
if (newIdx.isValid())
|
||||||
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
||||||
|
|
||||||
current = at(newIdx.row());
|
|
||||||
emit newImage(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
return current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageList::load(QStringList files)
|
void ImageList::load(QStringList files)
|
||||||
{
|
{
|
||||||
for (QString file : files)
|
QStringList valid = { "png", "jpg", "png" };
|
||||||
add(new Image(file));
|
|
||||||
|
|
||||||
current = first();
|
for (QString file : files) {
|
||||||
emit newImage(current);
|
QFileInfo checkFile(file);
|
||||||
|
if (checkFile.exists() && checkFile.isFile() &&
|
||||||
|
valid.contains(checkFile.suffix().toLower())) {
|
||||||
|
add(new Image(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageList::save(QString path)
|
void ImageList::save(QString path)
|
||||||
{
|
{
|
||||||
currentImage()->save(path);
|
getCurrent()->save(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageList::loadFilePicker()
|
void ImageList::loadFilePicker()
|
||||||
|
@ -145,8 +144,9 @@ void ImageList::loadFilePicker()
|
||||||
|
|
||||||
void ImageList::saveFilePicker()
|
void ImageList::saveFilePicker()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getSaveFileName(mwindow, tr("Save Image"), current->path,
|
QString path = QFileDialog::getSaveFileName(mwindow,
|
||||||
tr("Image Files (*.png *.jpg *.bmp)"));
|
tr("Save Image"), getCurrent()->getPath(),
|
||||||
|
tr("Image Files (*.png *.jpg *.bmp)"));
|
||||||
save(path);
|
save(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
imagelist.h
12
imagelist.h
|
@ -27,6 +27,9 @@ class ImageList :
|
||||||
|
|
||||||
QItemSelectionModel selection;
|
QItemSelectionModel selection;
|
||||||
|
|
||||||
|
QList<Image *> getSelected();
|
||||||
|
Image * getCurrent();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newImage(Image *img);
|
void newImage(Image *img);
|
||||||
|
|
||||||
|
@ -37,13 +40,8 @@ class ImageList :
|
||||||
void saveFilePicker();
|
void saveFilePicker();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
QList<Image *> selectedImages();
|
void prevImage();
|
||||||
Image * currentImage();
|
void nextImage();
|
||||||
Image * prevImage();
|
|
||||||
Image * nextImage();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Image *current;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGELIST_H
|
#endif // IMAGELIST_H
|
||||||
|
|
34
main.cpp
34
main.cpp
|
@ -23,38 +23,34 @@ int main(int argc, char *argv[])
|
||||||
foreach (const QCameraInfo &cameraInfo, cameras)
|
foreach (const QCameraInfo &cameraInfo, cameras)
|
||||||
qDebug() << "Found Qt camera: " << cameraInfo.deviceName() << ": " << cameraInfo.description();
|
qDebug() << "Found Qt camera: " << cameraInfo.deviceName() << ": " << cameraInfo.description();
|
||||||
|
|
||||||
filters = new FilterList;
|
|
||||||
images = new ImageList;
|
|
||||||
source = new Source;
|
source = new Source;
|
||||||
cam = new Camera(source);
|
cam = new Camera(source);
|
||||||
|
filters = new FilterList;
|
||||||
|
images = new ImageList;
|
||||||
mwindow = new MainWindow;
|
mwindow = new MainWindow;
|
||||||
|
|
||||||
QStringList imgs = QCoreApplication::arguments();
|
QStringList imgs = QCoreApplication::arguments();
|
||||||
imgs.removeFirst();
|
imgs.removeFirst();
|
||||||
imgs.removeDuplicates();
|
imgs.removeDuplicates();
|
||||||
imgs.sort();
|
|
||||||
images->load(imgs);
|
images->load(imgs);
|
||||||
|
|
||||||
/* Setup pipeline */
|
/* Setup pipeline */
|
||||||
#if 1
|
Pattern *pat = new Pattern(Size(2, 2), Size(60, 60), Pattern::QUADRILINEAR_MARKERS);
|
||||||
|
filters->add(pat);
|
||||||
|
filters->add(new Perspective(cam, pat));
|
||||||
|
filters->add(new Resize(Range<int>(400, 1000)));
|
||||||
|
|
||||||
filters->add(new Blur(Blur::GAUSSIAN, Size(3, 3)));
|
filters->add(new Blur(Blur::GAUSSIAN, Size(3, 3)));
|
||||||
filters->add(new KMeans(4));
|
filters->add(new KMeans(4));
|
||||||
filters->add(new Convert(COLOR_BGR2HSV));
|
filters->add(new Convert(COLOR_BGR2GRAY));
|
||||||
filters->add(new Channel(1));
|
|
||||||
//filters->add(new Convert(COLOR_BGR2GRAY));
|
|
||||||
//filters->add(new HistEqualize());
|
|
||||||
filters->add(new Threshold(Threshold::OTSU));
|
filters->add(new Threshold(Threshold::OTSU));
|
||||||
//filters->add(new EdgeDetect(80, 3));
|
|
||||||
//filters->add(new Watershed());
|
PadDetect *pads = new PadDetect();
|
||||||
filters->add(new Morph(MORPH_CLOSE, MORPH_RECT));
|
PadFilter *filter = new PadFilter(pads);
|
||||||
filters->add(new ShapeDetect());
|
|
||||||
//filters->add(new MaxChannel());
|
filters->add(pads);
|
||||||
//filters->add(new Normalize());
|
filters->add(filter);
|
||||||
#else
|
filters->add(new PathPlanner(filter, PathPlanner::NEAREST_NEIGHBOUR));
|
||||||
filters->add(new Undistort(cam));
|
|
||||||
filters->add(new Pattern(Size(13, 9), 60));
|
|
||||||
filters->add(new Perspective(cam, (Pattern *) filters->last()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mwindow->show();
|
mwindow->show();
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,17 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
static_cast<int>(0.8 * ui->splitterH->width()),
|
static_cast<int>(0.8 * ui->splitterH->width()),
|
||||||
static_cast<int>(0.2 * ui->splitterH->width())
|
static_cast<int>(0.2 * ui->splitterH->width())
|
||||||
});
|
});
|
||||||
|
ui->splitterV->setSizes({
|
||||||
|
static_cast<int>(0.75 * ui->viewer->width()),
|
||||||
|
static_cast<int>(0.25 * ui->viewer->width())
|
||||||
|
});
|
||||||
|
|
||||||
/* Connect actions */
|
/* Connect actions */
|
||||||
connect(images, &ImageList::newImage, ui->viewer, &Viewer::showImage);
|
connect(images, &ImageList::newImage, ui->viewer, &Viewer::showImage);
|
||||||
connect(source, &Source::newImage, ui->viewer, &Viewer::showImage);
|
connect(source, &Source::newImage, ui->viewer, &Viewer::showImage);
|
||||||
connect(filters, &FilterList::filtersChanged,ui->viewer, &Viewer::updateImage);
|
connect(filters, &FilterList::filtersChanged,ui->viewer, &Viewer::updateImage);
|
||||||
connect(ui->actionRedraw, &QAction::triggered, ui->viewer, &Viewer::updateImage);
|
connect(ui->actionRedraw, &QAction::triggered, ui->viewer, &Viewer::updateImage);
|
||||||
|
connect(ui->actionReset, &QAction::triggered, ui->viewer, &Viewer::reset);
|
||||||
connect(ui->actionCalibrate, &QAction::triggered, ui->tabCalibration, &TabCalibration::doCalibration);
|
connect(ui->actionCalibrate, &QAction::triggered, ui->tabCalibration, &TabCalibration::doCalibration);
|
||||||
connect(ui->actionSnapshot, &QAction::triggered, ui->tabCamera, &TabCamera::doSnapshot);
|
connect(ui->actionSnapshot, &QAction::triggered, ui->tabCamera, &TabCamera::doSnapshot);
|
||||||
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::showAbout);
|
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::showAbout);
|
||||||
|
@ -39,6 +44,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
connect(ui->actionSave, &QAction::triggered, images, &ImageList::saveFilePicker);
|
connect(ui->actionSave, &QAction::triggered, images, &ImageList::saveFilePicker);
|
||||||
connect(ui->actionNextImage, &QAction::triggered, images, &ImageList::nextImage);
|
connect(ui->actionNextImage, &QAction::triggered, images, &ImageList::nextImage);
|
||||||
connect(ui->actionPrevImage, &QAction::triggered, images, &ImageList::prevImage);
|
connect(ui->actionPrevImage, &QAction::triggered, images, &ImageList::prevImage);
|
||||||
|
connect(ui->actionReset, &QAction::triggered, filters, &FilterList::reset);
|
||||||
connect(ui->actionPlay, &QAction::triggered, source, &Source::play);
|
connect(ui->actionPlay, &QAction::triggered, source, &Source::play);
|
||||||
connect(ui->actionTabImages, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabImages); });
|
connect(ui->actionTabImages, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabImages); });
|
||||||
connect(ui->actionTabFilters, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabFilters); });
|
connect(ui->actionTabFilters, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabFilters); });
|
||||||
|
@ -49,6 +55,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
showMaximized();
|
showMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::showEvent(QShowEvent *)
|
||||||
|
{
|
||||||
|
ui->viewer->showImage(images->getCurrent());
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
|
|
|
@ -36,6 +36,8 @@ class MainWindow : public QMainWindow
|
||||||
protected:
|
protected:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
void showEvent(QShowEvent *se);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newImage(Image *img);
|
void newImage(Image *img);
|
||||||
};
|
};
|
||||||
|
|
137
mainwindow.ui
137
mainwindow.ui
|
@ -29,27 +29,27 @@
|
||||||
<enum>QTabWidget::Triangular</enum>
|
<enum>QTabWidget::Triangular</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralWidget">
|
<widget class="QWidget" name="centralWidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitterV">
|
<widget class="QSplitter" name="splitterH">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="minimumSize">
|
||||||
<enum>Qt::Vertical</enum>
|
<size>
|
||||||
|
<width>320</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QSplitter" name="splitterH">
|
<property name="orientation">
|
||||||
<property name="sizePolicy">
|
<enum>Qt::Horizontal</enum>
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
</property>
|
||||||
<horstretch>0</horstretch>
|
<widget class="QSplitter" name="splitterV">
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="Viewer" name="viewer" native="true">
|
<widget class="Viewer" name="viewer" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -68,57 +68,43 @@
|
||||||
<enum>Qt::DefaultContextMenu</enum>
|
<enum>Qt::DefaultContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="Console" name="logConsole">
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>200</width>
|
<width>0</width>
|
||||||
<height>400</height>
|
<height>150</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="verticalScrollBarPolicy">
|
||||||
<size>
|
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||||
<width>16777215</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="tabShape">
|
<property name="undoRedoEnabled">
|
||||||
<enum>QTabWidget::Rounded</enum>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="lineWrapMode">
|
||||||
<number>0</number>
|
<enum>QPlainTextEdit::WidgetWidth</enum>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="centerOnScroll">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="TabImages" name="tabImages">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Images</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
<widget class="TabFilters" name="tabFilters">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Filters</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
<widget class="TabCamera" name="tabCamera">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Camera</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
<widget class="TabCalibration" name="tabCalibration">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Calibration</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="Console" name="logConsole">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
@ -127,22 +113,47 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>200</width>
|
||||||
<height>100</height>
|
<height>400</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="undoRedoEnabled">
|
<property name="maximumSize">
|
||||||
<bool>false</bool>
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="readOnly">
|
<property name="tabShape">
|
||||||
<bool>true</bool>
|
<enum>QTabWidget::Rounded</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="plainText">
|
<property name="currentIndex">
|
||||||
<string/>
|
<number>0</number>
|
||||||
</property>
|
|
||||||
<property name="centerOnScroll">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="TabImages" name="tabImages">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Images</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabFilters" name="tabFilters">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Filters</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabCamera" name="tabCamera">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Camera</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabCalibration" name="tabCalibration">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Calibration</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabRobot" name="tabRobot">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Robot</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -479,6 +490,12 @@
|
||||||
<header>tabcalibration.h</header>
|
<header>tabcalibration.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabRobot</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabrobot.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="images.qrc"/>
|
<include location="images.qrc"/>
|
||||||
|
|
35
painter.cpp
35
painter.cpp
|
@ -1,15 +1,38 @@
|
||||||
#include "painter.h"
|
#include "painter.h"
|
||||||
|
|
||||||
Painter::Painter(QPaintDevice *device, double r) :
|
|
||||||
QPainter(device),
|
|
||||||
ratio(r)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
void Painter::drawMarker(const QPoint ¢er, int r)
|
void Painter::drawMarker(const QPoint ¢er, int r)
|
||||||
{
|
{
|
||||||
|
QBrush br(Qt::NoBrush);
|
||||||
|
setBrush(br);
|
||||||
|
|
||||||
|
r /= getRatio();
|
||||||
|
|
||||||
drawEllipse(center, r, r);
|
drawEllipse(center, r, r);
|
||||||
drawLine(center + QPoint(+r, +r), center - QPoint(+r, +r));
|
drawLine(center + QPoint(+r, +r), center - QPoint(+r, +r));
|
||||||
drawLine(center + QPoint(+r, -r), center - QPoint(+r, -r));
|
drawLine(center + QPoint(+r, -r), center - QPoint(+r, -r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Painter::drawPad(const Pad &pad)
|
||||||
|
{
|
||||||
|
const Point2f *v = pad.getVertexes();
|
||||||
|
QPointF vq[4];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
vq[i] = toQt(v[i]);
|
||||||
|
|
||||||
|
drawPolygon(vq, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::setPen(const QPen &pen)
|
||||||
|
{
|
||||||
|
QPen p(pen);
|
||||||
|
|
||||||
|
p.setWidthF((double) p.widthF() / getRatio());
|
||||||
|
|
||||||
|
QPainter::setPen(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Painter::getRatio()
|
||||||
|
{
|
||||||
|
return (transform().m11() + transform().m22()) / 2;
|
||||||
|
}
|
||||||
|
|
13
painter.h
13
painter.h
|
@ -3,16 +3,23 @@
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "cast.h"
|
||||||
|
#include "pad.h"
|
||||||
|
|
||||||
class Painter : public QPainter
|
class Painter : public QPainter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Painter(QPaintDevice *device, double ratio = 1);
|
Painter(QPaintDevice *dev) :
|
||||||
|
QPainter(dev)
|
||||||
|
{ }
|
||||||
|
|
||||||
void drawMarker(const QPoint ¢er, int radius = 8);
|
void drawMarker(const QPoint ¢er, int radius = 8);
|
||||||
|
void drawPad(const Pad &pad);
|
||||||
|
|
||||||
protected:
|
/* Proxy to adjust width */
|
||||||
double ratio;
|
void setPen(const QPen &pen);
|
||||||
|
|
||||||
|
double getRatio();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAINTER_H
|
#endif // PAINTER_H
|
||||||
|
|
13
source.cpp
13
source.cpp
|
@ -71,16 +71,11 @@ void Source::play(bool run)
|
||||||
|
|
||||||
void Source::tick()
|
void Source::tick()
|
||||||
{
|
{
|
||||||
static bool running;
|
Mat m;
|
||||||
|
|
||||||
if (running)
|
if (read(m)) {
|
||||||
return;
|
last.setSourceMat(m);
|
||||||
|
|
||||||
running = true;
|
|
||||||
|
|
||||||
if (read(last.original))
|
|
||||||
emit newImage(&last);
|
emit newImage(&last);
|
||||||
|
}
|
||||||
running = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ void TabCalibration::doCalibration()
|
||||||
|
|
||||||
filters->add(pattern);
|
filters->add(pattern);
|
||||||
|
|
||||||
if (cam->calibrate(images->selectedImages().toStdList(), pattern))
|
if (cam->calibrate(images->getSelected(), pattern))
|
||||||
showResults();
|
showResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ TabFilters::TabFilters(QWidget *parent) :
|
||||||
ui->tblFilters->setModel(filters);
|
ui->tblFilters->setModel(filters);
|
||||||
ui->tblFilters->setSelectionModel(&filters->selection);
|
ui->tblFilters->setSelectionModel(&filters->selection);
|
||||||
|
|
||||||
connect(ui->tblFilters->verticalHeader(), &QHeaderView::sectionCountChanged, [&] () {
|
connect(ui->tblFilters->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
||||||
ui->tblFilters->resizeColumnsToContents();
|
ui->tblFilters->resizeColumnsToContents();
|
||||||
ui->tblFilters->resizeRowsToContents();
|
ui->tblFilters->resizeRowsToContents();
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,10 +13,12 @@ TabImages::TabImages(QWidget *parent) :
|
||||||
|
|
||||||
ui->tblImages->setModel(images);
|
ui->tblImages->setModel(images);
|
||||||
ui->tblImages->setSelectionModel(&images->selection);
|
ui->tblImages->setSelectionModel(&images->selection);
|
||||||
ui->tblImages->resizeColumnsToContents();
|
ui->tblImages->setColumnWidth(0, 200);
|
||||||
ui->tblImages->setColumnWidth(0, 400);
|
|
||||||
|
|
||||||
connect(ui->tblImages->verticalHeader(), SIGNAL(sectionCountChanged(int,int)), this, SLOT(resizeTable(int,int)));
|
connect(ui->tblImages->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
||||||
|
ui->tblImages->resizeColumnsToContents();
|
||||||
|
ui->tblImages->resizeRowsToContents();
|
||||||
|
});
|
||||||
connect(ui->btnClear, &QPushButton::clicked, images, &ImageList::clear);
|
connect(ui->btnClear, &QPushButton::clicked, images, &ImageList::clear);
|
||||||
connect(ui->btnLoad, &QPushButton::clicked, images, &ImageList::loadFilePicker);
|
connect(ui->btnLoad, &QPushButton::clicked, images, &ImageList::loadFilePicker);
|
||||||
connect(ui->btnSave, &QPushButton::clicked, images, &ImageList::saveFilePicker);
|
connect(ui->btnSave, &QPushButton::clicked, images, &ImageList::saveFilePicker);
|
||||||
|
@ -26,9 +28,3 @@ TabImages::~TabImages()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabImages::resizeTable(int, int)
|
|
||||||
{
|
|
||||||
ui->tblImages->resizeColumnsToContents();
|
|
||||||
ui->tblImages->resizeRowsToContents();
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,9 +17,6 @@ class TabImages : public QWidget
|
||||||
explicit TabImages(QWidget *parent = 0);
|
explicit TabImages(QWidget *parent = 0);
|
||||||
~TabImages();
|
~TabImages();
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void resizeTable(int, int);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::TabImages *ui;
|
Ui::TabImages *ui;
|
||||||
};
|
};
|
||||||
|
|
245
viewer.cpp
245
viewer.cpp
|
@ -20,109 +20,204 @@ Viewer::Viewer(QWidget *parent) :
|
||||||
img(NULL)
|
img(NULL)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void Viewer::reset()
|
||||||
|
{
|
||||||
|
Mat &m = img->getMat();
|
||||||
|
updateWindow(QRect(0, 0, m.cols, m.rows));
|
||||||
|
}
|
||||||
|
|
||||||
void Viewer::resizeEvent(QResizeEvent *)
|
void Viewer::resizeEvent(QResizeEvent *)
|
||||||
{
|
{
|
||||||
updateViewport();
|
updateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::paintEvent(QPaintEvent *)
|
void Viewer::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
Painter p(this, 1 / ratio);
|
Painter p(this);
|
||||||
|
QPen pe;
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
p.fillRect(rect(), Qt::black);
|
p.fillRect(rect(), Qt::black);
|
||||||
|
p.setClipRect(viewport);
|
||||||
|
p.setTransform(transform);
|
||||||
|
|
||||||
if (!img)
|
pe.setStyle(Qt::SolidLine);
|
||||||
return;
|
pe.setWidth(2);
|
||||||
|
p.setPen(pe);
|
||||||
|
|
||||||
p.setViewport(viewport);
|
if (img) {
|
||||||
p.setWindow(qimg.rect());
|
p.drawImage(window, qimg, window);
|
||||||
|
|
||||||
p.drawImage(p.window(), qimg);
|
for (auto it = filters->begin(); it != filters->end(); it++) {
|
||||||
|
Result *result = img->getResult(*it);
|
||||||
|
if (result && (*it)->isShown()) {
|
||||||
|
p.save();
|
||||||
|
|
||||||
QPen pen = p.pen();
|
/*QTransform t;
|
||||||
pen.setColor(Qt::green);
|
for (auto it2 = it+1; it2 != filters->end(); it2++) {
|
||||||
pen.setWidth(2 / ratio);
|
Result *result2 = img->getResult(*it2);
|
||||||
p.setPen(pen);
|
if (result2 && (*it2)->isShown())
|
||||||
|
t *= result2->getTransform();
|
||||||
|
}
|
||||||
|
p.setWorldTransform(t * transform);*/
|
||||||
|
|
||||||
for (auto filter : *filters) {
|
result->drawResult(&p);
|
||||||
Result *result = img->getResult(filter);
|
p.restore();
|
||||||
|
}
|
||||||
if (filter->isShown() && result)
|
}
|
||||||
result->draw(&p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!first.isNull() && !last.isNull()) {
|
||||||
|
QRect sel(unmap(first), unmap(last));
|
||||||
|
|
||||||
|
pe.setWidth(2);
|
||||||
|
pe.setStyle(Qt::SolidLine);
|
||||||
|
pe.setColor(Qt::black);
|
||||||
|
p.setPen(pe);
|
||||||
|
p.drawRect(sel.normalized());
|
||||||
|
|
||||||
|
pe.setStyle(Qt::DotLine);
|
||||||
|
pe.setBrush(Qt::white);
|
||||||
|
p.setPen(pe);
|
||||||
|
p.drawRect(sel.normalized());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::wheelEvent(QWheelEvent * we)
|
||||||
|
{
|
||||||
|
QPoint numPixels = we->pixelDelta();
|
||||||
|
QPoint numDegrees = we->angleDelta() / 8;
|
||||||
|
|
||||||
|
int d = 0;
|
||||||
|
|
||||||
|
if (!numPixels.isNull())
|
||||||
|
d = numPixels.y();
|
||||||
|
else if (!numDegrees.isNull())
|
||||||
|
d = numDegrees.y();
|
||||||
|
|
||||||
|
double ratio = (double) window.width() / window.height();
|
||||||
|
|
||||||
|
if (d > 0 || (d < 0 && window.height() + 2*d > 32)) {
|
||||||
|
updateWindow(window.adjusted(
|
||||||
|
-d * ratio, -d,
|
||||||
|
d * ratio, d
|
||||||
|
));
|
||||||
|
|
||||||
|
update();
|
||||||
|
we->accept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
we->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::mousePressEvent(QMouseEvent *me)
|
||||||
|
{
|
||||||
|
if (viewport.contains(me->pos())) {
|
||||||
|
if (me->modifiers() & Qt::AltModifier)
|
||||||
|
first = me->pos();
|
||||||
|
else
|
||||||
|
last = me->pos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::mouseMoveEvent(QMouseEvent *me)
|
||||||
|
{
|
||||||
|
if (viewport.contains(me->pos())) {
|
||||||
|
if (me->modifiers() & Qt::AltModifier) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QPoint delta = (me->pos() - last) / transform.m11();
|
||||||
|
window.moveCenter(window.center() - delta);
|
||||||
|
|
||||||
|
updateWindow(window);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last = me->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::mouseReleaseEvent(QMouseEvent *me)
|
void Viewer::mouseReleaseEvent(QMouseEvent *me)
|
||||||
{
|
{
|
||||||
if (viewport.contains(me->pos())) {
|
if (viewport.contains(me->pos())) {
|
||||||
QPoint pos = transformInv(me->pos());
|
if (me->modifiers() & Qt::AltModifier) {
|
||||||
|
if (!first.isNull() && !last.isNull())
|
||||||
|
updateWindow(QRect(unmap(first), unmap(last)).normalized());
|
||||||
|
}
|
||||||
|
else if (last.isNull()) {
|
||||||
|
QPoint pos = unmap(me->pos());
|
||||||
|
Filter *f = filters->getCurrent();
|
||||||
|
|
||||||
qDebug() << "Clicked at: " << pos.x() << "," << pos.y();
|
qDebug() << "Clicked at: " << pos << "(" << me->pos() << ")";
|
||||||
|
|
||||||
clicks.push_back(Point(pos.x(), pos.y()));
|
if (f) {
|
||||||
emit clicked(pos);
|
if (f->clicked(toCv(pos), me))
|
||||||
|
updateImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
QPoint Viewer::transform(QPoint pos)
|
first = last = QPoint();
|
||||||
{
|
|
||||||
return pos * ratio + viewport.topLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint Viewer::transformInv(QPoint pos)
|
|
||||||
{
|
|
||||||
return (pos - viewport.topLeft()) / ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::showImage(Image *next)
|
|
||||||
{
|
|
||||||
if (!next)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (next != img)
|
|
||||||
filters->reset();
|
|
||||||
|
|
||||||
img = next;
|
|
||||||
updateImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::updateImage()
|
|
||||||
{
|
|
||||||
if (!img)
|
|
||||||
return;
|
|
||||||
|
|
||||||
filters->execute(img);
|
|
||||||
|
|
||||||
qimg = toQImage(img->filtered);
|
|
||||||
|
|
||||||
if (size != img->filtered.size()) {
|
|
||||||
size = img->filtered.size();
|
|
||||||
updateViewport();
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::updateViewport()
|
void Viewer::showImage(Image *next)
|
||||||
{
|
{
|
||||||
double viewRatio = (double) size.width / size.height;
|
if (next) {
|
||||||
|
if (next != img)
|
||||||
|
filters->reset();
|
||||||
|
|
||||||
int viewHeight = width() / viewRatio;
|
img = next;
|
||||||
int viewWidth = width();
|
updateImage();
|
||||||
|
|
||||||
if (viewHeight > height()) {
|
|
||||||
viewWidth = height() * viewRatio;
|
|
||||||
viewHeight = height();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
viewport = QRect(
|
|
||||||
(width() - viewWidth) / 2,
|
void Viewer::updateImage()
|
||||||
(height() - viewHeight) / 2,
|
{
|
||||||
viewWidth,
|
if (img) {
|
||||||
viewHeight
|
filters->execute(img);
|
||||||
);
|
|
||||||
|
Mat &m = img->getMat();
|
||||||
qDebug() << "New viewport" << viewport << " in widget " << rect() << " for frame " << toQt(size);
|
qimg = toQImage(m);
|
||||||
|
|
||||||
ratio = (double) viewport.width() / size.width;
|
if (window.size() != toQt(m.size()))
|
||||||
|
updateWindow(QRect(0, 0, m.cols, m.rows));
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::updateWindow(const QRect &win)
|
||||||
|
{
|
||||||
|
window = win;
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewer::updateTransform()
|
||||||
|
{
|
||||||
|
QSizeF s = window.size();
|
||||||
|
s.scale(size(), Qt::KeepAspectRatio);
|
||||||
|
|
||||||
|
viewport.setRect((double) (width() - s.width()) / 2,
|
||||||
|
(double) (height() - s.height()) / 2,
|
||||||
|
s.width(), s.height() );
|
||||||
|
|
||||||
|
double sc = (double) viewport.width() / window.width();
|
||||||
|
|
||||||
|
transform.reset();
|
||||||
|
transform.translate(viewport.x(), viewport.y());
|
||||||
|
transform.scale(sc, sc);
|
||||||
|
transform.translate( -window.x(), -window.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Viewer::map(const QPoint &p) const
|
||||||
|
{
|
||||||
|
return transform.map(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Viewer::unmap(const QPoint &p) const
|
||||||
|
{
|
||||||
|
return transform.inverted().map(p);
|
||||||
}
|
}
|
||||||
|
|
30
viewer.h
30
viewer.h
|
@ -17,31 +17,33 @@ class Viewer : public QGLWidget
|
||||||
public:
|
public:
|
||||||
explicit Viewer(QWidget *parent = 0);
|
explicit Viewer(QWidget *parent = 0);
|
||||||
|
|
||||||
Image *img;
|
|
||||||
|
|
||||||
QVector<Point> clicks;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPoint transform(QPoint pos);
|
|
||||||
QPoint transformInv(QPoint pos);
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *pe);
|
void paintEvent(QPaintEvent *pe);
|
||||||
void resizeEvent(QResizeEvent *re);
|
void resizeEvent(QResizeEvent *re);
|
||||||
|
|
||||||
|
void wheelEvent(QWheelEvent *we);
|
||||||
|
void mousePressEvent(QMouseEvent *me);
|
||||||
|
void mouseMoveEvent(QMouseEvent *me);
|
||||||
void mouseReleaseEvent(QMouseEvent *me);
|
void mouseReleaseEvent(QMouseEvent *me);
|
||||||
|
|
||||||
|
QPoint map(const QPoint &p) const;
|
||||||
|
QPoint unmap(const QPoint &p) const;
|
||||||
|
|
||||||
|
void updateTransform();
|
||||||
|
void updateWindow(const QRect &r);
|
||||||
|
|
||||||
|
Image *img;
|
||||||
QImage qimg;
|
QImage qimg;
|
||||||
QRect viewport;
|
QRect viewport;
|
||||||
|
QRect window;
|
||||||
Size size;
|
QPoint first, last;
|
||||||
double ratio;
|
QTransform transform;
|
||||||
|
|
||||||
signals:
|
|
||||||
void clicked(QPoint pos);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showImage(Image *img);
|
void showImage(Image *img);
|
||||||
void updateImage();
|
void updateImage();
|
||||||
void updateViewport();
|
|
||||||
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIEWER_H
|
#endif // VIEWER_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue