본문 바로가기

LiDAR

Unity에서 LiDAR 정보에 PCA를 적용해보자

728x90

우선 Unity에서 OpenCV를 사용할 수 있도록 package를 Install 해야합니다.

 

PCA를 사용하는 OpenCV코드는 아래와 같습니다!!

 //PCA 수행 PCA(pac진행할 행렬, 저장할 행렬, 각 데이터 표현 방법)
        PCA pca = new PCA(Center_mat, new Mat(), PCA.Flags.DataAsRow);

 

위 코드의 Center_mat의 경우 아래의 코드를 따르게 됩니다. 

// pca를 하기 위한 데이터 중심이동
        Mat Center_mat = new Mat(pointList.Count, 3, MatType.CV_32F);
        for (int j = 0; j < Center_mat.Rows; j++)
        {
            // Center_mat.Set<float>(row, column, value);
            Center_mat.Set<float>(j, 0, pointList[j].x - mean.x);
            Center_mat.Set<float>(j, 1, pointList[j].y - mean.y);
            Center_mat.Set<float>(j, 2, pointList[j].z - mean.z);
        }

 

다음과 같이 point 정보에 평균을 빼는 구조를 가지는 이유는 PCA가 공분산 행렬에 대해 고유값을 추출하기 때문입니다.

위 수식은 data에 대한 공분산 행렬을 구할때 사용한 수식입니다.

Center_mat에 작성한 코드와 같이 각 data의 값에 평균을 빼는 형태를 볼 수 있으며 

unity에 적용한 OpenCV또한 다음 데이터의 mean값을 요구하고 있습니다.

OpenCV에서는 data와 mean을 따로 요구하지만 저는 코드에서 볼 수 있듯 미리 평균을 빼준값을 data에 넣고 mean 부분은 빈 matrix를 적용했습니다.

위 코드를 사용하여 LiDAR pointcloud에 적용하여 시각화 한 결과 

 

하얀 선으로 eigen vector가 시각화 되었습니다

Eigen Vector에 대한 내용은 색칠된 화살표로 설명되고 있습니다. 여기서 PC1은 eigen value가 가장 큰 eigen vector방향을 뜻합니다. 따라서 사진에서 파란색 점들이 뭉쳐있는 LiDAR pointcloud의 경우 PC1 방향의 벡터가 내적했을 때 loss가 가장 적은 방향을 의미합니다!!