Skip to content

Commit

Permalink
added BiNI bilateral normal integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
ponchio committed Jan 19, 2024
1 parent 6fb43ff commit 2007218
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 51 deletions.
46 changes: 32 additions & 14 deletions relight/normalstask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../src/jpeg_encoder.h"
#include "../src/imageset.h"
#include "../src/relight_threadpool.h"
#include "../src/bni_normal_integration.h"

#include <Eigen/Eigen>
#include <Eigen/Core>
Expand All @@ -27,7 +28,7 @@ void NormalsTask::run()
{
status = RUNNING;
// ImageSet initialization
ImageSet imageSet(m_InputFolder.toStdString().c_str());
ImageSet imageSet(input_folder.toStdString().c_str());

QList<QVariant> qlights = (*this)["lights"].value.toList();
std::vector<Vector3f> lights(qlights.size()/3);
Expand All @@ -52,7 +53,8 @@ void NormalsTask::run()
}
imageSet.crop(m_Crop.left(), m_Crop.top(), m_Crop.width(), m_Crop.height());

std::vector<uint8_t> normals(imageSet.width * imageSet.height * 3);
//std::vector<uint8_t> normals(imageSet.width * imageSet.height * 3);
std::vector<float> normals(imageSet.width * imageSet.height * 3);

// Thread pool used to handle the processors
RelightThreadPool pool;
Expand All @@ -68,10 +70,11 @@ void NormalsTask::run()

// Create the normal task and get the run lambda
uint32_t idx = i * 3 * imageSet.width;
uint8_t* data = normals.data() + idx;
//uint8_t* data = normals.data() + idx;
float* data = &normals[idx];

std::function<void(void)> run = [this, &line, &imageSet, data](void)->void {
NormalsWorker task(m_Method, line, data, imageSet.lights);
NormalsWorker task(solver, line, data, imageSet.lights);
return task.run();
};

Expand All @@ -84,11 +87,22 @@ void NormalsTask::run()

// Wait for the end of all the threads
pool.finish();
// Save the final result
QImage img(normals.data(), imageSet.width, imageSet.height, imageSet.width*3, QImage::Format_RGB888);
img.save(m_OutputFolder);
progressed("Cleaning up...", 99);

std::vector<uint8_t> normalmap(imageSet.width * imageSet.height * 3);
for(size_t i = 0; i < normals.size(); i++)
normalmap[i] = floor(((normals[i] + 1.0f) / 2.0f) * 255);

// Save the final result
QImage img(normalmap.data(), imageSet.width, imageSet.height, imageSet.width*3, QImage::Format_RGB888);
img.save(output);

if(exportSurface) {
progressed("Integrating normals...", 0);
auto z = bni_integrate(imageSet.width, imageSet.height, normals, exportK);
QString filename = output.left(output.size() -4) + ".ply";
progressed("Saving surface...", 99);
savePly(filename, imageSet.width, imageSet.height, z);
}
int end = clock();
qDebug() << "Time: " << ((double)(end - start) / CLOCKS_PER_SEC);
progressed("Finished", 100);
Expand Down Expand Up @@ -118,18 +132,18 @@ bool NormalsTask::progressed(std::string s, int percent)

