# Point cloud 3D target detection learning: pointnet + + source code

## pointnet + + source code learning

Pointnet + + contains the pointnet source code, so just look at pointnet + +

### Overall process

Look at the source code in the form of debug, analyze the change process of power data in the network, and how to extract features
Take batch size = 2 as an example

Input data: 2, 1024, 3
->channel_first 2, 3, 1024

### First SA

First, it was changed back to 21024, 3
Then there are three different radii of MSG
Using query_ball_point() to group

Farthest point sampling
512 points [2512,3] are selected, and then the given r is grouped with the 512 points as the center of the circle,
Group
The operations of the three radii were done separately and finally merged together
Take the first as an example

The data obtained through the grouping of the first radius is [2512,16,3]
Then it was changed to [2,3,16512]
After mlp feature extraction, the result is
[2,64,16,512]
Explain: 2-batchsize 64 channel 16 is the number of points in a group
Find the maximum value again (that is, find the maximum value for each group, which is the same as maxpool in pointnet)
The final result is [2,64512]
This is the result of mlp for the first group

The results of the other two radii are  and  Then concat the three results
The final is 

Second SA
The into SA consists of two parts,
One is the point after farthest point sampling [2,3512], and the result after MLP is 
The results after MLP are put into the network as part of the features,
The result after extraction is
[2,3128] results of farthest point sampling
 after MLP

Third SA

[2,3,1]
[21024, 1] after MLP

Final classification
Classify according to the characteristics of [21024,1], and MLP is completed, which is relatively simple.

### Source code

FPS farthest point sampling, each line is annotated, and other codes are relatively simple

Firstly, centroids and distance are defined as subsequent storage center points and distances
Randomly select a point as the beginning of the farthest point,
Then find the distance from all points to this point
A new distance matrix dist is obtained
Compare this distance with distance. If the distance is small, replace the distance result,
Then select the maximum value according to the distance matrix, that is, the value with the maximum distance. Get the corresponding index
When calculating the third point, calculate the distance dist from all points to the second point
Compare with distance. Notice what distance means here. It means the distance from all points to the first point
Compare the two, that is, the distance from all points to the first point and the distance from the second point. Select the smaller distance and update it to distance. Then the distance becomes the shortest distance from all the points to the first point and the second point. Here is the key. I can understand it only by drawing a little
The next point is determined to be the largest one among the nearest ones, and continue the iteration.

```def farthest_point_sample(xyz, npoint):
"""
Input:
xyz: pointcloud data, [B, N, 3]
npoint: number of samples
Return:
centroids: sampled pointcloud index, [B, npoint]
"""
device = xyz.device #
B, N, C = xyz.shape#
#First define the matrix of the center point and the distance matrix. The center point is our farthest point. The number of sampling points is 512 for the first time
centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)#2*512
distance = torch.ones(B, N).to(device) * 1e10 #1024 the distance matrix defined first has a large number
#Farthest point, the first farthest point is randomly selected
#Random indexes, such as , have two values because batch size is 2
farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)#In batch, each sample randomly initializes an index of the farthest point
# Index in each batch
batch_indices = torch.arange(B, dtype=torch.long).to(device)
for i in range(npoint): #The first npoint is 512 and the cycle is 512ci
centroids[:, i] = farthest #The first sampling point selects the randomly initialized index
centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)#Get the coordinates of the current sampling point B*3
dist = torch.sum((xyz - centroid) ** 2, -1)#Calculate the distance between the current sampling point and other points
mask = dist < distance#Select the nearest one to update the distance (update and maintain this table), and a mask consisting of bool