Skip to content

Commit 7f8407b

Browse files
committed
added ecc based alignment
1 parent a1a8691 commit 7f8407b

14 files changed

+107
-27
lines changed

align/imagealignment.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "imagealignment.h"
2-
2+
#include <opencv2/opencv.hpp>
33
#include <iostream>
44
using namespace std;
55

align/main.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ std::vector<Offset> readOffsetsCSV(const QString &filePath) {
136136
return offsets;
137137
}
138138

139-
void analyzeErrors(const std::vector<QPoint> &calculatedOffsets, const std::vector<Offset> &trueOffsets) {
139+
void analyzeErrors(const std::vector<cv::Point2f> &calculatedOffsets, const std::vector<cv::Point2f> &trueOffsets) {
140140
if (calculatedOffsets.size() != trueOffsets.size()) {
141141
cerr << "Number of compute offsets and real offsets not matching" << endl;
142142
return;
@@ -150,11 +150,11 @@ void analyzeErrors(const std::vector<QPoint> &calculatedOffsets, const std::vect
150150

151151
cout << "Differenze calcolate:" << endl;
152152
for (size_t i = 0; i < calculatedOffsets.size(); i++) {
153-
int dx = std::abs(calculatedOffsets[i].x() - trueOffsets[i].x);
154-
int dy = std::abs(calculatedOffsets[i].y() - trueOffsets[i].y);
153+
int dx = std::abs(calculatedOffsets[i].x - trueOffsets[i].x);
154+
int dy = std::abs(calculatedOffsets[i].y - trueOffsets[i].y);
155155
double error = std::sqrt(dx * dx + dy * dy); // Distanza euclidea
156156

157-
cout << "Offset [" << i << "] - Calcolato: (" << calculatedOffsets[i].x() << ", " << calculatedOffsets[i].y()
157+
cout << "Offset [" << i << "] - Calcolato: (" << calculatedOffsets[i].x << ", " << calculatedOffsets[i].y
158158
<< "), Reale: (" << trueOffsets[i].x << ", " << trueOffsets[i].y << "), ΔX: " << dx << ", ΔY: " << dy
159159
<< ", Errore: " << error << endl;
160160

@@ -228,7 +228,7 @@ int main(int argc, char *argv[]) {
228228
}
229229

230230
int max_offset = QString(argv[2]).toInt();
231-
int radius = max_offset / 4;
231+
int radius = max_offset / 8;
232232
QStringList c = QString(argv[3]).split(":");
233233

234234
//random
@@ -258,9 +258,8 @@ int main(int argc, char *argv[]) {
258258
samples.push_back(img(region));
259259
original_offsets.push_back(cv::Point2f(-dx, -dy));
260260
}
261-
alignment.testAlign();
262-
return 0;
263-
alignment.alignSamples(false);
261+
alignment.alignSamples(true);
262+
264263
for(int i = 0; i < original_offsets.size(); i++) {
265264
auto o = alignment.offsets[i];
266265
if(o.x == 0 && o.y == 0 && i != 0) {

relightlab/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ target_link_libraries(
185185
${JPEG_LIBRARIES}
186186
TIFF::TIFF
187187
OpenMP::OpenMP_CXX
188+
opencv_core opencv_imgcodecs opencv_imgproc opencv_video
188189
${RELIGHT_QT}::Core
189190
${RELIGHT_QT}::Gui
190191
${RELIGHT_QT}::Widgets

relightlab/alignframe.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ AlignFrame::AlignFrame(QWidget *parent): QFrame(parent) {
1919
QVBoxLayout *content = new QVBoxLayout(this);
2020

2121
content->addSpacing(10);
22-
QPushButton *new_align = new QPushButton("New align...");
22+
QPushButton *new_align = new QPushButton("New alignment...");
2323
new_align->setProperty("class", "large");
2424
content->addWidget(new_align);
2525
new_align->setMinimumWidth(200);

relightlab/alignrow.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
FindAlignment::FindAlignment(Align *_align, bool update) {
1717
align = _align;
1818
update_positions = update;
19+
visible = false;
1920
}
2021

2122
void FindAlignment::run() {

relightlab/processqueue.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ bool ProcessQueue::hasTasks() {
7575
if(task) return true;
7676
return queue.size() > 0;
7777
}
78+
bool ProcessQueue::contains(Task *a) {
79+
QMutexLocker locker(&lock);
80+
return queue.indexOf(a) >= 0 || past.indexOf(a) >= 0;
81+
82+
}
83+
7884

7985
void ProcessQueue::addTask(Task *a, bool paused) {
8086
if(paused)
@@ -87,11 +93,15 @@ void ProcessQueue::addTask(Task *a, bool paused) {
8793

8894
void ProcessQueue::removeTask(Task *a) {
8995
QMutexLocker locker(&lock);
90-
int index = queue.indexOf(a);
91-
if(index < 0)
92-
return;
96+
int index = past.indexOf(a);
97+
if(index >= 0) {
98+
past.takeAt(index);
9399

94-
queue.takeAt(index);
100+
}
101+
index = queue.indexOf(a);
102+
if(index >= 0) {
103+
queue.takeAt(index);
104+
}
95105
emit update();
96106
}
97107

relightlab/processqueue.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ProcessQueue: public QThread {
3535

3636
bool hasTasks();
3737
void addTask(Task *a, bool paused = false);
38+
bool contains(Task *a);
3839
void removeTask(Task *a);
3940
void removeTask(int id);
4041
void pushFront(int id);

relightlab/queueframe.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,19 @@ void QueueFrame::selectionChanged(const QItemSelection & selected, const QItemSe
161161

162162

163163
void QueueFrame::update() {
164+
ProcessQueue &queue = ProcessQueue::instance();
164165
QSet<int> tasks;
165166
//check status of each widget
166167
for(int i = 0; i < list->count(); i++) {
167168
QueueItem *item = (QueueItem *)list->item(i);
169+
//check for deleted tasks
170+
if(!queue.contains(item->task)) {
171+
throw QString("Delete task!");
172+
}
168173
item->update();
169174
tasks.insert(item->id);
170175
}
171-
ProcessQueue &queue = ProcessQueue::instance();
176+
172177

173178
//add all task not already present.
174179
for(Task *task: queue.queue) {

relightlab/relightlab.pro

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ win32:INCLUDEPATH += ../external/libjpeg-turbo-2.0.6/include \
1616
../src/
1717
win32:LIBS += ../external/libjpeg-turbo-2.0.6/lib/jpeg-static.lib
1818

19-
unix:INCLUDEPATH += ../external/eigen-3.3.9/
20-
unix:LIBS += -ljpeg -ltiff -lgomp
19+
unix:INCLUDEPATH += ../external/eigen-3.3.9/ /usr/include/opencv4
20+
unix:LIBS += -ljpeg -ltiff -lgomp -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_video
2121
#unix:QMAKE_CXXFLAGS += -fopenmp
2222

2323

relightlab/verifydialog.cpp

+54-8
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
#include <QScrollArea>
88
#include <QVBoxLayout>
9+
#include <QPushButton>
910
#include <QImage>
1011
#include <QLabel>
1112
#include <QDialogButtonBox>
12-
#include "assert.h"
1313

14+
#include <opencv2/opencv.hpp>
15+
16+
#include "assert.h"
1417
#include <iostream>
1518
using namespace std;
1619

@@ -20,6 +23,16 @@ VerifyDialog::VerifyDialog(std::vector<QImage> &_thumbs, std::vector<QPointF> &_
2023

2124
showMaximized();
2225
QVBoxLayout *layout = new QVBoxLayout(this);
26+
if(marker == ALIGN) {
27+
QHBoxLayout *operations_layout = new QHBoxLayout;
28+
layout->addLayout(operations_layout);
29+
QPushButton *reset = new QPushButton("Reset");
30+
operations_layout->addWidget(reset);
31+
QPushButton *ecc = new QPushButton("Align");
32+
operations_layout->addWidget(ecc);
33+
connect(reset, SIGNAL(clicked()), this, SLOT(resetAligns()));
34+
connect(ecc, SIGNAL(clicked()), this, SLOT(alignSamples()));
35+
}
2336
QScrollArea *area = new QScrollArea(this);
2437
layout->addWidget(area);
2538

@@ -32,16 +45,49 @@ VerifyDialog::VerifyDialog(std::vector<QImage> &_thumbs, std::vector<QPointF> &_
3245

3346
for(size_t i = 0; i < thumbs.size(); i++) {
3447
assert(!thumbs[i].isNull());
35-
if(marker == REFLECTION ) {
36-
VerifyView *thumb = new VerifyView(thumbs[i], 192, positions[i], VerifyMarker::REFLECTION);
37-
flowlayout->addWidget(thumb);
38-
} else {
39-
VerifyView *thumb = new VerifyView(thumbs[i], 192, positions[i], VerifyMarker::ALIGN);
40-
flowlayout->addWidget(thumb);
41-
}
48+
VerifyView *thumb = new VerifyView(thumbs[i], 192, positions[i], marker == REFLECTION? VerifyMarker::REFLECTION : VerifyMarker::ALIGN);
49+
views.push_back(thumb);
50+
flowlayout->addWidget(thumb);
4251
}
4352

4453
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
4554
layout->addWidget(buttonBox);
4655
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
4756
}
57+
58+
void VerifyDialog::resetAligns() {
59+
for(QPointF &p: positions)
60+
p = QPointF(0, 0);
61+
update();
62+
}
63+
64+
cv::Mat qimg2mat(QImage img) {
65+
QImage gray = img.convertToFormat(QImage::Format_Grayscale8);
66+
return cv::Mat(gray.height(), gray.width(), CV_8UC1,
67+
const_cast<uchar*>(gray.bits()), gray.bytesPerLine()).clone();
68+
}
69+
70+
void VerifyDialog::alignSamples() {
71+
if (positions.empty()) return;
72+
73+
cv::Mat ref = qimg2mat(thumbs[0]);
74+
75+
for (size_t i = 1; i < thumbs.size(); i++) {
76+
cv::Mat warpMat = cv::Mat::eye(2, 3, CV_32F);
77+
78+
try {
79+
cv::findTransformECC(ref, qimg2mat(thumbs[i]), warpMat, cv::MOTION_TRANSLATION);
80+
81+
positions[i] = QPointF(warpMat.at<float>(0, 2), warpMat.at<float>(1, 2));
82+
} catch(cv::Exception &e) {
83+
cerr << e.msg << endl;
84+
positions[i] = QPointF(0.0f, 0.0f);
85+
}
86+
}
87+
update();
88+
}
89+
90+
void VerifyDialog::update() {
91+
for(VerifyView *view: views)
92+
view->set();
93+
}

relightlab/verifydialog.h

+8
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,23 @@
55

66
class FlowLayout;
77
class Sphere;
8+
class VerifyView;
89

910

1011
class VerifyDialog: public QDialog {
12+
Q_OBJECT
1113
public:
1214
enum Markers { REFLECTION, ALIGN };
1315
VerifyDialog(std::vector<QImage> &thumbs, std::vector<QPointF> &positions, Markers marker, QWidget *parent = nullptr);
1416

17+
public slots:
18+
void alignSamples();
19+
void resetAligns();
20+
void update();
21+
1522
private:
1623
FlowLayout *flowlayout = nullptr;
24+
std::vector<VerifyView *> views;
1725
std::vector<QImage> &thumbs;
1826
std::vector<QPointF> &positions;
1927

relightlab/verifyview.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
VerifyMarker::VerifyMarker(VerifyView *_view, Marker _marker, QGraphicsItem *parent):
15-
QGraphicsItem(parent), view(_view), marker(_marker) {
15+
QGraphicsItem(parent), marker(_marker), view(_view) {
1616
setCursor(Qt::CrossCursor);
1717
setFlag(QGraphicsItem::ItemIsMovable);
1818
setFlag(QGraphicsItem::ItemIsSelectable);
@@ -96,6 +96,10 @@ void VerifyView::update() {
9696
marker_item->active = !pos.isNull();
9797
}
9898

99+
void VerifyView::set() {
100+
marker_item->setPos(center + pos);
101+
}
102+
99103
void VerifyView::resizeEvent(QResizeEvent *) {
100104
fitInView(img_item->boundingRect()); //.sceneRect()); //img_item);
101105
}

relightlab/verifyview.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class VerifyView: public QGraphicsView {
3333
VerifyMarker::Marker marker;
3434

3535
VerifyView(QImage &image, int height, QPointF &pos, VerifyMarker::Marker _marker, QWidget *parent = nullptr);
36-
void update();
36+
void update(); //update pos from marker
37+
void set(); //update marker from pos
3738

3839
protected:
3940
void resizeEvent(QResizeEvent *event) override;

src/project.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ void Project::clear() {
7070
delete sphere;
7171
spheres.clear();
7272

73+
for(auto align: aligns)
74+
delete align;
75+
aligns.clear();
76+
7377
for(auto m: measures)
7478
delete m;
7579
measures.clear();

0 commit comments

Comments
 (0)