Skip to content

Commit

Permalink
some cleanup of the saliency computation functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Randall Smith committed May 4, 2017
1 parent 0ba9cd9 commit 464a5d2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 48 deletions.
33 changes: 15 additions & 18 deletions geometry_processing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -298,25 +298,24 @@ void ComputeLogLaplacianSpectrum(
const Eigen::MatrixXd &vertices, const Eigen::MatrixXi &indices,
Eigen::SelfAdjointEigenSolver<Eigen::SparseMatrix<double>> &solver,
Eigen::VectorXd &log_laplacian_spectrum) {
// variant we need.
Eigen::SparseMatrix<double> weighted_adjacency(vertices.rows(),
vertices.rows());
ComputeWeightedAdjacency(vertices, indices, weighted_adjacency);

Eigen::SparseMatrix<double> normalized_laplacian(vertices.rows(),
vertices.rows());
Eigen::SparseMatrix<double> weighted_degree(vertices.rows(), vertices.rows());
ComputeWeightedDegree(weighted_adjacency, weighted_degree);
ComputeNormalizedLaplacian(weighted_adjacency, weighted_degree,
normalized_laplacian);
normalized_laplacian = weighted_degree - weighted_adjacency;

solver.compute(normalized_laplacian);
Eigen::SparseMatrix<double> laplacian = weighted_degree - weighted_adjacency;
Eigen::SparseMatrix<double> inverse_sqrt =
weighted_degree.unaryExpr([](const double &x) -> double {
return (x == 0.0 ? 0.0 : 1.0 / sqrt(x));
});
Eigen::SparseMatrix<double> symmetric_laplacian =
inverse_sqrt * laplacian * inverse_sqrt;
solver.compute(symmetric_laplacian);
Eigen::VectorXd eigenvalues = solver.eigenvalues();
//LOG(DEBUG) << "Smallest eigenvalue = " << eigenvalues(0) << "\n";

log_laplacian_spectrum = eigenvalues.unaryExpr(
[](double x) -> double { return std::log(std::abs(x)); });
LOG(DEBUG) << "min_eigenvalues = " << eigenvalues.minCoeff() << "\n";
LOG(DEBUG) << "max_eigenvalues = " << eigenvalues.maxCoeff() << "\n";
}

