huge commit of refactoring work
This commit is contained in:
parent
20891805e0
commit
de953d0a6d
33 changed files with 321 additions and 209 deletions
|
@ -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, 2015-01-15T11:48:54. -->
|
<!-- Written by QtCreator 3.3.0, 2015-01-28T16:52:04. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|
|
@ -32,9 +32,10 @@ bool Camera::calibrate(QList<Image *> imgs, Pattern *pattern)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto img : imgs) {
|
for (Image *img : imgs) {
|
||||||
img->applyFilter(pattern);
|
PatternResult *result = (PatternResult*) pattern->apply(img);
|
||||||
PatternResult *result = (PatternResult *) img->getResult(pattern);
|
|
||||||
|
img->results[pattern] = result;
|
||||||
|
|
||||||
if (result->isFound())
|
if (result->isFound())
|
||||||
imagePoints.push_back(result->getPoints());
|
imagePoints.push_back(result->getPoints());
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool FilterList::setData(const QModelIndex &index, const QVariant &value, int ro
|
||||||
case 1: filter->setShow(value == Qt::Checked); break;
|
case 1: filter->setShow(value == Qt::Checked); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit filtersChanged();
|
emit filterChanged(filter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,36 +101,27 @@ void FilterList::add(Filter *filter)
|
||||||
push_back(filter);
|
push_back(filter);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
|
||||||
connect(filter, SIGNAL(filterChanged()), this, SIGNAL(filtersChanged()));
|
connect(filter, SIGNAL(filterChanged(Filter *)), this, SIGNAL(filterChanged(Filter *)));
|
||||||
|
connect(filter, SIGNAL(filterApplied(Filter*)), this, SLOT(update(Filter *)));
|
||||||
|
|
||||||
emit filterAdded(filter);
|
emit filterAdded(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterList::execute(Image *img)
|
|
||||||
{
|
|
||||||
img->getMat().release();
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (auto filter : *this)
|
|
||||||
img->applyFilter(filter);
|
|
||||||
} catch (Exception e) {
|
|
||||||
qCritical("%s", e.msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update times and results */
|
|
||||||
emit dataChanged(
|
|
||||||
createIndex(0, 4),
|
|
||||||
createIndex(size(), 4)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilterList::reset()
|
void FilterList::reset()
|
||||||
{
|
{
|
||||||
qDebug() << "Reset filters";
|
qDebug() << "Reset filters";
|
||||||
for (Filter *filter : *this)
|
for (Filter *filter : *this)
|
||||||
filter->reset();
|
filter->reset();
|
||||||
|
|
||||||
emit filtersChanged();
|
emit filterChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterList::update(Filter *f)
|
||||||
|
{
|
||||||
|
emit dataChanged(
|
||||||
|
createIndex(indexOf(f), 0),
|
||||||
|
createIndex(indexOf(f)+1, 5)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter * FilterList::getCurrent()
|
Filter * FilterList::getCurrent()
|
||||||
|
|
|
@ -23,8 +23,7 @@ class FilterList :
|
||||||
Qt::ItemFlags flags(const QModelIndex & index) const;
|
Qt::ItemFlags flags(const QModelIndex & index) const;
|
||||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
|
|
||||||
void add(Filter *filt);
|
void add(Filter *filter);
|
||||||
void execute(Image *img);
|
|
||||||
|
|
||||||
Filter * getCurrent();
|
Filter * getCurrent();
|
||||||
|
|
||||||
|
@ -32,9 +31,10 @@ class FilterList :
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reset();
|
void reset();
|
||||||
|
void update(Filter *);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filtersChanged();
|
void filterChanged(Filter *filter = NULL);
|
||||||
void filterSelected(Filter *filter);
|
void filterSelected(Filter *filter);
|
||||||
void filterAdded(Filter *filter);
|
void filterAdded(Filter *filter);
|
||||||
void filterRemoved(Filter *filter);
|
void filterRemoved(Filter *filter);
|
||||||
|
|
|
@ -36,5 +36,14 @@ Result * Filter::apply(Image *img)
|
||||||
time = timer.nsecsElapsed();
|
time = timer.nsecsElapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img->results[this] = result;
|
||||||
|
|
||||||
|
emit filterApplied(this);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::settingChanged(Setting *)
|
||||||
|
{
|
||||||
|
emit filterChanged(this);
|
||||||
|
}
|
||||||
|
|
|
@ -41,10 +41,12 @@ class Filter : public QObject
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void reset() { }
|
virtual void reset() { }
|
||||||
virtual bool clicked(Point, QMouseEvent * = 0) { return false; }
|
virtual void clicked(Point, QMouseEvent *) { }
|
||||||
|
virtual void settingChanged(Setting *);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filterChanged();
|
void filterChanged(Filter *);
|
||||||
|
void filterApplied(Filter *);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
|
|
@ -94,8 +94,9 @@ Result * KMeans::applyInternal(Image *img)
|
||||||
return new Result;
|
return new Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KMeans::clicked(Point p, QMouseEvent *)
|
void KMeans::clicked(Point p, QMouseEvent *)
|
||||||
{
|
{
|
||||||
colorFilterPoints.append(p);
|
colorFilterPoints.append(p);
|
||||||
return true;
|
|
||||||
|
emit filterChanged(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class KMeans : public Filter
|
||||||
QString getName() const { return "KMeans"; }
|
QString getName() const { return "KMeans"; }
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
bool clicked(Point, QMouseEvent *);
|
void clicked(Point, QMouseEvent *);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -103,13 +103,18 @@ QString PadResult::getResult() const
|
||||||
return QString("count = %1").arg(size());
|
return QString("count = %1").arg(size());
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Pad>::iterator PadResult::getNearest(const Point &p)
|
PadResult::iterator PadResult::getNearest(const Pad &p)
|
||||||
{
|
{
|
||||||
float minDist = FLT_MAX;
|
return getNearest(p.center);
|
||||||
QList<Pad>::iterator nearest = end();
|
}
|
||||||
|
|
||||||
for (auto it = begin(); it != end(); it++) {
|
PadResult::iterator PadResult::getNearest(const Point2f &p)
|
||||||
float dist = norm(it->center - Point2f(p));
|
{
|
||||||
|
double minDist = FLT_MAX;
|
||||||
|
iterator nearest = end();
|
||||||
|
|
||||||
|
for (iterator it = begin(); it != end(); it++) {
|
||||||
|
double dist = it->getDistance(p);
|
||||||
if (dist < minDist) {
|
if (dist < minDist) {
|
||||||
nearest = it;
|
nearest = it;
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef PADDETECT_H
|
#ifndef PADDETECT_H
|
||||||
#define PADDETECT_H
|
#define PADDETECT_H
|
||||||
|
|
||||||
#include <vector>
|
#include <QLinkedList>
|
||||||
|
|
||||||
#include "pad.h"
|
#include "pad.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
@ -28,14 +28,16 @@ class PadDetect : public Filter
|
||||||
enum Mode mode;
|
enum Mode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PadResult : public Result, public QList<Pad>
|
class PadResult : public Result, public QLinkedList<Pad>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void drawResult(Painter *p) const;
|
void drawResult(Painter *p) const;
|
||||||
|
|
||||||
QString getResult() const;
|
QString getResult() const;
|
||||||
|
|
||||||
QList<Pad>::iterator getNearest(const Point &p);
|
iterator getNearest(const Point2f &p);
|
||||||
|
iterator getNearest(const Pad &p);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PADDETECT_H
|
#endif // PADDETECT_H
|
||||||
|
|
|
@ -24,10 +24,10 @@ Result * PadFilter::applyInternal(Image *img)
|
||||||
result->push_back(pad);
|
result->push_back(pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Point p : addPoints)
|
for (Point2f p : addPoints)
|
||||||
result->append(Pad(p));
|
result->append(Pad(p));
|
||||||
|
|
||||||
for (Point p : delPoints)
|
for (Point2f p : delPoints)
|
||||||
result->erase(result->getNearest(p));
|
result->erase(result->getNearest(p));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -44,12 +44,12 @@ void PadFilter::reset()
|
||||||
delPoints.clear();
|
delPoints.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PadFilter::clicked(Point p, QMouseEvent *me)
|
void PadFilter::clicked(Point p, QMouseEvent *me)
|
||||||
{
|
{
|
||||||
if (me->modifiers() & Qt::AltModifier)
|
if (me->modifiers() & Qt::AltModifier)
|
||||||
delPoints.append(p);
|
delPoints.append(Point2f(p));
|
||||||
else
|
else
|
||||||
addPoints.append(p);
|
addPoints.append(Point2f(p));
|
||||||
|
|
||||||
return true;
|
emit filterChanged(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ class PadFilter : public Filter
|
||||||
|
|
||||||
QString getName() const { return "PadFilter"; }
|
QString getName() const { return "PadFilter"; }
|
||||||
|
|
||||||
bool clicked(Point p, QMouseEvent *me);
|
void clicked(Point p, QMouseEvent *me);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -20,7 +20,7 @@ class PadFilter : public Filter
|
||||||
|
|
||||||
Range<double> areaRange, ratioRange;
|
Range<double> areaRange, ratioRange;
|
||||||
|
|
||||||
QList<Point> addPoints, delPoints;
|
QList<Point2f> addPoints, delPoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PADFILTER_H
|
#endif // PADFILTER_H
|
||||||
|
|
|
@ -9,35 +9,78 @@ PathPlanner::PathPlanner(Filter *s, enum Algorithm a) :
|
||||||
algoMap[NEAREST_NEIGHBOUR] = "Nearest Neighbour";
|
algoMap[NEAREST_NEIGHBOUR] = "Nearest Neighbour";
|
||||||
algoMap[REPETETIVE_NEAREST_NEIGHBOUR] = "Repetitive Nearest Neighbour";
|
algoMap[REPETETIVE_NEAREST_NEIGHBOUR] = "Repetitive Nearest Neighbour";
|
||||||
|
|
||||||
//settings["Algorithm"] = new EnumSetting(this, (int &) algo, algoMap);
|
settings["Algorithm"] = new EnumSetting(this, (int &) algo, algoMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result * PathPlanner::applyInternal(Image *img)
|
Result * PathPlanner::applyInternal(Image *img)
|
||||||
{
|
{
|
||||||
PadResult *list = dynamic_cast<PadResult*>(img->getResult(source));
|
PathResult *path = NULL;
|
||||||
if (list) {
|
PadResult *padResult = dynamic_cast<PadResult*>(img->getResult(source));
|
||||||
PathResult *path = new PathResult;
|
|
||||||
PadResult vertices = *list; /* create a copy */
|
|
||||||
|
|
||||||
if (vertices.size() < 1 || vertices.size() > 1000) {
|
if (padResult) {
|
||||||
qWarning() << "Found too much/less pads (" << vertices.size() << ")! Skipping PathPlanner";
|
if (padResult->size() < 1 || padResult->size() > 1000) {
|
||||||
|
qWarning() << "Found too much/less pads (" << padResult->size() << ")! Skipping PathPlanner";
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case NEAREST_NEIGHBOUR:
|
case NEAREST_NEIGHBOUR: {
|
||||||
path->append(vertices.takeFirst());
|
path = new PathResult;
|
||||||
|
PadResult pads = *padResult; /* create a copy */
|
||||||
|
PadResult::iterator start = pads.begin(); /* fixed */
|
||||||
|
Pad last = *start;
|
||||||
|
|
||||||
while (!vertices.isEmpty()) {
|
path->append(*start);
|
||||||
auto nearest = vertices.getNearest(path->last().center);
|
pads.erase(start);
|
||||||
|
|
||||||
|
while (!pads.isEmpty()) {
|
||||||
|
PadResult::iterator nearest = pads.getNearest(last);
|
||||||
path->append(*nearest);
|
path->append(*nearest);
|
||||||
vertices.erase(nearest);
|
pads.erase(nearest);
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REPETETIVE_NEAREST_NEIGHBOUR:
|
last = *nearest;
|
||||||
// FIXME: implement
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
|
case REPETETIVE_NEAREST_NEIGHBOUR: {
|
||||||
|
double minLength = FLT_MAX;
|
||||||
|
|
||||||
|
for (int i = 0; i < padResult->size(); i++) {
|
||||||
|
double currentLength = 0;
|
||||||
|
PathResult *currentPath = new PathResult;
|
||||||
|
PadResult pads = *padResult;
|
||||||
|
PadResult::iterator start = pads.begin() + i;
|
||||||
|
Pad last = *start;
|
||||||
|
|
||||||
|
currentPath->append(*start);
|
||||||
|
pads.erase(start);
|
||||||
|
|
||||||
|
while (!pads.isEmpty()) {
|
||||||
|
PadResult::iterator nearest = pads.getNearest(last);
|
||||||
|
|
||||||
|
CV_Assert(nearest != pads.end());
|
||||||
|
|
||||||
|
currentLength += last.getDistance(*nearest);
|
||||||
|
if (currentLength > minLength)
|
||||||
|
break;
|
||||||
|
|
||||||
|
currentPath->append(*nearest);
|
||||||
|
pads.erase(nearest);
|
||||||
|
|
||||||
|
last = *nearest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLength > minLength)
|
||||||
|
delete currentPath;
|
||||||
|
else {
|
||||||
|
if (path)
|
||||||
|
delete path;
|
||||||
|
|
||||||
|
minLength = currentLength;
|
||||||
|
path = currentPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
@ -48,39 +91,25 @@ Result * PathPlanner::applyInternal(Image *img)
|
||||||
return new Result;
|
return new Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
Mat PathPlanner::calcDistanceMat(QList<Point2f> vertices)
|
|
||||||
{
|
|
||||||
int size = vertices.size();
|
|
||||||
Mat distance = Mat::zeros(size, size, CV_32F);
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
for (int j = i+1; j < size; j++) {
|
|
||||||
distance.at<float>(i, j) = Pad::distance(pads[i], pads[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PathResult::drawResult(Painter *p) const
|
void PathResult::drawResult(Painter *p) const
|
||||||
{
|
{
|
||||||
if (size()) {
|
if (size() >= 2) {
|
||||||
QPen pe = p->pen();
|
QPen pe = p->pen();
|
||||||
QBrush br(Qt::SolidPattern);
|
QBrush br(Qt::SolidPattern);
|
||||||
|
|
||||||
pe.setWidth(2);
|
pe.setWidth(2);
|
||||||
|
|
||||||
for (int i = 1; i < size(); i++) {
|
const_iterator prev = begin();
|
||||||
|
const_iterator curr = begin() + 1;
|
||||||
|
for (int i = 0; curr != end(); i++, curr++, prev++) {
|
||||||
QColor c = QColor::fromHsl(360.0 / size() * i, 255, 128);
|
QColor c = QColor::fromHsl(360.0 / size() * i, 255, 128);
|
||||||
|
|
||||||
pe.setColor(c);
|
pe.setColor(c);
|
||||||
br.setColor(c);
|
br.setColor(c);
|
||||||
p->setPen(pe);
|
p->setPen(pe);
|
||||||
p->setBrush(br);
|
p->setBrush(br);
|
||||||
p->drawLine(toQt(at(i-1)), toQt(at(i)));
|
p->drawLine(toQt(*prev), toQt(*curr));
|
||||||
p->drawEllipse(toQt(at(i)), 1, 1);
|
p->drawEllipse(toQt(*curr), 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->drawMarker(toQt((Point2i) (Point2f) first()));
|
p->drawMarker(toQt((Point2i) (Point2f) first()));
|
||||||
|
@ -88,11 +117,17 @@ void PathResult::drawResult(Painter *p) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float PathResult::getLength() const
|
double PathResult::getLength() const
|
||||||
{
|
{
|
||||||
float length = 0;
|
double length = 0;
|
||||||
for (int i = 1; i < size(); i++)
|
|
||||||
length += norm(at(i-1).center - at(i).center);
|
if (size() >= 2) {
|
||||||
|
const_iterator curr = begin() + 1;
|
||||||
|
const_iterator prev = begin();
|
||||||
|
|
||||||
|
for (; curr != end(); prev++, curr++)
|
||||||
|
length += prev->getDistance(*curr);
|
||||||
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ class PathResult : public PadResult
|
||||||
public:
|
public:
|
||||||
void drawResult(Painter *p) const;
|
void drawResult(Painter *p) const;
|
||||||
|
|
||||||
float getLength() const;
|
double getLength() const;
|
||||||
QString getResult() const;
|
QString getResult() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
#include "viewer.h"
|
#include "viewer.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
|
||||||
Setting::Setting(Filter *f, QString tip)
|
Setting::Setting(Filter *f, QString tip) :
|
||||||
: toolTip(tip)
|
filter(f),
|
||||||
|
toolTip(tip)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(valueChanged()), f, SIGNAL(filterChanged()));
|
connect(this, &Setting::valueChanged, [&]() {
|
||||||
connect(this, SIGNAL(valueChanged()), f, SLOT(reset()));
|
filter->settingChanged(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget * Setting::getWidget(QWidget *parent)
|
QWidget * Setting::getWidget(QWidget *parent)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "watershed.h"
|
#include "watershed.h"
|
||||||
|
|
||||||
bool Watershed::clicked(Point pos, QMouseEvent *me)
|
void Watershed::clicked(Point pos, QMouseEvent *me)
|
||||||
{
|
{
|
||||||
qDebug() << getName() << ": Marker " << ((me->modifiers() & Qt::AltModifier) ? "deleted" : "added") << " at:" << toQt(pos);
|
qDebug() << getName() << ": Marker " << ((me->modifiers() & Qt::AltModifier) ? "deleted" : "added") << " at:" << toQt(pos);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ bool Watershed::clicked(Point pos, QMouseEvent *me)
|
||||||
else
|
else
|
||||||
addMarkers.push_back(pos);
|
addMarkers.push_back(pos);
|
||||||
|
|
||||||
return true;
|
emit filterChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Watershed::reset()
|
void Watershed::reset()
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Watershed : public Filter
|
||||||
public:
|
public:
|
||||||
QString getName() const { return "Watershed"; }
|
QString getName() const { return "Watershed"; }
|
||||||
|
|
||||||
bool clicked(Point pos, QMouseEvent *me = 0);
|
void clicked(Point pos, QMouseEvent *me = 0);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reset();
|
void reset();
|
||||||
|
|
17
image.cpp
17
image.cpp
|
@ -26,7 +26,7 @@ Image::~Image()
|
||||||
|
|
||||||
void Image::load(QString p)
|
void Image::load(QString p)
|
||||||
{
|
{
|
||||||
if (p != "")
|
if (!p.isNull())
|
||||||
path = p;
|
path = p;
|
||||||
|
|
||||||
source = cv::imread(path.toStdString());
|
source = cv::imread(path.toStdString());
|
||||||
|
@ -35,19 +35,12 @@ void Image::load(QString p)
|
||||||
|
|
||||||
void Image::save(QString p)
|
void Image::save(QString p)
|
||||||
{
|
{
|
||||||
if (p != "")
|
if (!p.isNull())
|
||||||
path = p;
|
path = p;
|
||||||
|
|
||||||
saved = imwrite(path.toStdString(), getMat());
|
saved = imwrite(path.toStdString(), getMat());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::applyFilter(Filter *filter)
|
|
||||||
{
|
|
||||||
Result *result = filter->apply(this);
|
|
||||||
if (result)
|
|
||||||
results[filter] = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mat & Image::getMat()
|
Mat & Image::getMat()
|
||||||
{
|
{
|
||||||
if (!filtered.data)
|
if (!filtered.data)
|
||||||
|
@ -56,6 +49,12 @@ Mat & Image::getMat()
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage Image::getQImage()
|
||||||
|
{
|
||||||
|
return toQImage(getMat());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const Mat & Image::getSourceMat()
|
const Mat & Image::getSourceMat()
|
||||||
{
|
{
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
|
|
6
image.h
6
image.h
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
#include <opencv2/core.hpp>
|
#include <opencv2/core.hpp>
|
||||||
#include <opencv2/imgproc.hpp>
|
#include <opencv2/imgproc.hpp>
|
||||||
|
@ -23,8 +24,6 @@ class Image
|
||||||
void save(QString path = QString());
|
void save(QString path = QString());
|
||||||
void load(QString path = QString());
|
void load(QString path = QString());
|
||||||
|
|
||||||
void applyFilter(Filter *filter);
|
|
||||||
|
|
||||||
/* Getter */
|
/* Getter */
|
||||||
bool isLoaded() const { return loaded; }
|
bool isLoaded() const { return loaded; }
|
||||||
bool isSaved() const { return saved; }
|
bool isSaved() const { return saved; }
|
||||||
|
@ -32,13 +31,14 @@ class Image
|
||||||
Result * getResult(Filter *f) { return results[f]; }
|
Result * getResult(Filter *f) { return results[f]; }
|
||||||
QString getPath() { return path; }
|
QString getPath() { return path; }
|
||||||
Mat & getMat();
|
Mat & getMat();
|
||||||
|
QImage getQImage();
|
||||||
|
|
||||||
const Mat & getSourceMat();
|
const Mat & getSourceMat();
|
||||||
void setSourceMat(const Mat &m);
|
void setSourceMat(const Mat &m);
|
||||||
|
|
||||||
protected:
|
|
||||||
QMap<Filter*, Result*> results;
|
QMap<Filter*, Result*> results;
|
||||||
|
|
||||||
|
protected:
|
||||||
QString path;
|
QString path;
|
||||||
Mat source;
|
Mat source;
|
||||||
Mat filtered;
|
Mat filtered;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "painter.h"
|
||||||
#include "imagelist.h"
|
#include "imagelist.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
@ -132,7 +133,14 @@ void ImageList::load(QStringList files)
|
||||||
|
|
||||||
void ImageList::save(QString path)
|
void ImageList::save(QString path)
|
||||||
{
|
{
|
||||||
getCurrent()->save(path);
|
Image *img = getCurrent();
|
||||||
|
QImage qimg = img->getQImage();
|
||||||
|
Painter p(&qimg);
|
||||||
|
|
||||||
|
p.setRatio(1e-3 * qimg.width());
|
||||||
|
p.drawOverlay(img);
|
||||||
|
|
||||||
|
qimg.save(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageList::loadFilePicker()
|
void ImageList::loadFilePicker()
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
<file>resources/go-top.png</file>
|
<file>resources/go-top.png</file>
|
||||||
<file>resources/process-stop.png</file>
|
<file>resources/process-stop.png</file>
|
||||||
<file>resources/start-here.png</file>
|
<file>resources/start-here.png</file>
|
||||||
|
<file>resources/bed_circ.png</file>
|
||||||
|
<file>resources/bed_rect.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/math">
|
<qresource prefix="/math">
|
||||||
<file>resources/matbr_left.png</file>
|
<file>resources/matbr_left.png</file>
|
||||||
|
|
25
main.cpp
25
main.cpp
|
@ -2,15 +2,16 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCameraInfo>
|
#include <QCameraInfo>
|
||||||
|
|
||||||
/* Filters */
|
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "imagelist.h"
|
#include "imagelist.h"
|
||||||
#include "filterlist.h"
|
#include "filterlist.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "robot.h"
|
||||||
|
|
||||||
Source *source;
|
Source *source;
|
||||||
Camera *cam;
|
Camera *cam;
|
||||||
|
Robot *robot;
|
||||||
FilterList *filters;
|
FilterList *filters;
|
||||||
ImageList *images;
|
ImageList *images;
|
||||||
MainWindow *mwindow;
|
MainWindow *mwindow;
|
||||||
|
@ -27,7 +28,6 @@ int main(int argc, char *argv[])
|
||||||
cam = new Camera(source);
|
cam = new Camera(source);
|
||||||
filters = new FilterList;
|
filters = new FilterList;
|
||||||
images = new ImageList;
|
images = new ImageList;
|
||||||
mwindow = new MainWindow;
|
|
||||||
|
|
||||||
QStringList imgs = QCoreApplication::arguments();
|
QStringList imgs = QCoreApplication::arguments();
|
||||||
imgs.removeFirst();
|
imgs.removeFirst();
|
||||||
|
@ -35,22 +35,25 @@ int main(int argc, char *argv[])
|
||||||
images->load(imgs);
|
images->load(imgs);
|
||||||
|
|
||||||
/* Setup pipeline */
|
/* Setup pipeline */
|
||||||
Pattern *pat = new Pattern(Size(2, 2), Size(60, 60), Pattern::QUADRILINEAR_MARKERS);
|
Pattern *pattern = new Pattern(Size(2, 2), Size(60, 60), Pattern::QUADRILINEAR_MARKERS);
|
||||||
filters->add(pat);
|
PadDetect *pads = new PadDetect();
|
||||||
filters->add(new Perspective(cam, pat));
|
PadFilter *filter = new PadFilter(pads);
|
||||||
filters->add(new Resize(Range<int>(400, 1000)));
|
PathPlanner *planner = new PathPlanner(filter, PathPlanner::REPETETIVE_NEAREST_NEIGHBOUR);
|
||||||
|
|
||||||
|
filters->add(pattern);
|
||||||
|
filters->add(new Perspective(cam, pattern));
|
||||||
|
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_BGR2GRAY));
|
filters->add(new Convert(COLOR_BGR2GRAY));
|
||||||
filters->add(new Threshold(Threshold::OTSU));
|
filters->add(new Threshold(Threshold::OTSU));
|
||||||
|
filters->add(new Morph(MORPH_CLOSE, MORPH_RECT));
|
||||||
PadDetect *pads = new PadDetect();
|
|
||||||
PadFilter *filter = new PadFilter(pads);
|
|
||||||
|
|
||||||
filters->add(pads);
|
filters->add(pads);
|
||||||
filters->add(filter);
|
filters->add(filter);
|
||||||
filters->add(new PathPlanner(filter, PathPlanner::NEAREST_NEIGHBOUR));
|
filters->add(planner);
|
||||||
|
|
||||||
|
robot = new Robot(pattern, planner);
|
||||||
|
mwindow = new MainWindow;
|
||||||
|
|
||||||
mwindow->show();
|
mwindow->show();
|
||||||
|
|
||||||
|
|
|
@ -30,15 +30,15 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Connect actions */
|
/* Connect actions */
|
||||||
connect(images, &ImageList::newImage, ui->viewer, &Viewer::showImage);
|
connect(images, &ImageList::newImage, this, &MainWindow::showImage);
|
||||||
connect(source, &Source::newImage, ui->viewer, &Viewer::showImage);
|
connect(source, &Source::newFrame, this, &MainWindow::showFrame);
|
||||||
connect(filters, &FilterList::filtersChanged,ui->viewer, &Viewer::updateImage);
|
connect(filters, &FilterList::filterChanged, this, &MainWindow::render);
|
||||||
connect(ui->actionRedraw, &QAction::triggered, ui->viewer, &Viewer::updateImage);
|
connect(ui->actionRedraw, &QAction::triggered, this, &MainWindow::render);
|
||||||
|
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::showAbout);
|
||||||
|
connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close);
|
||||||
connect(ui->actionReset, &QAction::triggered, ui->viewer, &Viewer::reset);
|
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->actionExit, &QAction::triggered, this, &MainWindow::close);
|
|
||||||
connect(ui->actionClear, &QAction::triggered, images, &ImageList::clear);
|
connect(ui->actionClear, &QAction::triggered, images, &ImageList::clear);
|
||||||
connect(ui->actionLoad, &QAction::triggered, images, &ImageList::loadFilePicker);
|
connect(ui->actionLoad, &QAction::triggered, images, &ImageList::loadFilePicker);
|
||||||
connect(ui->actionSave, &QAction::triggered, images, &ImageList::saveFilePicker);
|
connect(ui->actionSave, &QAction::triggered, images, &ImageList::saveFilePicker);
|
||||||
|
@ -46,6 +46,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
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->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); });
|
||||||
connect(ui->actionTabCamera, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabCamera); });
|
connect(ui->actionTabCamera, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabCamera); });
|
||||||
|
@ -55,11 +56,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
showMaximized();
|
showMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showEvent(QShowEvent *)
|
|
||||||
{
|
|
||||||
ui->viewer->showImage(images->getCurrent());
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
|
@ -73,3 +69,33 @@ void MainWindow::showAbout()
|
||||||
about.setupUi(&dialog);
|
about.setupUi(&dialog);
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::showImage(Image *i)
|
||||||
|
{
|
||||||
|
source->play(false);
|
||||||
|
|
||||||
|
showFrame(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showFrame(Image *i)
|
||||||
|
{
|
||||||
|
currentImage = i;
|
||||||
|
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::render()
|
||||||
|
{
|
||||||
|
currentImage->getMat().release();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (Filter *filter : *filters)
|
||||||
|
filter->apply(currentImage);
|
||||||
|
} catch (Exception e) {
|
||||||
|
qCritical("%s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Rendering completed";
|
||||||
|
|
||||||
|
ui->viewer->showImage(currentImage);
|
||||||
|
}
|
||||||
|
|
11
mainwindow.h
11
mainwindow.h
|
@ -29,16 +29,19 @@ class MainWindow : public QMainWindow
|
||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
|
Image * getCurrentImage() { return currentImage; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showAbout();
|
void showAbout();
|
||||||
|
void showImage(Image *img);
|
||||||
|
void showFrame(Image *img);
|
||||||
|
void render();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
void showEvent(QShowEvent *se);
|
Image *currentImage;
|
||||||
|
|
||||||
signals:
|
|
||||||
void newImage(Image *img);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
3
pad.h
3
pad.h
|
@ -13,8 +13,11 @@ class Pad : public RotatedRect
|
||||||
Pad(const Point &p);
|
Pad(const Point &p);
|
||||||
Pad(const RotatedRect &p);
|
Pad(const RotatedRect &p);
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
double getArea() const { return size.area(); }
|
double getArea() const { return size.area(); }
|
||||||
double getRatio() const { return qMax(size.width, size.height) / qMin(size.width, size.height); }
|
double getRatio() const { return qMax(size.width, size.height) / qMin(size.width, size.height); }
|
||||||
|
double getDistance(const Pad &b) const { return norm(center - b.center); }
|
||||||
|
double getDistance(const Point2f &b) const { return norm(center - b); }
|
||||||
Point2f getCenter() const { return center; }
|
Point2f getCenter() const { return center; }
|
||||||
Point2f const * getVertexes() const { return vertexes; }
|
Point2f const * getVertexes() const { return vertexes; }
|
||||||
|
|
||||||
|
|
37
painter.cpp
37
painter.cpp
|
@ -1,11 +1,39 @@
|
||||||
#include "painter.h"
|
#include "painter.h"
|
||||||
|
#include "filters/filter.h"
|
||||||
|
|
||||||
|
Painter::Painter(QPaintDevice *dev) :
|
||||||
|
QPainter(dev)
|
||||||
|
{
|
||||||
|
setRenderHint(Antialiasing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawOverlay(Image *img)
|
||||||
|
{
|
||||||
|
for (Filter *filter : img->results.keys()) {
|
||||||
|
Result *result = img->getResult(filter);
|
||||||
|
if (result && filter->isShown()) {
|
||||||
|
save();
|
||||||
|
|
||||||
|
/*QTransform t;
|
||||||
|
for (auto it2 = it+1; it2 != filters->end(); it2++) {
|
||||||
|
Result *result2 = img->getResult(*it2);
|
||||||
|
if (result2 && (*it2)->isShown())
|
||||||
|
t *= result2->getTransform();
|
||||||
|
}
|
||||||
|
p.setWorldTransform(t * transform);*/
|
||||||
|
|
||||||
|
result->drawResult(this);
|
||||||
|
restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Painter::drawMarker(const QPoint ¢er, int r)
|
void Painter::drawMarker(const QPoint ¢er, int r)
|
||||||
{
|
{
|
||||||
QBrush br(Qt::NoBrush);
|
QBrush br(Qt::NoBrush);
|
||||||
setBrush(br);
|
setBrush(br);
|
||||||
|
|
||||||
r /= getRatio();
|
r *= ratio;
|
||||||
|
|
||||||
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));
|
||||||
|
@ -27,12 +55,7 @@ void Painter::setPen(const QPen &pen)
|
||||||
{
|
{
|
||||||
QPen p(pen);
|
QPen p(pen);
|
||||||
|
|
||||||
p.setWidthF((double) p.widthF() / getRatio());
|
p.setWidthF((double) p.widthF() * ratio);
|
||||||
|
|
||||||
QPainter::setPen(p);
|
QPainter::setPen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Painter::getRatio()
|
|
||||||
{
|
|
||||||
return (transform().m11() + transform().m22()) / 2;
|
|
||||||
}
|
|
||||||
|
|
13
painter.h
13
painter.h
|
@ -3,15 +3,16 @@
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
#include "cast.h"
|
#include "cast.h"
|
||||||
#include "pad.h"
|
#include "pad.h"
|
||||||
|
|
||||||
class Painter : public QPainter
|
class Painter : public QPainter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Painter(QPaintDevice *dev) :
|
Painter(QPaintDevice *dev);
|
||||||
QPainter(dev)
|
|
||||||
{ }
|
void drawOverlay(Image *p);
|
||||||
|
|
||||||
void drawMarker(const QPoint ¢er, int radius = 8);
|
void drawMarker(const QPoint ¢er, int radius = 8);
|
||||||
void drawPad(const Pad &pad);
|
void drawPad(const Pad &pad);
|
||||||
|
@ -19,7 +20,11 @@ class Painter : public QPainter
|
||||||
/* Proxy to adjust width */
|
/* Proxy to adjust width */
|
||||||
void setPen(const QPen &pen);
|
void setPen(const QPen &pen);
|
||||||
|
|
||||||
double getRatio();
|
double getRatio() const { return ratio; }
|
||||||
|
void setRatio(double r) { ratio = r; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PAINTER_H
|
#endif // PAINTER_H
|
||||||
|
|
|
@ -75,7 +75,7 @@ void Source::tick()
|
||||||
|
|
||||||
if (read(m)) {
|
if (read(m)) {
|
||||||
last.setSourceMat(m);
|
last.setSourceMat(m);
|
||||||
emit newImage(&last);
|
emit newFrame(&last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
source.h
2
source.h
|
@ -31,7 +31,7 @@ class Source :
|
||||||
void play(bool);
|
void play(bool);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newImage(Image *img);
|
void newFrame(Image *img);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void tick();
|
void tick();
|
||||||
|
|
|
@ -13,6 +13,11 @@ TabFilters::TabFilters(QWidget *parent) :
|
||||||
|
|
||||||
ui->tblFilters->setModel(filters);
|
ui->tblFilters->setModel(filters);
|
||||||
ui->tblFilters->setSelectionModel(&filters->selection);
|
ui->tblFilters->setSelectionModel(&filters->selection);
|
||||||
|
ui->tblFilters->resizeColumnsToContents();
|
||||||
|
ui->tblFilters->resizeRowsToContents();
|
||||||
|
|
||||||
|
for (Filter *filter : *filters)
|
||||||
|
ui->wdgSettings->addWidget(filter->getWidget(this));
|
||||||
|
|
||||||
connect(ui->tblFilters->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
connect(ui->tblFilters->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
||||||
ui->tblFilters->resizeColumnsToContents();
|
ui->tblFilters->resizeColumnsToContents();
|
||||||
|
@ -25,7 +30,6 @@ TabFilters::TabFilters(QWidget *parent) :
|
||||||
connect(filters, &FilterList::filterAdded, [&] (Filter *filter) {
|
connect(filters, &FilterList::filterAdded, [&] (Filter *filter) {
|
||||||
ui->wdgSettings->addWidget(filter->getWidget(this));
|
ui->wdgSettings->addWidget(filter->getWidget(this));
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TabFilters::~TabFilters()
|
TabFilters::~TabFilters()
|
||||||
|
|
|
@ -14,11 +14,14 @@ TabImages::TabImages(QWidget *parent) :
|
||||||
ui->tblImages->setModel(images);
|
ui->tblImages->setModel(images);
|
||||||
ui->tblImages->setSelectionModel(&images->selection);
|
ui->tblImages->setSelectionModel(&images->selection);
|
||||||
ui->tblImages->setColumnWidth(0, 200);
|
ui->tblImages->setColumnWidth(0, 200);
|
||||||
|
ui->tblImages->resizeColumnsToContents();
|
||||||
|
ui->tblImages->resizeRowsToContents();
|
||||||
|
|
||||||
connect(ui->tblImages->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
connect(ui->tblImages->verticalHeader(), &QHeaderView::sectionCountChanged, [&]() {
|
||||||
ui->tblImages->resizeColumnsToContents();
|
ui->tblImages->resizeColumnsToContents();
|
||||||
ui->tblImages->resizeRowsToContents();
|
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);
|
||||||
|
|
94
viewer.cpp
94
viewer.cpp
|
@ -17,6 +17,7 @@ extern FilterList *filters;
|
||||||
|
|
||||||
Viewer::Viewer(QWidget *parent) :
|
Viewer::Viewer(QWidget *parent) :
|
||||||
QGLWidget(parent),
|
QGLWidget(parent),
|
||||||
|
mouseMode(MOUSE_NONE),
|
||||||
img(NULL)
|
img(NULL)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -36,10 +37,10 @@ void Viewer::paintEvent(QPaintEvent *)
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
QPen pe;
|
QPen pe;
|
||||||
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
|
||||||
p.fillRect(rect(), Qt::black);
|
p.fillRect(rect(), Qt::black);
|
||||||
p.setClipRect(viewport);
|
p.setClipRect(viewport);
|
||||||
p.setTransform(transform);
|
p.setTransform(transform);
|
||||||
|
p.setRatio(1 / transform.m11());
|
||||||
|
|
||||||
pe.setStyle(Qt::SolidLine);
|
pe.setStyle(Qt::SolidLine);
|
||||||
pe.setWidth(2);
|
pe.setWidth(2);
|
||||||
|
@ -48,26 +49,10 @@ void Viewer::paintEvent(QPaintEvent *)
|
||||||
if (img) {
|
if (img) {
|
||||||
p.drawImage(window, qimg, window);
|
p.drawImage(window, qimg, window);
|
||||||
|
|
||||||
for (auto it = filters->begin(); it != filters->end(); it++) {
|
p.drawOverlay(img);
|
||||||
Result *result = img->getResult(*it);
|
|
||||||
if (result && (*it)->isShown()) {
|
|
||||||
p.save();
|
|
||||||
|
|
||||||
/*QTransform t;
|
|
||||||
for (auto it2 = it+1; it2 != filters->end(); it2++) {
|
|
||||||
Result *result2 = img->getResult(*it2);
|
|
||||||
if (result2 && (*it2)->isShown())
|
|
||||||
t *= result2->getTransform();
|
|
||||||
}
|
|
||||||
p.setWorldTransform(t * transform);*/
|
|
||||||
|
|
||||||
result->drawResult(&p);
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!first.isNull() && !last.isNull()) {
|
if (mouseMode == MOUSE_ZOOMING) {
|
||||||
QRect sel(unmap(first), unmap(last));
|
QRect sel(unmap(first), unmap(last));
|
||||||
|
|
||||||
pe.setWidth(2);
|
pe.setWidth(2);
|
||||||
|
@ -85,6 +70,11 @@ void Viewer::paintEvent(QPaintEvent *)
|
||||||
|
|
||||||
void Viewer::wheelEvent(QWheelEvent * we)
|
void Viewer::wheelEvent(QWheelEvent * we)
|
||||||
{
|
{
|
||||||
|
if (mouseMode != MOUSE_NONE) {
|
||||||
|
we->ignore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QPoint numPixels = we->pixelDelta();
|
QPoint numPixels = we->pixelDelta();
|
||||||
QPoint numDegrees = we->angleDelta() / 8;
|
QPoint numDegrees = we->angleDelta() / 8;
|
||||||
|
|
||||||
|
@ -113,80 +103,70 @@ void Viewer::wheelEvent(QWheelEvent * we)
|
||||||
void Viewer::mousePressEvent(QMouseEvent *me)
|
void Viewer::mousePressEvent(QMouseEvent *me)
|
||||||
{
|
{
|
||||||
if (viewport.contains(me->pos())) {
|
if (viewport.contains(me->pos())) {
|
||||||
|
first = me->pos();
|
||||||
|
last = me->pos();
|
||||||
|
|
||||||
if (me->modifiers() & Qt::AltModifier)
|
if (me->modifiers() & Qt::AltModifier)
|
||||||
first = me->pos();
|
mouseMode = MOUSE_ZOOMING;
|
||||||
else
|
else
|
||||||
last = me->pos();
|
mouseMode = MOUSE_DRAGGING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::mouseMoveEvent(QMouseEvent *me)
|
void Viewer::mouseMoveEvent(QMouseEvent *me)
|
||||||
{
|
{
|
||||||
if (viewport.contains(me->pos())) {
|
if (viewport.contains(me->pos())) {
|
||||||
if (me->modifiers() & Qt::AltModifier) {
|
if (mouseMode == MOUSE_ZOOMING)
|
||||||
update();
|
{ } /* draw zoom rectangle */
|
||||||
}
|
else if (mouseMode == MOUSE_DRAGGING) {
|
||||||
else {
|
|
||||||
QPoint delta = (me->pos() - last) / transform.m11();
|
QPoint delta = (me->pos() - last) / transform.m11();
|
||||||
window.moveCenter(window.center() - delta);
|
window.moveCenter(window.center() - delta);
|
||||||
|
|
||||||
updateWindow(window);
|
updateWindow(window);
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last = me->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
last = me->pos();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::mouseReleaseEvent(QMouseEvent *me)
|
void Viewer::mouseReleaseEvent(QMouseEvent *me)
|
||||||
{
|
{
|
||||||
if (viewport.contains(me->pos())) {
|
if (viewport.contains(me->pos())) {
|
||||||
if (me->modifiers() & Qt::AltModifier) {
|
if (mouseMode == MOUSE_ZOOMING) {
|
||||||
if (!first.isNull() && !last.isNull())
|
if (!first.isNull() && !last.isNull()) {
|
||||||
updateWindow(QRect(unmap(first), unmap(last)).normalized());
|
updateWindow(QRect(unmap(first), unmap(last)).normalized());
|
||||||
|
|
||||||
|
first = QPoint();
|
||||||
|
last = QPoint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (last.isNull()) {
|
else if (mouseMode == MOUSE_DRAGGING) {
|
||||||
QPoint pos = unmap(me->pos());
|
QPoint pos = unmap(me->pos());
|
||||||
Filter *f = filters->getCurrent();
|
Filter *f = filters->getCurrent();
|
||||||
|
|
||||||
qDebug() << "Clicked at: " << pos << "(" << me->pos() << ")";
|
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
if (f->clicked(toCv(pos), me))
|
qDebug() << "Clicked at: " << pos << "(" << me->pos() << ") << for filer " << f->getName();
|
||||||
updateImage();
|
f->clicked(toCv(pos), me);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
first = last = QPoint();
|
mouseMode = MOUSE_NONE;
|
||||||
|
first = last = QPoint();
|
||||||
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::showImage(Image *next)
|
void Viewer::showImage(Image *next)
|
||||||
{
|
{
|
||||||
if (next) {
|
img = next;
|
||||||
if (next != img)
|
qimg = img->getQImage();
|
||||||
filters->reset();
|
|
||||||
|
|
||||||
img = next;
|
if (window.size() != qimg.size())
|
||||||
updateImage();
|
updateWindow(QRect(QPoint(), qimg.size()));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::updateImage()
|
update();
|
||||||
{
|
|
||||||
if (img) {
|
|
||||||
filters->execute(img);
|
|
||||||
|
|
||||||
Mat &m = img->getMat();
|
|
||||||
qimg = toQImage(m);
|
|
||||||
|
|
||||||
if (window.size() != toQt(m.size()))
|
|
||||||
updateWindow(QRect(0, 0, m.cols, m.rows));
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::updateWindow(const QRect &win)
|
void Viewer::updateWindow(const QRect &win)
|
||||||
|
|
7
viewer.h
7
viewer.h
|
@ -18,6 +18,12 @@ class Viewer : public QGLWidget
|
||||||
explicit Viewer(QWidget *parent = 0);
|
explicit Viewer(QWidget *parent = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
enum MouseMode {
|
||||||
|
MOUSE_NONE,
|
||||||
|
MOUSE_ZOOMING,
|
||||||
|
MOUSE_DRAGGING
|
||||||
|
} mouseMode;
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *pe);
|
void paintEvent(QPaintEvent *pe);
|
||||||
void resizeEvent(QResizeEvent *re);
|
void resizeEvent(QResizeEvent *re);
|
||||||
|
|
||||||
|
@ -41,7 +47,6 @@ class Viewer : public QGLWidget
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showImage(Image *img);
|
void showImage(Image *img);
|
||||||
void updateImage();
|
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue