Giter Club home page Giter Club logo

normalintegration's Introduction

Xu Cao, Boxin Shi, Fumio Okura and Yasuyuki Matsushita

CVPR 2021

2022.07 UPDATE: We have developed a new method substituting this method while allowing discontinuity preservation. See this repository. We believe there is no reason to use this repository any more in practice given the newly developed method.

This repository contains the official python implementation of the CVPR'21 normal integration paper, along with our python implementations based on the following papers:

  • "Variational Methods for Normal Integration", Quéau et al., Journal of Mathematical Imaging and Vision 60(4), pp 609--632, 2018.
  • "Normal Integration: a Survey", Quéau et al., Journal of Mathematical Imaging and Vision 60(4), pp 576--593, 2018. Official Matlab Code
  • "Least Squares Surface Reconstruction on Arbitrary Domains", Zhu et al., ECCV, 2020. Official Matlab Code
  • "Surface-from-Gradients: An Approach Based on Discrete Geometry Processing", Xie et al., CVPR, 2014.

Quick Start

cd to this repository's root folder and reproduce our anaconda environment by running

conda env create -f=environment.yml 
conda activate ni

Experiments on orthographic normal maps

run

python comparison_on_analytically_computed_orthographic_normal_maps.py

This script compares 5 methods on 3 orthographic normal maps: sphere, vase, and anisotropic Gaussian. The results will be saved in results/#TIME.

You can optionally add Gaussian noise and/or outliers to the input normal maps by running

python comparison_on_analytically_computed_orthographic_normal_maps.py --noise 0.1
python comparison_on_analytically_computed_orthographic_normal_maps.py --outlier 0.1
python comparison_on_analytically_computed_orthographic_normal_maps.py --outlier 0.1 --noise 0.1

The number after --noise is the standard deviation of Gaussian noise added to all normal vectors; the number after --outlier is the percentage (0~1) of outliers in the normal map.

Experiments on perspective normal maps

  • Download the perspective normal maps from here and extract them under the data folder. These normal maps are picked out from DiLiGenT dataset.

  • run

python comparison_on_perspective_diligent_normal_maps.py

This script compares 6 perspective normal integration methods on 9 DiLiGenT objects.

You might want to quickly check the results from a specific method on a specific object. To this end, comment out the object names defined in surface_name list at line 19 and methods defined in results list at line 56.

As DiLiGenT contains normal maps estimated by different photometric stereo methods, you can check the normal integration results on these normal maps by modifying the method_type list defined in line 31. For example, add "ECCV12Shi", "CVPR12Shi", etc. to the list.

Visualization

To visualize the estimated mesh surfaces, run

python plot_surface.py --path #YOUR_FOLDER_CONTAINING_PLY_FILES

A plot window of one surface will pop up, you can adjust the viewpoint that you would like to save as images. Then close the window, the images of all meshes viewed from the adjusted viewpoint will be saved in your input folder.

Use Your Data

Choose the method you would like to use from methods folder and provide a .mat or a .npy file path. For example:

python methods/perspective_five_point_plane_fitting.py --path data/sample_data/sample.npy

We recommend five point plane fitting in terms of the balance between robustness and computation time.

Data Structure