void ComputeMeshIrregularity(
Expand All @@ -341,8 +340,8 @@ void ComputeMeshIrregularity(
average /= static_cast<double>(filter_size);
// Compute the spectral irregularity, R(f).
irregularity = (log_laplacian_spectrum - average).cwiseAbs();
//for (int i = 0; i < vertices.rows(); ++i) {
//LOG(DEBUG) << "irregularity(" << i << ")=" << irregularity(i) << "\n";
// for (int i = 0; i < vertices.rows(); ++i) {
// LOG(DEBUG) << "irregularity(" << i << ")=" << irregularity(i) << "\n";
//}
}

Expand All @@ -367,11 +366,7 @@ void ComputeMeshSaliencyMatrix(const Eigen::MatrixXd &vertices,
weighted_degree.unaryExpr(
[](const double &x) -> double { return (x == 0.0 ? 0.0 : 1.0 / x); });
Eigen::SparseMatrix<double> normalized_adjacency =
weighted_adjacency;
//for (int i = 0; i < normalized_adjacency.rows(); ++i) {
//float sum = normalized_adjacency.row(i).sum();
//assert(std::abs(sum - 1.0) < 1e-5);
//}
inverse_weighted_degree * weighted_adjacency;
// Compute the saliency S = B*R*B^T * W.
Eigen::MatrixXd lhs = solver.eigenvectors() * r_diagonal.asDiagonal() *
solver.eigenvectors().transpose();
Expand All @@ -384,6 +379,8 @@ void ComputeMeshSaliency(const Eigen::MatrixXd &vertices,
Eigen::MatrixXd saliency_matrix(vertices.rows(), vertices.rows());
ComputeMeshSaliencyMatrix(vertices, indices, saliency_matrix);
saliency = saliency_matrix.colwise().sum();
LOG(DEBUG) << "min_saliency = " << saliency.minCoeff() << "\n";
LOG(DEBUG) << "max_saliency = " << saliency.maxCoeff() << "\n";
}

void ComputeMultiScaleSaliency(const geometry::Mesh &mesh, int max_faces,
Expand Down
3 changes: 2 additions & 1 deletion include/view_setting.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ struct ViewSetting {
orthographic(v.orthographic),
near(v.near),
far(v.far),
view_angle(v.view_angle) {}
view_angle(v.view_angle),
camera_center(v.camera_center) {}
ViewSetting(int screen_width, int screen_height,
const Eigen::Vector3d &eye_position,
const Eigen::Vector3d &up_vector, bool is_orthographic,
Expand Down
69 changes: 40 additions & 29 deletions spectral_saliency.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <pcl/filters/convolution_3d.h>
#include <pcl/point_types.h>

#define USE_JET

using geometry::BoundingBox;
using geometry::Mesh;
using std::placeholders::_1;
Expand All @@ -37,10 +39,6 @@ int window_height = 256;
std::string output_directory;
bool run_view_sampling = false;

void RgbToLuma(const Eigen::Vector3d &rgb, double &luma) {
luma = 0.299 * rgb(0) + 0.587 * rgb(1) + 0.1146 * rgb(2);
}

void SaveViewerSettings(const igl::viewer::Viewer &viewer,
const std::string &file_name) {
std::ofstream out(file_name);
Expand All @@ -64,20 +62,18 @@ void SaveViewerSettings(const igl::viewer::Viewer &viewer,
// This is the Viewer initialization callback.
bool ViewerInit(igl::viewer::Viewer &viewer,
const ViewSettings *view_settings) {
LOG(DEBUG) << "ViewerInit\n";
// LOG(DEBUG) << "ViewerInit\n";
if (view_settings->which >= view_settings->view_setting_list.size())
return false;
const ViewSetting *view_setting =
&view_settings->view_setting_list[view_settings->which];
if (!run_view_sampling) {
window_width = view_setting->width;
window_height = view_setting->height;
}
// LOG(DEBUG) << "view_setting->which = " << view_settings->which << "\n"
//<< " view_setting->width = " << view_setting->width << "\n"
//<< " view_setting->height = " << view_setting->height << "\n"
//<< " window_height = " << window_height << "\n"
//<< " window_width = " << window_width << "\n";
window_width = view_setting->width;
window_height = view_setting->height;
LOG(DEBUG) << "view_setting->which = " << view_settings->which << "\n"
<< " view_setting->width = " << view_setting->width << "\n"
<< " view_setting->height = " << view_setting->height << "\n"
<< " window_height = " << window_height << "\n"
<< " window_width = " << window_width << "\n";
// exit(0);
// Set the window size and viewport before drawing begins.
glfwSetWindowSize(viewer.window, window_width, window_height);
Expand All @@ -88,27 +84,41 @@ bool ViewerInit(igl::viewer::Viewer &viewer,
// This is a pre render callback for the Viewr class.
bool ViewerPreDraw(igl::viewer::Viewer &viewer, const Mesh *mesh,
const ViewSettings *view_settings) {
LOG(DEBUG) << "ViewerPreDraw\n";
// LOG(DEBUG) << "ViewerPreDraw\n";
if (view_settings->which >= view_settings->view_setting_list.size())
return false;
const ViewSetting *view_setting =
&view_settings->view_setting_list[view_settings->which];
viewer.core.camera_eye = view_setting->eye.cast<float>();
//viewer.core.light_position = viewer.core.camera_eye;
viewer.core.lighting_factor = 0.0;
if (run_view_sampling) viewer.core.lighting_factor = 0.0;
viewer.core.camera_up = view_setting->up.cast<float>();
viewer.core.orthographic = view_setting->orthographic;
viewer.core.camera_dnear = view_setting->near;
viewer.core.camera_dfar = view_setting->far;
viewer.core.camera_view_angle = view_setting->view_angle;
viewer.core.camera_center = view_setting->camera_center.cast<float>();
static bool once = false;
if (!once) {
LOG(DEBUG) << "viewer.core.camera_up =" << view_setting->up.cast<float>()
<< "\n";
LOG(DEBUG) << "viewer.core.orthographic =" << view_setting->orthographic
<< "\n";
LOG(DEBUG) << "viewer.core.camera_dnear =" << view_setting->near << "\n";
LOG(DEBUG) << "viewer.core.camera_dfar =" << view_setting->far << "\n";
LOG(DEBUG) << "viewer.core.camera_view_angle =" << view_setting->view_angle
<< "\n";
LOG(DEBUG) << "viewer.core.camera_center ="
<< view_setting->camera_center.cast<float>() << "\n";
once = true;
}

return false;
}

// This callback will run until all view_settinged views have been rendered.
bool ViewerPostDraw(igl::viewer::Viewer &viewer, const Mesh *mesh,
ViewSettings *view_settings) {
LOG(DEBUG) << "ViewerPostDraw\n";
// LOG(DEBUG) << "ViewerPostDraw\n";
if (view_settings->is_sampled) {
// If no more views to render, make sure the Viewer class exits.
if (view_settings->which >= view_settings->view_setting_list.size()) {
Expand Down Expand Up @@ -142,17 +152,16 @@ bool ViewerPostDraw(igl::viewer::Viewer &viewer, const Mesh *mesh,
LOG(DEBUG) << "Saving PNG file to :'" << png_file_path << "\n";
// Save it to a PNG.
igl::png::writePNG(R, G, B, A, png_file_path);
//std::string cfg_file_path =
//output_directory + "/cfg/out" + which_str + ".cfg";
//LOG(DEBUG) << "Saving CFG file to :'" << cfg_file_path << "\n";
// std::string cfg_file_path =
// output_directory + "/cfg/out" + which_str + ".cfg";
// LOG(DEBUG) << "Saving CFG file to :'" << cfg_file_path << "\n";
//// Save the camera settings.
//SaveViewerSettings(viewer, cfg_file_path);
// SaveViewerSettings(viewer, cfg_file_path);
++view_settings->which;

// Post an empty event so igl::viewer::Viewer will continue to pump events
// and render the next view.
glfwPostEmptyEvent();
}
// Post an empty event so igl::viewer::Viewer will continue to pump events
// and render the next view.
glfwPostEmptyEvent();
return false;
}

Expand Down Expand Up @@ -246,12 +255,14 @@ int main(int argc, char *argv[]) {
mesh.colors.resize(mesh.vertices.rows(), 3);
double min_saliency = saliency.minCoeff();
double max_saliency = saliency.maxCoeff();
// igl::jet(saliency, saliency.minCoeff(), saliency.maxCoeff(), mesh.colors);
#ifdef USE_JET
igl::jet(saliency, saliency.minCoeff(), saliency.maxCoeff(), mesh.colors);
#elif
for (int i = 0; i < mesh.colors.rows(); ++i) {
double value =
(saliency(i) - min_saliency) / (max_saliency - min_saliency);
double value = (saliency(i) - min_saliency) / (max_saliency - min_saliency);
mesh.colors.row(i) = Eigen::Vector3d(value, value, value);
}
#endif
LOG(DEBUG) << "#mesh.colors() = " << mesh.colors.rows() << "\n";

LOG(DEBUG) << "Normalize mesh.\n";
Expand Down

0 comments on commit 464a5d2

Please sign in to comment.