1. PCD(Point Cloud Data)
1.1 PCD file format
PCD 파일은 Point Cloud Library 포맷 구조를 가지고 있다.
하지만 PCD는 3D point cloud data를 나타내기 위해 처음 나온 파일 형식이 아니다. 이전에도 PLY, STL, OBJ, X3D 등 많은 종류가 있었다. 하지만 앞에서 언급된 파일 형식들은 최근에 개발된 센싱 기술들과 알고리즘 이전에 개발되었기 때문에 최근 방향과는 다른 목적을 위해 만들어졌다. 따라서 최근 기술 방향에 따르면 PCD 파일 형식이 사용되는 편이다.
1.2 PCD versions
PCD 파일 형식은 PCD_V6, PCD_V7와 같이 PCD_Vx로 다른 버전을 나타낸다.
현재 공식적으로 버전은 0.7 즉 PCD_V7이어야 한다.
1.3 File format header
PCD 파일의 구조는 헤더(header)와 데이터(data)로 나뉜다. 먼저 헤더부터 살펴보자.
헤더는 파일에 저장된 point cloud data의 특성이 작성되어 있으며, ASCII로 인코딩되어야만 한다.
0.7버전에 따르면 다음 항목들이 있다.
- VERSION: PCD 파일의 버전 기술
- FIELDS: 각 point가 가질 차원(dimension)과 필드(field)를 지정한다. 예는 아래와 같다.
FIELDS x y z # XYZ data
FIELDS x y z rgb # XYZ + colors
FIELDS x y z normal_x normal_y normal_z # XYZ + surface normals
FIELDS j1 j2 j3 # moment invariants
...
- SIZE: 차원의 크기 정한다. 크기는 바이트 단위로 지정할 수 있다.
- unsigned char - 1byte
- unsigned short - 2bytes
- unsigned int/float - 4bytes
- double - 8bytes
- TYPE: 차원의 유형을 정한다. 유형은 문자로 지정할 수 있으며 종류는 아래와 같다.
- I - signed types int8(char), int16(short), int32(int)
- U - unsigned types uint8(unsigned char), uint16(unsigned short), uint32(unsigned int)
- F - float types
- COUNT: 차원에 몇 개의 요소가 있는지 지정한다. 예를 들어서, 보통 x data에는 1개 요소를 포함한다. 하지만 VFH와 같은 feature descriptor는 308개의 요소를 포함한다. COUNT값을 작성하지 않으면 default값 1로 설정된다.
- WIDTH: point의 개수로 point cloud dataset의 폭을 지정한다. 다음과 같은 두 가지 의미가 있다고 한다.
- 무작위 dataset에 대해 cloud의 총 point 개수를 지정한다.
- 구성된 point cloud dataset의 너비(총 point들의 수)의 너비를 지정한다.
- ex. WIDTH 640 : 라인 당 640개의 point가 있음을 나타낸다.
- HEIGHT: point의 개수로 point cloud dataset의 높이를 지정한다. height 역시 두 가지 의미가 있다고 한다.
- 무작위 dataset의 경우, 1로 설정된다. ➡ dataset이 구성되어있는지 여부를 확인하기 위해 사용된다.
- 구성된 point cloud dataset의 높이(총 point들의 수)를 지정한다.
WIDTH 640 # Image-like organized structure, with 480 rows and 640 columns,
HEIGHT 480 # thus 640*480=307200 points total in the dataset
480개의 행과 640개의 열로 구성된 구조를 가진다. 즉, 640*480 = 총 307200개의 points를 가지는 dataset을 나타낸다.
WIDTH 307200
HEIGHT 1 # unorganized point cloud dataset with 307200 points
HEIGHT 값이 1이므로, 구성되지 않은 구조를 dataset이다. 따라서 총 307200개의 points를 가지는 무작위 dataset을 나타낸다.
- VIEWPOINT: dataset에 있는 point를 가지는 시점을 작성한다. 시점 정보는 translation(tx, ty, tz)와 쿼터니언(qw, qx, qy, qz)로 지정한다. 아래는 default 값이다.
VIEWPOINT 0 0 0 1 0 0 0 # tx ty tz qw qx qy qz
- POINTS: cloud 내에 가지는 총 points의 수를 지정한다. WIDTH, HEIGHT와 의미가 중복되기 때문에 이후 버전에서는 아마 해당 항목이 사라질 것이라고 한다.
POINTS 307200 # the total number of points in the cloud
헤더 다음 바이트부터는 point cloud data가 바로 시작된다. 따라서 다음 순서에 따라 정확하게 작성해야만 한다.
VERSION |
FIELDS |
SIZE |
TYPE |
COUNT |
WIDTH |
HEIGHT |
VIEWPOINT |
POINTS |
DATA |
1.4 File Format DATA
이제 헤더 이후로 오는 point cloud data를 살펴보자. 버전 0.7에 따르면, .PCD 파일은 데이터를 저장하기 위해서 다음 세 가지 형식을 사용한다.
1. ASCII form: 새로운 줄에 각 점을 작성하는 형식
p_1
p_2
p_3
p_4
...
p_n
* 참고: PCL 버전 1.0.1부터 NaN의 문자열 표현은 "nan"로 작성한다.
2. binary form: 여기서 data는 PointCloud.points의 배열/벡터의 전체 메모리 복사본(?)이다. 잘 모르겠음..
3. binary_compressed form: 헤더 이후로 작성되는 본문(data)을 compressed form 형식으로 된 데이터의 크기를 32bytes의 unsigned binary number로 지정한다. 그 후에 uncompressed form 형식의 데이터가 온다.
여기서 압축하고 압축을 푸는 알고리즘 방식은 Lehmann's LZF algorithm 방식이 사용된다고 한다. 이 알고리즘 방식은 데이터 크기를 줄이는 측면에서는 평범하지만, 속도 측면에서는 엄청 빠르다.
일반적인 point cloud의 경우에, 원래 크기의 30~60% 정도로 압축된다. 그리고 압축할 때 데이터가 재정렬된다. 예로 들어서 3개의 점과 필드 x, y, z가 xyzxyzxyz로 되어 있는 구름이 있다면, 압축 후에는 xxxyyyzzz로 재정렬된다.
➡ 주로 ASCII 형식이 사용되는 것 같다.
1.5 예시
앞의 설명에 따라 PCD는 다음과 같이 작성될 수 있다.
각 points들은 x, y, z rgb를 나타내고 있고, 각 정보는 4byte, 형식은 float임을 나타낸다.
또 HEIGHT가 1이고, WIDTH가 213이므로 무작위의 213개 points들을 가지는 cloud이다.
데이터는 ASCII form이므로, 각 라인마다 한 point를 나타낸다.
# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 213
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 213
DATA ascii
0.93773 0.33763 0 4.2108e+06
0.90805 0.35641 0 4.2108e+06
0.81915 0.32 0 4.2108e+06
0.97192 0.278 0 4.2108e+06
0.944 0.29474 0 4.2108e+06
0.98111 0.24247 0 4.2108e+06
0.93655 0.26143 0 4.2108e+06
0.91631 0.27442 0 4.2108e+06
0.81921 0.29315 0 4.2108e+06
0.90701 0.24109 0 4.2108e+06
0.83239 0.23398 0 4.2108e+06
0.99185 0.2116 0 4.2108e+06
0.89264 0.21174 0 4.2108e+06
0.85082 0.21212 0 4.2108e+06
0.81044 0.32222 0 4.2108e+06
0.74459 0.32192 0 4.2108e+06
0.69927 0.32278 0 4.2108e+06
0.8102 0.29315 0 4.2108e+06
0.75504 0.29765 0 4.2108e+06
0.8102 0.24399 0 4.2108e+06
0.74995 0.24723 0 4.2108e+06
0.68049 0.29768 0 4.2108e+06
0.66509 0.29002 0 4.2108e+06
0.69441 0.2526 0 4.2108e+06
0.62807 0.22187 0 4.2108e+06
0.58706 0.32199 0 4.2108e+06
0.52125 0.31955 0 4.2108e+06
0.49351 0.32282 0 4.2108e+06
0.44313 0.32169 0 4.2108e+06
0.58678 0.2929 0 4.2108e+06
0.53436 0.29164 0 4.2108e+06
0.59308 0.24134 0 4.2108e+06
0.5357 0.2444 0 4.2108e+06
0.50043 0.31235 0 4.2108e+06
0.44107 0.29711 0 4.2108e+06
0.50727 0.22193 0 4.2108e+06
0.43957 0.23976 0 4.2108e+06
0.8105 0.21112 0 4.2108e+06
0.73555 0.2114 0 4.2108e+06
0.69907 0.21082 0 4.2108e+06
0.63327 0.21154 0 4.2108e+06
0.59165 0.21201 0 4.2108e+06
0.52477 0.21491 0 4.2108e+06
0.49375 0.21006 0 4.2108e+06
0.4384 0.19632 0 4.2108e+06
0.43425 0.16052 0 4.2108e+06
0.3787 0.32173 0 4.2108e+06
0.33444 0.3216 0 4.2108e+06
0.23815 0.32199 0 4.808e+06
0.3788 0.29315 0 4.2108e+06
0.33058 0.31073 0 4.2108e+06
0.3788 0.24399 0 4.2108e+06
0.30249 0.29189 0 4.2108e+06
0.23492 0.29446 0 4.808e+06
0.29465 0.24399 0 4.2108e+06
0.23514 0.24172 0 4.808e+06
0.18836 0.32277 0 4.808e+06
0.15992 0.32176 0 4.808e+06
0.08642 0.32181 0 4.808e+06
0.039994 0.32283 0 4.808e+06
0.20039 0.31211 0 4.808e+06
0.1417 0.29506 0 4.808e+06
0.20921 0.22332 0 4.808e+06
0.13884 0.24227 0 4.808e+06
0.085123 0.29441 0 4.808e+06
0.048446 0.31279 0 4.808e+06
0.086957 0.24399 0 4.808e+06
0.3788 0.21189 0 4.2108e+06
0.29465 0.19323 0 4.2108e+06
0.23755 0.19348 0 4.808e+06
0.29463 0.16054 0 4.2108e+06
0.23776 0.16054 0 4.808e+06
0.19016 0.21038 0 4.808e+06
0.15704 0.21245 0 4.808e+06
0.08678 0.21169 0 4.808e+06
0.012746 0.32168 0 4.808e+06
-0.075715 0.32095 0 4.808e+06
-0.10622 0.32304 0 4.808e+06
-0.16391 0.32118 0 4.808e+06
0.00088411 0.29487 0 4.808e+06
-0.057568 0.29457 0 4.808e+06
-0.0034333 0.24399 0 4.808e+06
-0.055185 0.24185 0 4.808e+06
-0.10983 0.31352 0 4.808e+06
-0.15082 0.29453 0 4.808e+06
-0.11534 0.22049 0 4.808e+06
-0.15155 0.24381 0 4.808e+06
-0.1912 0.32173 0 4.808e+06
-0.281 0.3185 0 4.808e+06
-0.30791 0.32307 0 4.808e+06
-0.33854 0.32148 0 4.808e+06
-0.21248 0.29805 0 4.808e+06
-0.26372 0.29905 0 4.808e+06
-0.22562 0.24399 0 4.808e+06
-0.25035 0.2371 0 4.808e+06
-0.29941 0.31191 0 4.808e+06
-0.35845 0.2954 0 4.808e+06
-0.29231 0.22236 0 4.808e+06
-0.36101 0.24172 0 4.808e+06
-0.0034393 0.21129 0 4.808e+06
-0.07306 0.21304 0 4.808e+06
-0.10579 0.2099 0 4.808e+06
-0.13642 0.21411 0 4.808e+06
-0.22562 0.19323 0 4.808e+06
-0.24439 0.19799 0 4.808e+06
-0.22591 0.16041 0 4.808e+06
-0.23466 0.16082 0 4.808e+06
-0.3077 0.20998 0 4.808e+06
-0.3413 0.21239 0 4.808e+06
-0.40551 0.32178 0 4.2108e+06
-0.50568 0.3218 0 4.2108e+06
-0.41732 0.30844 0 4.2108e+06
-0.44237 0.28859 0 4.2108e+06
-0.41591 0.22004 0 4.2108e+06
-0.44803 0.24236 0 4.2108e+06
-0.50623 0.29315 0 4.2108e+06
-0.50916 0.24296 0 4.2108e+06
-0.57019 0.22334 0 4.2108e+06
-0.59611 0.32199 0 4.2108e+06
-0.65104 0.32199 0 4.2108e+06
-0.72566 0.32129 0 4.2108e+06
-0.75538 0.32301 0 4.2108e+06
-0.59653 0.29315 0 4.2108e+06
-0.65063 0.29315 0 4.2108e+06
-0.59478 0.24245 0 4.2108e+06
-0.65063 0.24399 0 4.2108e+06
-0.70618 0.29525 0 4.2108e+06
-0.76203 0.31284 0 4.2108e+06
-0.70302 0.24183 0 4.2108e+06
-0.77062 0.22133 0 4.2108e+06
-0.41545 0.21099 0 4.2108e+06
-0.45004 0.19812 0 4.2108e+06
-0.4475 0.1673 0 4.2108e+06
-0.52031 0.21236 0 4.2108e+06
-0.55182 0.21045 0 4.2108e+06
-0.5965 0.21131 0 4.2108e+06
-0.65064 0.2113 0 4.2108e+06
-0.72216 0.21286 0 4.2108e+06
-0.7556 0.20987 0 4.2108e+06
-0.78343 0.31973 0 4.2108e+06
-0.87572 0.32111 0 4.2108e+06
-0.90519 0.32263 0 4.2108e+06
-0.95526 0.34127 0 4.2108e+06
-0.79774 0.29271 0 4.2108e+06
-0.85618 0.29497 0 4.2108e+06
-0.79975 0.24326 0 4.2108e+06
-0.8521 0.24246 0 4.2108e+06
-0.91157 0.31224 0 4.2108e+06
-0.95031 0.29572 0 4.2108e+06
-0.92223 0.2213 0 4.2108e+06
-0.94979 0.24354 0 4.2108e+06
-0.78641 0.21505 0 4.2108e+06
-0.87094 0.21237 0 4.2108e+06
-0.90637 0.20934 0 4.2108e+06
-0.93777 0.21481 0 4.2108e+06
0.22244 -0.0296 0 4.808e+06
0.2704 -0.078167 0 4.808e+06
0.24416 -0.056883 0 4.808e+06
0.27311 -0.10653 0 4.808e+06
0.26172 -0.10653 0 4.808e+06
0.2704 -0.1349 0 4.808e+06
0.24428 -0.15599 0 4.808e+06
0.19017 -0.025297 0 4.808e+06
0.14248 -0.02428 0 4.808e+06
0.19815 -0.037432 0 4.808e+06
0.14248 -0.03515 0 4.808e+06
0.093313 -0.02428 0 4.808e+06
0.044144 -0.02428 0 4.808e+06
0.093313 -0.03515 0 4.808e+06
0.044144 -0.03515 0 4.808e+06
0.21156 -0.17357 0 4.808e+06
0.029114 -0.12594 0 4.2108e+06
0.036583 -0.15619 0 4.2108e+06
0.22446 -0.20514 0 4.808e+06
0.2208 -0.2369 0 4.808e+06
0.2129 -0.208 0 4.808e+06
0.19316 -0.25672 0 4.808e+06
0.14497 -0.27484 0 4.808e+06
0.030167 -0.18748 0 4.2108e+06
0.1021 -0.27453 0 4.808e+06
0.1689 -0.2831 0 4.808e+06
0.13875 -0.28647 0 4.808e+06
0.086993 -0.29568 0 4.808e+06
0.044924 -0.3154 0 4.808e+06
-0.0066125 -0.02428 0 4.808e+06
-0.057362 -0.02428 0 4.808e+06
-0.0066125 -0.03515 0 4.808e+06
-0.057362 -0.03515 0 4.808e+06
-0.10653 -0.02428 0 4.808e+06
-0.15266 -0.025282 0 4.808e+06
-0.10653 -0.03515 0 4.808e+06
-0.16036 -0.037257 0 4.808e+06
0.0083286 -0.1259 0 4.2108e+06
0.0007442 -0.15603 0 4.2108e+06
-0.1741 -0.17381 0 4.808e+06
-0.18502 -0.02954 0 4.808e+06
-0.20707 -0.056403 0 4.808e+06
-0.23348 -0.07764 0 4.808e+06
-0.2244 -0.10653 0 4.808e+06
-0.23604 -0.10652 0 4.808e+06
-0.20734 -0.15641 0 4.808e+06
-0.23348 -0.13542 0 4.808e+06
0.0061083 -0.18729 0 4.2108e+06
-0.066235 -0.27472 0 4.808e+06
-0.17577 -0.20789 0 4.808e+06
-0.10861 -0.27494 0 4.808e+06
-0.15584 -0.25716 0 4.808e+06
-0.0075775 -0.31546 0 4.808e+06
-0.050817 -0.29595 0 4.808e+06
-0.10306 -0.28653 0 4.808e+06
-0.1319 -0.2831 0 4.808e+06
-0.18716 -0.20571 0 4.808e+06
-0.18369 -0.23729 0 4.808e+06
2. PCDLoader
1. PCDLoader란?
PCDLoader는 .pcd 파일을 로딩하는 Loader이다.
Loader는 ASCII form과 compressed binary form을 지원한다.
2. PCDLoader 사용법
index.js에 해당 코드를 추가한다.
import { PCDLoader } from './examples/jsm/loaders/PCDLoader.js';
그럼 이제 사용할 수 있게 된다.
const loader = new PCDLoader();
PCDLoader의 예시는 다음과 같다.
// instantiate a loader
const loader = new PCDLoader();
// load a resource
loader.load(
// resource URL
'sample.pcd',
// 로드가 완료되면 호출되는 함수
(mesh) => {
scene.add( mesh );
},
// 로드되는 동안 호출되는 함수
(xhr) => {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// 로드를 실패했을 때 호출되는 함수
(err) => {
console.log( 'An error happened' );
}
);
참고 자료
'Front-End: Web > JavaScript' 카테고리의 다른 글
모듈(Module) (0) | 2021.05.26 |
---|---|
객체(Object) (0) | 2021.05.26 |
Three.js 1: 시작하기 (0) | 2021.05.16 |
JavaScript란? (0) | 2021.04.25 |
JSON와 JSON 메서드 (0) | 2021.04.16 |