The .mat or .npy file should contain following key-value pairs:

  • "normal_map": (H, W, 3) input normal map. This normal map should be defined in such a camera coordinate system: x-axis upwards, y-axis rightwards, and z-axis (the camera's principle axis) towards the scene. Check figure 1 in our supplementary for a visualization. One correction for figure 1: u-axis and v-axis in the pixel coordinates should be swapped.
  • "mask": (H, W) boolean mask indicating the region of interest to be integrated. Foreground should be 1; background should be 0.
  • "K" (optional): the (3, 3) camera intrinsic matrix. You should prepare this matrix if you choose perspective normal integration methods. If you are not aware of the camera matrix, you can treat a perspective normal map as an orthographic one, and call orthographic normal integration methods. There will be slight global distortion in the estimated surface.

Citation

If you find our work useful in your research, please consider citing:

@inproceedings{cao2021normal,
  title={Normal Integration via Inverse Plane Fitting With Minimum Point-to-Plane Distance},
  author={Cao, Xu and Shi, Boxin and Okura, Fumio and Matsushita, Yasuyuki},
  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
  pages={2382--2391},
  year={2021}
}

normalintegration's People

Stargazers

 avatar Youwei Lyu avatar Yucheol Jung avatar tengdecheng avatar  avatar  avatar Guohui Wang avatar  avatar  avatar  avatar NEU-Junshun avatar  avatar Yuliang Xiu avatar  avatar  avatar YR TSAO avatar Xu Cao 曹旭 avatar Markus Lanxinger avatar Vlad (Kuzmin) Erium avatar Marco Romelli avatar Kai He avatar  avatar Feiran LI avatar  avatar Fan Fei avatar znkwong avatar Daoyi Gao avatar  avatar Daniel Limberger avatar  avatar  avatar Bjoern avatar Researcher.YuanYuhui avatar

Watchers

James Cloos avatar Xu Cao 曹旭 avatar

normalintegration's Issues

Strange 3D surface from body normal maps

Firstly, thanks for your code, I am applying your normal integration algorithm to my task, refine coarse geometry with fine normal maps

I run this script on body and cloth normal maps and reconstructed the surfaces as follows

python methods/orthographic_five_point_plane_fitting.py --path slack_trial2-000150.npy
normal map surface-view1 surface-view2
slack_trial2-000150_normal_F snapshot02_L01 snapshot03_L01
slack_trial2-000150_T_normal_F snapshot02_L00 snapshot03_L00

It seems that the local offsets are correct, but the global translation is totally wrong. If I already have the coarse geometry+fine normal maps of the human, what if I want to introduce the coarse geometry into the optimization process? Should I replace the $d$ with point-to-origin distance $d_o$ computed from coarse geometry?

image

human.zip

npy file dict keys:

  • clothed human: "normal_map_F", "normal_map_B", "mask"
  • coarse body: "T_normal_F", "T_normal_B", "T_mask"

UPDATE:

OMG, I tried your ECCV 2022 work, and the results look much much much better
snapshot04

I cannot wait to ask what's the main difference between the Inverse Plane Fitting and Bilateral Normal Integration?

Errors occured

First of all, I would like to express my gratitude for your contribution to such a useful project. I am currently experiencing some issues with your NormalIntegration module and would appreciate your help.
I want to get the results of obj, but encountered multiple runtime warnings and errors while running the module, mainly related to invalid value calculations and file opening issues. Below are the detailed error messages and the context in which they occurred.

E:\NormalIntegration\data\data_class.py:29: RuntimeWarning: invalid value encountered in sqrt
t = (-b - np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
E:\NormalIntegration\utils.py:173: RuntimeWarning: invalid value encountered in true_divide
zx = -nx / nz
E:\NormalIntegration\utils.py:174: RuntimeWarning: invalid value encountered in true_divide
zy = -ny / nz
E:\NormalIntegration\utils.py:241: RuntimeWarning: Mean of empty slice
left_forward[..., None]), -1), -1)
E:\NormalIntegration\utils.py:244: RuntimeWarning: Mean of empty slice
bottom_forward[..., None]), -1), -1)
E:\NormalIntegration\data\data_class.py:61: RuntimeWarning: invalid value encountered in true_divide
p = - n[..., 0] / n[..., 2]
E:\NormalIntegration\data\data_class.py:62: RuntimeWarning: invalid value encountered in true_divide
q = - n[..., 1] / n[..., 2]
E:\NormalIntegration\data\data_class.py:103: RuntimeWarning: invalid value encountered in true_divide
p_map = - self.n[..., 0] / self.n[..., 2]
E:\NormalIntegration\data\data_class.py:104: RuntimeWarning: invalid value encountered in true_divide
q_map = - self.n[..., 1] / self.n[..., 2]
E:\NormalIntegration\data\data_class.py:61: RuntimeWarning: invalid value encountered in true_divide
p = - n[..., 0] / n[..., 2]
E:\NormalIntegration\data\data_class.py:62: RuntimeWarning: invalid value encountered in true_divide
q = - n[..., 1] / n[..., 2]
E:\NormalIntegration\data\data_class.py:124: RuntimeWarning: invalid value encountered in true_divide
p_map = - self.n[..., 0] / self.n[..., 2]
E:\NormalIntegration\data\data_class.py:125: RuntimeWarning: invalid value encountered in true_divide
q_map = - self.n[..., 1] / self.n[..., 2]
E:\shapeUp2014_face_quick_version\NormalIntegration\data\data_class.py:61: RuntimeWarning: invalid value encountered in true_divide
p = - n[..., 0] / n[..., 2]
E:\shapeUp2014_face_quick_version\NormalIntegration\data\data_class.py:62: RuntimeWarning: invalid value encountered in true_divide
q = - n[..., 1] / n[..., 2]
E:\NormalIntegration\data\data_sphere.py:20: RuntimeWarning: invalid value encountered in sqrt
z = np.sqrt(1 - XX ** 2 - YY ** 2)
E:\NormalIntegration\data\data_vase.py:31: RuntimeWarning: invalid value encountered in sqrt
z = np.sqrt(py ** 2 - XX ** 2)
running orthographic_five_point_plane_fitting...
running orthographic_four_point_plane_fitting...
running orthographic_poisson...
running orthographic_discrete_functional...
running orthographic_discrete_geometry_processing...
ERROR:root:Error opening PLY file
running orthographic_five_point_plane_fitting...
running orthographic_four_point_plane_fitting...
running orthographic_poisson...
running orthographic_discrete_functional...
running orthographic_discrete_geometry_processing...
ERROR:root:Error opening PLY file
ERROR:root:Error opening PLY file
ERROR:root:Error opening PLY file
ERROR:root:Error opening PLY file
ERROR:root:Error opening PLY file
ERROR:root:Error opening PLY file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.