Learning Normals of Noisy Points by Local Gradient-Aware Surface Filtering (ICCV 2025)
October 15, 2025 · View on GitHub
Project | arXiv
Estimating normals for noisy point clouds is a persistent challenge in 3D geometry processing, particularly for end-to-end oriented normal estimation. Existing methods generally address relatively clean data and rely on supervised priors to fit local surfaces within specific neighborhoods. In this paper, we propose a novel approach for learning normals from noisy point clouds through local gradient-aware surface filtering. Our method projects noisy points onto the underlying surface by utilizing normals and distances derived from an implicit function constrained by local gradients. We start by introducing a distance measurement operator for global surface fitting on noisy data, which integrates projected distances along normals. Following this, we develop an implicit field-based filtering approach for surface point construction, adding projection constraints on these points during filtering. To address issues of over-smoothing and gradient degradation, we further incorporate local gradient consistency constraints, as well as local gradient orientation and aggregation. Comprehensive experiments on normal estimation, surface reconstruction, and point cloud denoising demonstrate the state-of-the-art performance of our method.
Requirements
The code is implemented in the following environment settings:
- Ubuntu 20.04
- CUDA 11.7
- Python 3.8
- Pytorch 1.9
- Pytorch3d 0.6
- Numpy 1.19
- Scipy 1.6
Other optional pakeges for mesh extraction and filtering includes: pytorch3d, trimesh, mcubes, point_cloud_utils.
We train and test our code on an NVIDIA 3090 Ti GPU.
Dataset
The datasets used in our paper can be downloaded from Here.
Unzip them to a folder ***/Dataset/ and set the path value of dataset_root in train_test.py.
The dataset is organized as follows:
│Dataset/
├──PCPNet/
│ ├── list
│ ├── ***.txt
│ ├── ***.xyz
│ ├── ***.normals
│ ├── ***.pidx
├──FamousShape/
│ ├── list
│ ├── ***.txt
│ ├── ***.xyz
│ ├── ***.normals
│ ├── ***.pidx
Train
python train_test.py --mode=train --gpu=0 --data_set=***
You need to set data_set according to the used dataset. The trained models will be save in ./log/***/.
Test
To test on the given dataset using the trained models, simply run:
python train_test.py --mode=test --gpu=0 --data_set=*** --ckpt_dir=*** --ckpt_iter=20000
ckpt_dir indicates the name of the log folder.
Some other useful options:
avg_nor: use normal average strategysave_normal_npy: save the predicted normalssave_filter_pcd: save the filtered point cloudssave_mesh: save the reconstructed surfaces
The normal estimation results can be evaluated using eval_normal.py.
The predicted normals and evaluation results will be saved in ./log/***/test_20000/.
Citation
If you find our work useful in your research, please cite our paper:
@inproceedings{li2025LGSF,
title={Learning Normals of Noisy Points by Local Gradient-Aware Surface Filtering},
author={Li, Qing and Feng, Huifang and Gong, Xun and Liu, Yu-Shen},
booktitle={International Conference on Computer Vision (ICCV)},
year={2025}
}