# In MATLAB, the normal vector of surface point cloud is visualized, and the normal vector direction of each point is inconsistent. How to modify the code to make the normal vector of each point face the unity?

2022-01-27 02:30:08

The problem is as follows ：

I hope the effect picture is as follows ：

Or something like that , Just move towards unity ：

Point cloud coordinates p.txt Exist in Baidu cloud ： link ： https://pan.baidu.com/s/13DFDJi7184CjJvigpj1BNQ
Extraction code ：nhu4
The code is as follows ：

``load p.txt%MYNORMALVECTOR  use PCA The algorithm obtains the normal vector of each point of the point cloud matrix .%Input: % p yes Nx3 Matrix , Contains the 3D coordinate information of the point cloud [X,Y,Z].%Output:% n yes Nx3 Matrix , Corresponding p The unit normal vector of each point in .N = size(p,1);n = zeros(N,3); %  A matrix that stores normals %  Look for each point K Nearest neighbor index k = 5; % k a near neighbor [NeiborIndex,~] = knnsearch(p,p,'Distance','euclidean','NSMethod','kdtree','K',k);for i=1:N    %  Index of the current point neighborhood point set     IndexOfCurrentNeibors = NeiborIndex(i,:);    %  Current point neighborhood point set     CurrentNeighbors = p(IndexOfCurrentNeibors,:);    PtCent = mean(CurrentNeighbors); % Get the average value of local point cloud , It is convenient to calculate the length and direction of the normal vector      % PCA Calculate the normal vector with the method     B = CurrentNeighbors - repmat(PtCent,k,1); %  Decentralized point set matrix     PtCov = transpose(B)*B; % Covariance matrix     %  Find the eigenvalue 、 Eigenvector .     % D Is the corresponding eigenvalue diagonal matrix ,V It's the eigenvector     % ( Because the covariance matrix is a real symmetric matrix , Therefore, the eigenvector is a unit orthogonal vector )    [V,D] = eig(PtCov);     % d0 Is the minimum eigenvalue  idx Index the number of columns of the eigenvalue .    [~, idx] = min(diag(D)); % diag(): Create a diagonal matrix or get the diagonal elements of the matrix     n(i,:) = V(:,idx)';   %  The eigenvector corresponding to the minimum eigenvalue is the normal vector , The unit normal vector      %  Towards unity     n1 = n(i,:);    n2 = p(i,:);    if dot(n1,n2)<0 %  If the quantity product of this vector and the normal vector is negative （ reverse ）        n(i,:) = -n(i,:);  %  The normal vector takes the inverse     endend% Normal vector visualization ptCloud = pointCloud(p);figure()pcshow(ptCloud);hold on quiver3(p(:,1),p(:,2),p(:,3),n(:,1),n(:,2),n(:,3));hold off  Please comment ``

You put n1 Change your direction to y In the right direction [0,1,0], then n2 Switch to n(i,:), That's all right. , final view(2) It's to show xOy Face set , It can be seen that the direction of the arrow is indeed the same

``load p.txt%MYNORMALVECTOR  use PCA The algorithm obtains the normal vector of each point of the point cloud matrix .%Input: % p yes Nx3 Matrix , Contains the 3D coordinate information of the point cloud [X,Y,Z].%Output:% n yes Nx3 Matrix , Corresponding p The unit normal vector of each point in .N = size(p,1);n = zeros(N,3); %  A matrix that stores normals %  Look for each point K Nearest neighbor index k = 5; % k a near neighbor [NeiborIndex,~] = knnsearch(p,p,'Distance','euclidean','NSMethod','kdtree','K',k);for i=1:N    %  Index of the current point neighborhood point set     IndexOfCurrentNeibors = NeiborIndex(i,:);    %  Current point neighborhood point set     CurrentNeighbors = p(IndexOfCurrentNeibors,:);    PtCent = mean(CurrentNeighbors); % Get the average value of local point cloud , It is convenient to calculate the length and direction of the normal vector      % PCA Calculate the normal vector with the method     B = CurrentNeighbors - repmat(PtCent,k,1); %  Decentralized point set matrix     PtCov = transpose(B)*B; % Covariance matrix     %  Find the eigenvalue 、 Eigenvector .     % D Is the corresponding eigenvalue diagonal matrix ,V It's the eigenvector     % ( Because the covariance matrix is a real symmetric matrix , Therefore, the eigenvector is a unit orthogonal vector )    [V,D] = eig(PtCov);     % d0 Is the minimum eigenvalue  idx Index the number of columns of the eigenvalue .    [~, idx] = min(diag(D)); % diag(): Create a diagonal matrix or get the diagonal elements of the matrix     n(i,:) = V(:,idx)';   %  The eigenvector corresponding to the minimum eigenvalue is the normal vector , The unit normal vector      %  Towards unity     n1 = [0,1,0]; %% n1 It's using y Affirmative direction     n2 = n(i,:); %% n2 It's using n Of i A direction     if dot(n1,n2)<0 %  If the quantity product of this vector and the normal vector is negative （ reverse ）        n(i,:) = -n(i,:);  %  The normal vector takes the inverse     endend% Normal vector visualization ptCloud = pointCloud(p);figure()pcshow(ptCloud);hold on quiver3(p(:,1),p(:,2),p(:,3),n(:,1),n(:,2),n(:,3));hold off xlabel('x'); ylabel('y');zlabel('z')view(2)``