void NormalsWorker::run()
{
switch (m_Method)
switch (solver)
{
// L2 solver
case 0:
case NORMALS_L2:
solveL2();
break;
// SBL solver
case 4:
case NORMALS_SBL:
solveSBL();
break;
// RPCA solver
case 5:
case NORMALS_RPCA:
solveRPCA();
break;
}
Expand All @@ -154,6 +168,7 @@ void NormalsWorker::solveL2()
mLights(i, j) = m_Lights[i][j];

// For each pixel in the line solve the system
//TODO do it in a single pass, it's faster.
for (size_t p = 0; p < m_Row.size(); p++) {
// Fill the pixel vector
for (size_t m = 0; m < m_Lights.size(); m++)
Expand All @@ -164,9 +179,12 @@ void NormalsWorker::solveL2()
mNormals.col(0).normalize();

// Save
m_Normals[normalIdx] = floor(((mNormals(0, 0) + 1.0f) / 2.0f) * 255);
/*m_Normals[normalIdx] = floor(((mNormals(0, 0) + 1.0f) / 2.0f) * 255);
m_Normals[normalIdx+1] = floor(((mNormals(1, 0) + 1.0f) / 2.0f) * 255);
m_Normals[normalIdx+2] = floor(((mNormals(2, 0) + 1.0f) / 2.0f) * 255);
m_Normals[normalIdx+2] = floor(((mNormals(2, 0) + 1.0f) / 2.0f) * 255);*/
m_Normals[normalIdx+0] = mNormals(0,0);
m_Normals[normalIdx+1] = mNormals(1,0);
m_Normals[normalIdx+2] = mNormals(2,0);

normalIdx += 3;
}
Expand Down
30 changes: 20 additions & 10 deletions relight/normalstask.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,49 @@
#include "task.h"
#include <QRunnable>

enum NormalSolver { NORMALS_L2, NORMALS_SBL, NORMALS_RPCA };


class NormalsTask : public Task
{
public:
NormalsTask(QString& inputPath, QString& outputPath, QRect crop, uint32_t method) :
m_InputFolder(inputPath), m_OutputFolder(outputPath), m_Crop(crop), m_Method(method){}
NormalSolver solver;
bool exportSurface = false;
bool exportK = 2.0;
QRect m_Crop;

NormalsTask(QString& inputPath, QString& outputPath, QRect crop, NormalSolver _solver) :
m_Crop(crop), solver(_solver) {
input_folder = inputPath;
output = outputPath;
}
virtual ~NormalsTask(){};

virtual void run() override;

public slots:
bool progressed(std::string str, int percent) override;
private:
QString m_InputFolder;
QString m_OutputFolder;
QRect m_Crop;
uint32_t m_Method;


};

class NormalsWorker
{
public:
NormalsWorker(unsigned int method, PixelArray& toProcess, uint8_t* normals, std::vector<Vector3f> lights) :
m_Method(method), m_Row(toProcess), m_Normals(normals), m_Lights(lights){}
NormalsWorker(NormalSolver _solver, PixelArray& toProcess, float* normals, std::vector<Vector3f> lights) :
solver(_solver), m_Row(toProcess), m_Normals(normals), m_Lights(lights){}

void run();
private:
void solveL2();
void solveSBL();
void solveRPCA();
private:
uint32_t m_Method;
NormalSolver solver;
PixelArray m_Row;
uint8_t* m_Normals;
//uint8_t* m_Normals;
float* m_Normals;
std::vector<Vector3f> m_Lights;
QMutex m_Mutex;
};
2 changes: 2 additions & 0 deletions relight/relight.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mac:QMAKE_LFLAGS += -lomp
mac:LIBS += -L /usr/local/lib /usr/local/lib/libomp.dylib

SOURCES += main.cpp \
../src/bni_normal_integration.cpp \
dstretchdialog.cpp \
dstretchtask.cpp \
history.cpp \
Expand Down Expand Up @@ -84,6 +85,7 @@ SOURCES += main.cpp \


HEADERS += \
../src/bni_normal_integration.h \
../src/deepzoom.h \
dstretch.h \
dstretchdialog.h \
Expand Down
15 changes: 9 additions & 6 deletions relight/rtiexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,20 @@ void RtiExport::createNormals() {
output += ".png";

// Get normal method
unsigned int method = 0; //least squares
NormalSolver solver = NORMALS_L2; //least squares
if(ui->l2_solver->isChecked())
method = 0;
solver = NORMALS_L2;
if(ui->sbl_solver->isChecked())
method = 4;
solver = NORMALS_SBL;
if(ui->rpca_solver->isChecked())
method = 5;
solver = NORMALS_RPCA;


ProcessQueue &queue = ProcessQueue::instance();
NormalsTask *task = new NormalsTask(path, output, crop, method);

ProcessQueue &queue = ProcessQueue::instance();
NormalsTask *task = new NormalsTask(path, output, crop, solver);
task->exportSurface = ui->export_surface->isChecked();
task->exportK = ui->discontinuity->value();
QList<QVariant> slights;
for(auto light: lights)
for(int k = 0; k < 3; k++)
Expand Down
56 changes: 43 additions & 13 deletions relight/rtiexport.ui
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="ImageCropper" name="cropview">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
Expand All @@ -24,7 +24,7 @@
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="QTabWidget" name="export_frame">
<property name="currentIndex">
<number>0</number>
Expand Down Expand Up @@ -286,13 +286,23 @@
<attribute name="title">
<string>Normals</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Solver</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<widget class="QRadioButton" name="sbl_solver">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sparse Baesian</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="l2_solver">
<property name="text">
Expand All @@ -303,23 +313,43 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="sbl_solver">
<item row="3" column="0">
<widget class="QRadioButton" name="rpca_solver">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sparse Baesian</string>
<string>Robust PCA</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="rpca_solver">
<property name="enabled">
<bool>false</bool>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>3D Surface</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="export_surface">
<property name="text">
<string>Export ply surface</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Robust PCA</string>
<string>Discontinuity</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="discontinuity">
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
Expand Down Expand Up @@ -361,7 +391,7 @@
</widget>
</widget>
</item>
<item>
<item row="0" column="2">
<widget class="QFrame" name="crop_frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
Expand Down
2 changes: 1 addition & 1 deletion relight/settingsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
Expand Down
14 changes: 7 additions & 7 deletions relight/zoomdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
</size>
</property>
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="Deepzoom">
<property name="sizePolicy">
Expand Down Expand Up @@ -107,8 +107,8 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:7.8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="placeholderText">
<string>Select a folder</string>
Expand Down Expand Up @@ -287,8 +287,8 @@ p, li { white-space: pre-wrap; }
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:7.8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="placeholderText">
<string>Select a folder</string>
Expand Down Expand Up @@ -382,8 +382,8 @@ p, li { white-space: pre-wrap; }
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:7.8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="placeholderText">
<string>Select a folder</string>
Expand Down
Loading

0 comments on commit 2007218

Please sign in to comment.