# Normal Estimation Using Integral Images

In this tutorial we will learn how to compute normals for an organized point cloud using integral images.

# The code

First, download the dataset table_scene_mug_stereo_textured.pcd and save it somewhere to disk.

Then, create a file, let’s say, `normal_estimation_using_integral_images.cpp` in your favorite editor, and place the following inside it:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34``` ```#include #include #include #include #include int main () { // load point cloud pcl::PointCloud::Ptr cloud (new pcl::PointCloud); pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud); // estimate normals pcl::PointCloud::Ptr normals (new pcl::PointCloud); pcl::IntegralImageNormalEstimation ne; ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT); ne.setMaxDepthChangeFactor(0.02f); ne.setNormalSmoothingSize(10.0f); ne.setInputCloud(cloud); ne.compute(*normals); // visualize normals pcl::visualization::PCLVisualizer viewer("PCL Viewer"); viewer.setBackgroundColor (0.0, 0.0, 0.5); viewer.addPointCloudNormals(cloud, normals); while (!viewer.wasStopped ()) { viewer.spinOnce (); } return 0; } ```

# The explanation

Now, let’s break down the code piece by piece. In the first part we load a point cloud from a file:

```    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);
```

In the second part we create an object for the normal estimation and compute the normals:

```    // estimate normals
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);

pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
ne.setMaxDepthChangeFactor(0.02f);
ne.setNormalSmoothingSize(10.0f);
ne.setInputCloud(cloud);
ne.compute(*normals);
```

The following normal estimation methods are available:

```enum NormalEstimationMethod
{
COVARIANCE_MATRIX,
AVERAGE_3D_GRADIENT,
AVERAGE_DEPTH_CHANGE
};
```

The COVARIANCE_MATRIX mode creates 9 integral images to compute the normal for a specific point from the covariance matrix of its local neighborhood. The AVERAGE_3D_GRADIENT mode creates 6 integral images to compute smoothed versions of horizontal and vertical 3D gradients and computes the normals using the cross-product between these two gradients. The AVERAGE_DEPTH_CHANGE mode creates only a single integral image and computes the normals from the average depth changes.

In the last part we visualize the point cloud and the corresponding normals:

```    // visualize normals
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
viewer.setBackgroundColor (0.0, 0.0, 0.5);
viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, normals);

while (!viewer.wasStopped ())
{
viewer.spinOnce ();
}
```