Skip to content

Commit

Permalink
align with master branch
Browse files Browse the repository at this point in the history
  • Loading branch information
ponchio committed Nov 21, 2024
1 parent 8c759ea commit aae3437
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 69 deletions.
5 changes: 5 additions & 0 deletions relight/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,11 @@ void MainWindow::detectHighlights() {
progress->show();
progress->setMaximum(project.size());

//clean up reflection summary for each sphere.
for(Sphere *sphere: project.spheres) {
sphere->sphereImg = QImage();
}

QThreadPool::globalInstance()->setMaxThreadCount(1);
progress_jobs.clear();
for(size_t i = 0; i < project.size(); i++)
Expand Down
87 changes: 44 additions & 43 deletions relight/normalstask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,66 +18,66 @@
#include <iostream>
#include <time.h>

using namespace std;

//////////////////////////////////////////////////////// NORMALS TASK //////////////////////////////////////////////////////////
/// \brief NormalsTask: Takes care of creating the normals from the images given in a folder (inputFolder) and saves the file
/// in the outputFolder. After applying the crop described in the QRect passed as an argument to the constructor,
/// the NormalsTask creates a NormalsWorker for each line in the final image.
/// That NormalsWorker fills a vector with the colors of the normals in that line.
///

void NormalsTask::run()
{
void NormalsTask::run() {
status = RUNNING;
// ImageSet initialization
ImageSet imageSet(input_folder.toStdString().c_str());

QList<QVariant> qlights = (*this)["lights"].value.toList();
std::vector<Vector3f> lights(qlights.size()/3);
for(int i = 0; i < qlights.size(); i+= 3)
for(int k = 0; k < 3; k++)
lights[i/3][k] = qlights[i+k].toDouble();


ImageSet imageSet;
imageSet.images = (*this)["images"].value.toStringList();
imageSet.lights = lights;
imageSet.light3d = project->dome.lightConfiguration != Dome::DIRECTIONAL;
imageSet.image_width_mm = project->dome.imageWidth;
imageSet.dome_radius = project->dome.domeDiameter/2.0;
imageSet.vertical_offset = project->dome.verticalOffset;
imageSet.initLights();
imageSet.initImages(input_folder.toStdString().c_str());

if(hasParameter("crop")) {
QRect rect = (*this)["crop"].value.toRect();
imageSet.crop(rect.left(), rect.top(), rect.width(), rect.height());
}

// Normals vector


int start = clock();
// Init
imageSet.setCallback(nullptr);

// Set the crop
if(!m_Crop.isValid()) {
m_Crop.setLeft(0);
m_Crop.setWidth(imageSet.width);
m_Crop.setTop(0);
m_Crop.setHeight(imageSet.height);
}
imageSet.crop(m_Crop.left(), m_Crop.top(), m_Crop.width(), m_Crop.height());

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

// Thread pool used to handle the processors
RelightThreadPool pool;
// Line in the imageset to be processed
PixelArray line;

pool.start(QThread::idealThreadCount());

for (int i=0; i<imageSet.height; i++)
{
for (int i=0; i<imageSet.height; i++) {
// Read a line
imageSet.readLine(line);

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

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

std::function<void(void)> run = [this, task](void)->void {
task->run();
delete task;
};

// Launch the task
pool.queue(run);
pool.waitForSpace();

Expand Down Expand Up @@ -118,6 +118,12 @@ void NormalsTask::run()

// Save the final result
QImage img(normalmap.data(), imageSet.width, imageSet.height, imageSet.width*3, QImage::Format_RGB888);
// Set spatial resolution if known. Need to convert as pixelSize stored in mm/pixel whereas QImage requires pixels/m
if( pixelSize > 0 ) {
int dotsPerMeter = round(1000.0/pixelSize);
img.setDotsPerMeterX(dotsPerMeter);
img.setDotsPerMeterY(dotsPerMeter);
}
img.save(output);

std::function<bool(QString s, int d)> callback = [this](QString s, int n)->bool { return this->progressed(s, n); };
Expand Down Expand Up @@ -148,21 +154,6 @@ void NormalsTask::run()
qDebug() << "Time: " << ((double)(end - start) / CLOCKS_PER_SEC);
progressed("Finished", 100);
}
/*
bool NormalsTask::progressed(QString str, int percent)
{
if(status == PAUSED) {
mutex.lock(); //mutex should be already locked. this talls the
mutex.unlock();
}
if(status == STOPPED)
return false;
emit progress(str, percent);
if(status == STOPPED)
return false;
return true;
}*/

/**
* \brief NormalsWorker: generates the normals for a given line in the image set, depending on the method specified when
Expand Down Expand Up @@ -195,13 +186,16 @@ void NormalsWorker::run()

void NormalsWorker::solveL2()
{
std::vector<Vector3f> &m_Lights = m_Imageset.lights;
std::vector<Vector3f> &m_Lights3d = m_Imageset.lights3d;
// Pixel data
Eigen::MatrixXd mLights(m_Lights.size(), 3);
Eigen::MatrixXd mPixel(m_Lights.size(), 1);
Eigen::MatrixXd mNormals;

unsigned int normalIdx = 0;


// Fill the lights matrix
for (size_t i = 0; i < m_Lights.size(); i++)
for (int j = 0; j < 3; j++)
Expand All @@ -214,12 +208,19 @@ void NormalsWorker::solveL2()
for (size_t m = 0; m < m_Lights.size(); m++)
mPixel(m, 0) = m_Row[p][m].mean();

// Solve
mNormals = (mLights.transpose() * mLights).ldlt().solve(mLights.transpose() * mPixel);
mNormals.col(0).normalize();
if(m_Imageset.light3d) {
for(size_t i = 0; i < m_Lights3d.size(); i++) {
Vector3f light = m_Imageset.relativeLight(m_Lights3d[i], p, m_Imageset.height - row);
light.normalize();
for (int j = 0; j < 3; j++)
mLights(i, j) = light[j];
}
}


// Save

mNormals = (mLights.transpose() * mLights).ldlt().solve(mLights.transpose() * mPixel);
mNormals.col(0).normalize();
m_Normals[normalIdx+0] = mNormals(0, 0);
m_Normals[normalIdx+1] = mNormals(1, 0);
m_Normals[normalIdx+2] = mNormals(2, 0);
Expand Down
20 changes: 12 additions & 8 deletions relight/normalstask.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <QMutex>
#include <QRect>
#include "../src/relight_vector.h"
#include "../src/imageset.h"
#include "../src/project.h"
#include "task.h"
#include <QRunnable>

Expand All @@ -27,21 +29,23 @@ class NormalsTask : public Task
QRect m_Crop;
float pixelSize = 0.0f;

NormalsTask(QString& inputPath, QString& outputPath, QRect crop, NormalSolver _solver, FlatMethod _flatMethod) :
solver(_solver), flatMethod(_flatMethod), m_Crop(crop) {
input_folder = inputPath;
output = outputPath;
NormalsTask(Project *_project, NormalSolver _solver, FlatMethod _flatMethod) :
project(_project), solver(_solver), flatMethod(_flatMethod) {
}
virtual ~NormalsTask(){};
virtual void run() override;

private:
//TODO remove dependency on project!
Project *project;

};

class NormalsWorker
{
public:
NormalsWorker(NormalSolver _solver, PixelArray& toProcess, float* normals, std::vector<Vector3f> lights) :
solver(_solver), m_Row(toProcess), m_Normals(normals), m_Lights(lights){}
NormalsWorker(NormalSolver _solver, int _row, PixelArray& toProcess, float* normals, ImageSet &imageset) :
solver(_solver), row(_row), m_Row(toProcess), m_Normals(normals), m_Imageset(imageset){}

void run();
private:
Expand All @@ -50,9 +54,9 @@ class NormalsWorker
void solveRPCA();
private:
NormalSolver solver;
int row;
PixelArray m_Row;

float* m_Normals;
std::vector<Vector3f> m_Lights;
ImageSet &m_Imageset;
QMutex m_Mutex;
};
3 changes: 2 additions & 1 deletion relight/qspheremarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,14 @@ void SphereMarker::init() {
axis[1]->setLine(c.x(), c.y(), c.x() - dir.y()*sphere->eHeight, c.y() + dir.x()*sphere->eHeight);

double r1 = r * sphere->eHeight/sphere->eWidth;
smallcircle->setRect(c.x() - r, c.y() - r1, 2*r, 2*r1);
smallcircle->setTransformOriginPoint(c);
smallcircle->setRotation(sphere->eAngle);
} else {
circle->setRect(c.x()-R, c.y()-R, 2*R, 2*R);
smallcircle->setRect(c.x()-r, c.y()-r, 2*r, 2*r);
}
circle->setVisible(true);
smallcircle->setRect(c.x()-r, c.y()-r, 2*r, 2*r);
smallcircle->setVisible(true);
}

Expand Down
1 change: 0 additions & 1 deletion relight/relight.pro
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ SOURCES += main.cpp \
task.cpp \
rtitask.cpp \
settingsdialog.cpp \
../relight-cli/convert_rti.cpp \
domecalibration.cpp \
../src/lp.cpp \
qmarkerlist.cpp \
Expand Down
10 changes: 7 additions & 3 deletions relight/rtiexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,18 @@ void RtiExport::createNormals() {

double flat_radius = ui->flat_fourier_radius->value();


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

NormalsTask *task = new NormalsTask(project, solver, flat_method);
task->input_folder = path;
task->output = output;
task->exportSurface = ui->export_surface->isChecked();
// task->exportDepthmap = ui->export_depthmap->isChecked();
task->exportDepthmap = ui->export_depthmap->isChecked();
task->exportK = ui->discontinuity->value();
task->flat_radius = ui->flat_fourier_radius->value();

task->addParameter("images", Parameter::STRINGLIST, images);

QList<QVariant> slights;
for(auto light: lights)
for(int k = 0; k < 3; k++)
Expand Down
25 changes: 16 additions & 9 deletions relight/rtiexport.ui
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@
<attribute name="title">
<string>Normals</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Solver</string>
Expand Down Expand Up @@ -326,7 +326,7 @@
</layout>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>3D Surface</string>
Expand All @@ -339,14 +339,21 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="export_depthmap">
<property name="text">
<string>Export depth map</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Discontinuity</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="discontinuity">
<property name="value">
<double>2.000000000000000</double>
Expand All @@ -356,7 +363,7 @@
</layout>
</widget>
</item>
<item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Flatten normals</string>
Expand Down Expand Up @@ -393,7 +400,7 @@
</layout>
</widget>
</item>
<item>
<item row="3" column="0">
<widget class="QPushButton" name="crop1">
<property name="text">
<string>Crop...</string>
Expand All @@ -404,7 +411,7 @@
</property>
</widget>
</item>
<item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -417,7 +424,7 @@
</property>
</spacer>
</item>
<item>
<item row="5" column="0">
<widget class="QPushButton" name="build_normals">
<property name="text">
<string>Build</string>
Expand Down
1 change: 0 additions & 1 deletion relight/rtitask.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class RtiTask: public Task {
virtual void run() override;

public slots:

void relight(bool commonMinMax = false, bool saveLegacy = false); //use true for .rti and .ptm
void toRTI();
void fromRTI();
Expand Down
1 change: 1 addition & 0 deletions src/imageset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ void ImageSet::readLine(PixelArray &pixels) {
if(light3d) {
assert(lights3d.size() == size_t(images.size()));
for(Pixel &pixel: pixels) {
assert(pixel.size() == lights3d.size());
for(size_t i = 0; i < lights3d.size(); i++) {
Vector3f l = relativeLight(lights3d[i], pixel.x, pixel.y);
float r = l.squaredNorm();
Expand Down
3 changes: 2 additions & 1 deletion src/project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ void Project::load(QString filename) {
for(auto sphere: obj["spheres"].toArray()) {
Sphere *_sphere = new Sphere;
_sphere->fromJson(sphere.toObject());
_sphere->image_size = imgsize;
spheres.push_back(_sphere);
}
}
Expand Down Expand Up @@ -619,7 +620,7 @@ void Project::computeDirections() {
v = v.rotate(axis, angle);

if(dome.domeDiameter) {
//find intersection between direAlignctions and sphere.
//find intersection between directions and sphere.
for(size_t i = 0; i < sphere->directions.size(); i++) {
Vector3f &direction = sphere->directions[i];
direction.normalize();
Expand Down
1 change: 0 additions & 1 deletion src/sphere.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ bool Sphere::fit() {
center = QPointF(a, b);
radius = r;


}
float max_angle = (50.0/180.0)*M_PI; //slightly over 45. hoping not to spot reflexes
smallradius = radius*sin(max_angle);
Expand Down
Loading

0 comments on commit aae3437

Please sign in to comment.