{
  "fetched_at": "2026-10-19T08:27:55Z",
  "source_url": "https://www.kaggle.com/competitions/2024-ml-project-3d/data",
  "pages": [
    {
      "name": "data-description",
      "content": "본 프로젝트에서 사용하는 데이터는 다음과 같습니다.\n\n1) 3D 데이터 (.off) 파일\n- 학습 데이터 수: 1000 (클래스 당 100)\n- 테스트 데이터 수: 300 (클래스 당 30)\n\n2) 클래스 라벨 파일\n- 총 10 종류의 클래스 (bathtub, bed, chair, ..., toilet)에 대응하는 정수형 라벨 (0, 1, 2, ..., 9)의 정보를 담은 JSON 파일\n\n3) 제출용 csv 파일\n- 테스트 데이터에 대한 모델의 예측을 **정수형**으로 Label column에 추가하여 제출하면 됩니다.\n\n## 데이터 요약\n\n```\n├── ㅡmodelnet10\n│   ├── dataset\n│   │   ├── train\n│   │   │   ├── bathtub\n│   │   │   │   ├── bathtub_0001.off\n│   │   │   │   ├── bathtub_0002.off\n│   │   │   │   ├── ...\n│   │   │   │   ├── bathtub_0099.off\n│   │   │   │   └── bathtub_0100.off\n│   │   │   ├── bed\n│   │   │   ├── ···\n│   │   │   ├── table\n│   │   │   └── toilet\n│   │   ├── test\n│   │   │   ├── 0.off\n│   │   │   ├── 1.off\n│   │   │   ├── 10.off\n│   │   │   ├── ...\n│   │   │   ├── 2.off\n│   │   │   ├── 20.off\n│   │   │   └── 99.off\n├── class2Label.json\n├── sample_submit.csv\n``` \n\n참고) 학습 데이터에 대한 3D 모델의 클래스 10 종류는 아래와 같습니다.\n- bathtub\n- bed\n- chair\n- desk\n- dresser\n- monitor\n- night_stand\n- sofa\n- table\n- toilet",
      "isPublished": false,
      "hasIsPublished": false,
      "postTitle": "",
      "hasPostTitle": false,
      "mimeType": "",
      "hasMimeType": false
    },
    {
      "name": "Description",
      "content": "#### 과목 정보\n- 세종대학교 AI로봇학과 기계학습 (최유경 교수)\n\n***\n\n## 프로젝트 방향성 이해\n\n### 프로젝트의 목적\n- **본 프로젝트를 통해 3D 데이터를 Hand-crafted Feature로 기술하는 법을 알 수 있다.**\n- 본 프로젝트를 통해 생소한 데이터 (OFF 확장자 형식의 파일)를 다루는 방법에 대해 익힐 수 있다.\n- 본 프로젝트를 통해 데이터를 다루는 다양한 Feature Representation 방법에 대해 알 수 있다.\n- 최종적으로 기술한 Feature를 토대로 머신러닝 방법을 활용하여 3D 데이터를 분류할 수 있다.\n\n### 프로젝트 주의사항\n- 성능 향상을 위해 인공신경망 방법은 사용할 수 없다. (ANN, CNN 등)\n- 성능 향상을 위해 추가적인 Feature Extraction 방법을 사용하는 것에는 제약이 없다. 단, 주석을 통해 해당 방법을 명확히 적시해야 한다.\n- 성능 향상을 위한 AutoML을 포함하여 수업에 배우지 않은 타 분류기 사용은 금한다. 또한 Skeleton Code에 적시한 분류기 이외의 분류기 사용을 금한다. (이는 Feature Extraction 방법의 다양성으로 성능 향상을 권장하기 위함이다)\n\n### 프로젝트 시작하기\n1) 프로젝트 메뉴얼 (Description)을 자세하게 읽는다.\n\n2) [스켈레톤 코드](https://www.kaggle.com/code/heojaeyeon/skeleton-code-3d)를 Copy & Edit 한다.\n\n3) 스켈레톤 코드 내 **Empty Module**을  구현한다. (*기존 스켈레톤 코드의 함수명을 수정하지 않는다.)\n\n4) 결과 CSV 파일을 리더보드에 제출한다.\n- 4-1) 본 프로젝트는 3D 데이터를 표현하는 세 방법 (Point Cloud, Voxel, Mesh)에 대한 Baseline이 각각 설정되어 있음.\n- 4-2) **세 방법에 대한 노트북 이름을 각각 설정하여 (예: [2024-ML][TP_3D][Point Cloud] 학번_이름) 제출한다.**\n\n5) Baseline을 달성하지 못했다면, 프로젝트 메뉴얼과 스켈레톤 코드 내 마크다운을다시 읽으며 디버깅한다.\n- 5-1) Baseline 달성 후 추가적인 Feature Extraction 방법 및 다양한 분류기를 통한 성능 향상을 시도한다.\n\n***\n## [프로젝트 1] 3D 데이터 다루기 - 3차원 물체 분류\n![](https://www.researchgate.net/publication/330933095/figure/fig4/AS:960275410857998@1605958907799/The-some-samples-retrieval-result-on-ModelNet-10.png)\n\n- 본 프로젝트에서는 3D 데이터에 대한 Hand-crafted Feature를 기술하여 총 10 종류의 물체 (bathtub, bed, chair, desk, dresser, monitor, night_stand, sofa, table, toilet)를 분류하는 것을 목표로 합니다.\n\n- 위 그림은 본 프로젝트에서 사용하는 ModelNet10 데이터 셋의 예시로, 10 종류의 물체에 대해 다양한 형태를 갖는 3D CAD 모델의 예시입니다.\n\n***\n\n## 1. 3D 데이터 사전 지식\n#### [1-1] 3D 데이터 활용 분야 및 활용성\n- 3D 데이터는 다양한 분야에서 활용됩니다. 아래는 3D 데이터를 사용하는 분야 및 그 예시입니다.\n    - 컴퓨터 그래픽스: 3D 모델링, 가상현실, 애니메이션 등에서 주로 사용되며, 시각화 및 시뮬레이션을 수행합니다.\n    - 로봇 공학: 로봇 제어, 물체 인식, 환경 모델링 등에서 사용되며 로봇의 작업 공간을 모델링하여 로봇을 제어합니다.\n    - 건축 및 시설 관리: 건축 디자인, 구조 분석, 시설 관리 등에서 건축의 모델링 및 시뮬레이션을 수행합니다.\n- 이외에도 다양한 분야에서 3D 데이터가 사용되며, 이번 프로젝트의 주요 목적 중 하나는 일상에서 접근해보지 않았던 생소한 데이터인 3D 데이터 셋을 다루고, 읽고, 해당 데이터 셋을 학습하여 예측하는 것입니다. 그럼 우선적으로 3D 데이터의 표현 방법에 대해 알아보겠습니다.\n\n#### [1-2] 3D 데이터 표현 방법\n![](https://i.imgur.com/Ifl1EwK.png)\n- 3D 데이터는 대표적으로 Point Cloud, Voxel, Mesh 의 세 방법을 통해 표현할 수 있습니다. \n    - **Point Cloud**란 Lidar, RGB-D 등의 센서를 통해 수집한 데이터 (Point)의 집합으로, 물체에 빛/신호를 보내 돌아오는 시간을 토대로 물체와의 거리 정보를 계산하여 Point (점)을 생성하고, 해당 Point를 모은 집합을 의미합니다.\n    - **Voxel**이란 Volume과 Pixel의 합성어로, 3차원 공간에서 하나의 Point를 나타내는 3D 그래픽 개념입니다. Voxel은 Point Cloud 데이터를 Voxelization을 통해 모델의 3차원 공간을 일정한 크기의 정육면체로 분할하여 표현합니다.\n    - **Mesh**는 3D 그래픽에서 일반적으로 사용되는 개념으로, Point를 모아 만든 다각형 (대표적으로 삼각형)을 이루는 점 (Vertex), 선 (Edge), 면 (Face, Polygon)의 Point들로 구성됩니다.\n- 보다 자세한 내용은 SkeletonCode의 Feature Extraction 탭을 확인하시길 바랍니다.\n- 그럼 이제 3D 데이터 셋의 파일 확장자들에 대해 알아보겠습니다.\n\n#### [1-3] 3D 데이터를 담은 파일 확장자\n- 3D 데이터를 담은 파일 확장자는 몇 종류가 있습니다. 예를 들어 컴퓨터를 사용하다 메모를 남기고 싶다면, 메모장을 켜서 내용을 적은 후 바탕화면에 저장할 수 있습니다. 저장된 파일은 .txt 파일 확장자를 가지고 있습니다.일반적으로는 파일 확장자를 통해 해당 .txt 파일에 텍스트가 포함되어 있음을 알 수 있습니다. 이제 3D 데이터를 담은 다양한 파일 확장자를 알아보겠습니다.\n- **STL** 파일: 3D 모델의 표면 정보를 담은 파일 형식으로, 주로 산업용 3D 프린팅에서 사용됩니다.\n- **OBJ** 파일: 3D 모델의 정점, 면, 텍스쳐 정보를 담은 파일 형식으로, 주로 게임 개발 및 3D 모델링에서 사용됩니다.\n- **PLY** 파일: 3D 모델의 정점, 면, 색상 정보를 담은 파일 형식으로, 주로 3D 스캐닝 및 3D 모델링에서 사용됩니다.\n- **FBX** 파일: 3D 모델의 정점, 면, 에니메이션 및 입체 정보를 담은 파일 형식으로, 주로 게임 개발 및 애니메이션 제작에서 사용됩니다.\n- **OFF** 파일: 3D 모델의 정점, 면 정보를 포함하는 파일 형식으로, 주로 3D 모델링 및 CAD 시스템에서 사용됩니다.\n- 본 프로젝트에서 사용되는 파일 확장자는 OFF 파일 확장자로, 아래의 예시를 통해 자세히 살펴보겠습니다.\n\n<img src=\"https://i.imgur.com/0lA8iaM.png\" width=\"300\" height=\"200\">\n\n- 위는 OFF 확장자 파일의 예시 (본 프로젝트에서 사용되는 ModelNet10의 실제 학습 데이터 셋 예시입니다)로, 첫 번째 줄의 OFF는 해당 파일이 OFF 확장자임을 나타내는 구분자 역할을 합니다.\n- 아래 두 번째 줄은 3D 모델의 정점 (Vertex), 면 (Face), 선 (Edge)의 총 개수를 나타냅니다. OFF 파일에서는 Edge에 해당하는 정보를 포함하지 않으므로, Edge의 수는 항상 0으로 고정됩니다.\n-  다음의 세 번째 줄 부터 Vertex의 수만큼의 줄 (3 - 3516)은 Vertex의 정보를 담고 있습니다. Vertex의 정보는 한 Point의 x, y, z 좌표를 의미하며, 예로 3 번째 줄의 18.514300 -29.876500 -23.038200은 순서대로 각각 x, y, z 좌표를 의미합니다.\n- 마지막으로는 다각형의 정보와 다각형을 구성하는 좌표의 인덱스에 대한 정보를 담고 있습니다. 예를 들어 3517 번째 줄의 3 13 14 15는 순서대로 해당 Face가 삼각형 (3)임을 의미하며, 13 번째 인덱스의 Vertex, 14 번째 인덱스의 Vertex, 15 번째 인덱스의 Vertex로 구성되어 있음을 의미합니다.  3 번째 줄이 0 번째 인덱스의 Vertex 정보이며, 15 - 17 번째 줄의 Vertex 정보가 삼각형의 Face를 구성한다고 이해하면 됩니다.\n- 위의 예시를 토대로 **Empty Module #1**을 작성합니다. 해당 모듈은 OFF 확장자 형식의 데이터 파일을 읽어 Vertex 정보를 담은 배열과 Face 정보를 담은 배열을 반환하는 함수입니다. 구현을 위한 상세 내용은 Skeleton Code의 Read File 탭을 확인하시길 바랍니다.\n\n*** \n\n## 2. 본 프로젝트에서 사용하는 Hand-crafted Feature Extraction 방법\n- **원활한 구현을 위해 본 메뉴얼 뿐만 아니라 Skeleton Code의 Feature Extraction 탭을 확인하시길 바랍니다.**\n- 본 프로젝트에서는 Empty Module #1에서 읽은 데이터 파일을 토대로 다양한 Hand-crafted Feature Extraction 과정을 수행합니다. Feature Extraction은 위 [1-2]에서 설명한 Point Cloud, Voxel, Mesh의 세 표현 방법에 대해 각각 다른 방법으로 수행합니다.\n\n#### [2-1] Point Cloud - [Empty Module #2-#3]\n![](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9Nghi%2FbtqPYjhHHNI%2F4xDT51NNLhQzNHwMKu6GXK%2Fimg.png)\n- Point Cloud를 활용한 방법으로, 전체 파이프라인은 Skeleteon code의 Feature Extraction (Point Cloud) 탭에 상세히 설명되어 있습니다. 아래는 해당 파이프라인에 대한 추가적인 고찰입니다.\n- 우선적으로 Skeleton code에서 설명하는 전체적인 파이프라인을 한 줄로 설명하면 다음과 같습니다. \"Point Cloud로부터 Normal Vector (법선 벡터)를 추정한 다음, Normal Vector의 x, y, z 각 축의 데이터를 히스토그램으로 표현하여 Feature를 추출합니다.\"\n- 이 때의 의문점으로는 하나의 Point가 Normal Vector를 가질 수 있는지입니다. 다시 Normal Vector의 추정 파이프라인을 살펴보면 첫 번째 줄에서 Point Cloud의 한 점 P의 최근접 이웃점 (Nearest Neighbor)을 획득하는 과정이 존재합니다. 즉, Point의 한 좌표만으로는 법선 벡터를 가지는 것이 불가능해보이지만 해당 Point의 근처 이웃하는 점을 모은다면 해당 Point들을 포함하는 하나의 평면을 생성할 수 있으며, 해당 평면의 법선 벡터를 구할 수 있습니다.\n- 이 과정에서 KDTreeSearchParamHybrid 알고리즘이 사용되며, 쉽게는 하나의 Point에서 사전에 정한 반지름 (radius) 내의 최대 (max_nn)개수의 점을 찾아 평면을 구성합니다.\n- 이 때 해당 평면은 평면의 특성 상 2차원 상으로 표현된다고 생각할 수 있지만, 평면을 구성하는 점은 3차원 상의 점이므로 해당 평면의 법선벡터는 x, y, z 각 축의 정보를 담고 있습니다. 이제 법선 벡터의 각 축 별에 해당하는 히스토그램을 생성하여, 모든 축에 대해 합친 결과인 (n_bins, 3) 형태의 배열을 Feature로 사용합니다. 참고 사항으로 해당 과정에서 추정한 법선 벡터를 단위 벡터로 변환하기 위해 정규화하는 과정이 내포되어 있습니다.\n\n#### [2-2] Voxel - [Empty Module #6-#7]\n![](https://davidstutz.de/wordpress/wp-content/uploads/2018/04/voxelization-screenshot.jpg)\n- Voxel을 활용한 방법으로, 전체 파이프라인은 Skeleton Code의 Feature Extraction (Voxel) 탭에 상세히 설명되어 있습니다.\n- Voxelization은 3D 모델을 일정한 크기의 3D 정육면체 그리드 (Grid)로 분할하는 과정을 의미하며, 이 때 생성되는 그리드를 Voxel이라고 명합니다.\n- 본 프로젝트에서 사용되는 Voxel을 활용한 Feature Extraction은 Voxel Grid 내 Point가 차지하는 비율을 구합니다. 다음으로는 Point의 x, y, z 각 축에 대해 차지하는 비율을 구합니다. 해당 과정은 3D 모델의 전반적인 형태를 표현할 수 있으며 Voxel을 활용한 Feature Extraction 중 Naive 한 방법에 속합니다.\n- 본 프로젝트에서는 Voxel Grid로 변환하는 Voxelization 과정을 Open3d 라이브러리를 활용하지만, Empty Module #6의 설명의 create_voxel_grid 함수를 통해 Voxelization 과정을 살펴보는 것을 추천합니다.\n\n#### [2-3] Mesh - [Empty Module #10-#11]\n![](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cc/Surface_normals.svg/512px-Surface_normals.svg.png)\n- Mesh를 활용한 방법으로, 전체 파이프라인은 Skeleton Code의 Feature Extraction (Mesh) 탭에 상세히 설명되어 있습니다.\n- Point Cloud와 Mesh 모두 Normal Vector를 활용하는 방법입니다. [2-1]의 Point Cloud를 활용한 방법에서 우리는 'Point가 어떻게 Normal Vector를 가질 수 있을까?'에 대한 의문으로 시작한 고찰을 진행하였습니다. 따라서 실제로 Point Cloud에서의 Normal Vector는 **계산이 아닌 추정**이라는 단어를 사용하였습니다.\n- 하지만 Mesh 데이터는 다각형의 정보를 직관적으로 포함하고 있습니다.  [1-3]의 OFF 확장자 파일 예시를 살펴보면, 3 13 14 15와 같이 13, 14, 15 번째 인덱스의 Vertex 정보가 삼각형을 이루고 있음을 알 수 있습니다. 세 좌표를 알고 있으므로, 하나의 삼각형을 구성할 수 있으며 해당 삼각형의 Normal Vector를 계산할 수 있습니다. 참고로 삼각형 PQR의 Normal Vector를 계산하는 방법은 PQ 벡터와 PR 벡터를 외적해서 얻을 수 있습니다.\n- 위의 고찰을 통해 우리는 Point Cloud와 Mesh로부터 Normal Vector를 추정, 계산하여 Feature를 구성하는 방법이 비슷해보이더라도 3D 데이터의 표현 방법에 따라 그 의의가 다름을 이해하는 것이 중요합니다.\n- 추가적으로 Mesh를 사용하는 방법에 대한 하나의 고찰인, Mesh 데이터로부터 계산한 Normal Vector의 차원 축소로 인한 정보의 손실에 관해 생각해보겠습니다.\n- PCA는 다변량 데이터에서 주요한 정보를 추출하는 방법 중 하나로, 주요 정보를 나타내는 주성분을 찾아내고, 이를 이용해 데이터를 저차원으로 축소하는 대표적인 차원 축소 방법입니다. 하지만 PCA로 얻는 차원 축소는 장단점을 가지고 있습니다. 대표적인 장점으로는 차원 축소를 통해 모델 학습 시간을 단축할 수 있으며, 이상치 (Outlier)의 영향력을 줄일 수 있는 장점이 있습니다. 하지만 역으로는 차원 축소에 따라 정보를 손실할 수도 있다는 단점이 있습니다.\n- 본 프로젝트에서 사용한 방법은 Mesh로부터 계산한 Normal Vector를 PCA를 통해 3차원 공간 상의 법선 벡터를 표현하는 새로운 벡터를 생성하는 방법입니다. 이는 모델 입력 시 학습 데이터의 차원이 동일해야하지만, 데이터 파일마다 Face의 수가 달라 생성되는 Normal Vector의 수가 다르기 때문입니다. 실제로 Feature Extraction을 위해 참고한 논문에서는 Normal Vector 뿐만 아니라 Mesh의 Curvature (곡률)을 계산한 다음 둘을 결합한 Feature에 PCA를 적용하여 현재보다 고차원의 차원으로 정보 손실율이 적을 수 있지만, Curvature를 계산하는 과정에 대한 구현이 복잡하여 본 프로젝트에서는 제외하였습니다. 따라서 차원 축소로 인한 정보 손실을 고찰한다면, 계산된 Normal Vector를 동일 차원으로 맞추기 위한 방법 혹은 Normal Vector 계산 이전 Face의 수를 Sampling 하여 Normal Vector의 차원을 맞추는 방법을 고안할 수도 있습니다.\n\n***\n#### 코멘트\n- 프로젝트와 관련된 문의는 슬랙의 질의응답을 이용해주시길 바랍니다.",
      "isPublished": false,
      "hasIsPublished": false,
      "postTitle": "",
      "hasPostTitle": false,
      "mimeType": "",
      "hasMimeType": false
    },
    {
      "name": "Evaluation",
      "content": "평가 지표는 10 종류의 클래스 (bathtub, bed, chair 등)에 대한 **분류 정확도****(Categorization Accuracy)**입니다.",
      "isPublished": false,
      "hasIsPublished": false,
      "postTitle": "",
      "hasPostTitle": false,
      "mimeType": "",
      "hasMimeType": false
    },
    {
      "name": "rules",
      "content": " - Don't cheat!\n - Apply yourself!\n - Have fun!",
      "isPublished": false,
      "hasIsPublished": false,
      "postTitle": "",
      "hasPostTitle": false,
      "mimeType": "",
      "hasMimeType": false
    },
    {
      "name": "abstract",
      "content": " ",
      "isPublished": false,
      "hasIsPublished": false,
      "postTitle": "",
      "hasPostTitle": false,
      "mimeType": "",
      "hasMimeType": false
    }
  ]
}