|
|
2. 2D object detection 모델은 크게 one-step 방식 two-step 방식의 모델로 나뉜다. 2가지 모델의 차이를 설명하고 각 경우 모델의 종류를 조사하라.
3. 3D obeject detection 모델은 크게 point 기반모델과 voxel기반 모델로 나뉜다. 2가지 모델의 차이를 설명하고 각 경우 모델의 종류를 조사하라.
1. Point 기반 모델
2. Voxel 기반 모델
4. 심층신경망이란 무엇인가?
인공지능의 가장 기본적인 형태이고 단일층으로 구성된 퍼셉트론을 여러 개층으로 확장하고 은닉층을 포함한 다층 퍼셉트론에서 다층 퍼셉트론의 은닉층을 깊게 쌓은 구조(은닉층을 여러개인 신경망, 일반적으로 수십개 이상)가 심층신경망이다.
다층퍼셉트론보다 복잡한 비선형 문제를 해결가능(딥러닝)하다.
5. 딥러닝이란 무엇인가?
인경신공망을 기반으로하는 기계학습의 한 분야 --> 데이터로부터 복잡한 패턴을 자동으로 학습하는 기술
일반적인 머신러닝은 특징을 수작업으로 추출하지만 딥러닝은 다층 구조를 통해 자동으로 특징을 추출한다.
--> 층이 깊을 수록 더 복잡하고 추상적인 정보를 학습 가능
대표 알고리즘으로 CNN, RNN, Transfomrer등을 사용한다.
6. 딥러닝 라이브러리를 조사하라.
9장
1. 포인트 클라우드에서 라이다 중심에서 반경 5m안에 있는 포인트만 출력하라
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import open3d as o3d import numpy as np file_path = '../../dataset/data_object_velodyne/training/velodyne/000000.bin' # (N, 4) 형식의 numpy array로 변환 points = np.fromfile(file_path, dtype=np.float32).reshape(-1, 4) print("원본 포인트 수:", points.shape[0]) # 라이다 중심에서 거리 계산 (x^2 + y^2 + z^2) ** 0.5 xyz = points[:, :3] distances = np.linalg.norm(xyz, axis=1) mask = distances <= 5.0 # 반경 5m 이내 필터링 filtered_points = xyz[mask] print("5m 이내 포인트 수:", filtered_points.shape[0]) # Open3D 시각화 vis = o3d.visualization.Visualizer() vis.create_window(window_name='kitti', width=960, height=540) vis.get_render_option().point_size = 1.0 vis.get_render_option().background_color = np.zeros(3) # 좌표축 생성 axis_pcd = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0, origin=[0, 0, 0]) vis.add_geometry(axis_pcd) # 필터링된 포인트로 PointCloud 생성 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(filtered_points) pcd.paint_uniform_color([1, 1, 1]) # 흰색 vis.add_geometry(pcd) # 시점 설정 vis.get_view_control().set_zoom(0.1) vis.get_view_control().set_front([0, -1, 1]) vis.get_view_control().set_lookat([0, 0, 0]) vis.get_view_control().set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
2. 포인트 클라우드에서 도로에 해당하는 포인트는 삭제하고 출력하라
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import open3d as o3d import numpy as np file_path = '../../dataset/data_object_velodyne/training/velodyne/000000.bin' # (N, 4) 형식의 numpy array로 변환 points = np.fromfile(file_path, dtype=np.float32).reshape(-1, 4) print("전체 포인트 수:", points.shape[0]) # z값 기준으로 도로 포인트 제거 (예: z < -1.4 제거) z_threshold = -1.4 mask = points[:, 2] > z_threshold # z값이 너무 낮은 건 도로일 확률 높음 filtered_points = points[mask] print("도로 제외 후 포인트 수:", filtered_points.shape[0]) # 시각화 vis = o3d.visualization.Visualizer() vis.create_window(window_name='kitti', width=960, height=540) vis.get_render_option().point_size = 1.0 vis.get_render_option().background_color = np.zeros(3) # 좌표축 추가 axis_pcd = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0, origin=[0, 0, 0]) vis.add_geometry(axis_pcd) # 포인트 클라우드 설정 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(filtered_points[:, :3]) pcd.paint_uniform_color([1, 1, 1]) # 흰색 vis.add_geometry(pcd) # 시점 설정 vis.get_view_control().set_zoom(0.1) vis.get_view_control().set_front([0, -1, 1]) vis.get_view_control().set_lookat([0, 0, 0]) vis.get_view_control().set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
3. 포인트 클라우드에서 도로에 해당하는 포인트는 빨간색으로 출력하라
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import open3d as o3d import numpy as np file_path = '../../dataset/data_object_velodyne/training/velodyne/000000.bin' # (N, 4) 형식의 numpy array로 변환 points = np.fromfile(file_path, dtype=np.float32).reshape(-1, 4) print("전체 포인트 수:", points.shape[0]) # 도로 판단 기준 (z < -1.4면 도로로 간주) z_threshold = -1.4 road_mask = points[:, 2] < z_threshold # 도로 포인트: True non_road_mask = ~road_mask # 색상 초기화: 흰색 colors = np.ones((points.shape[0], 3)) # (1,1,1) # 도로 포인트만 빨간색으로 지정 colors[road_mask] = [1, 0, 0] # 빨간색 (R,G,B) print("도로 포인트 수:", np.sum(road_mask)) # 시각화 vis = o3d.visualization.Visualizer() vis.create_window(window_name='kitti', width=960, height=540) vis.get_render_option().point_size = 1.0 vis.get_render_option().background_color = np.zeros(3) # 좌표축 추가 axis_pcd = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0, origin=[0, 0, 0]) vis.add_geometry(axis_pcd) # 포인트 클라우드 설정 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points[:, :3]) pcd.colors = o3d.utility.Vector3dVector(colors) vis.add_geometry(pcd) # 시점 설정 vis.get_view_control().set_zoom(0.1) vis.get_view_control().set_front([0, -1, 1]) vis.get_view_control().set_lookat([0, 0, 0]) vis.get_view_control().set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
4. 영상에 객체의 2차원 바운딩 박스를 그릴때 객체별로 다른색으로 그리고 타입이 Don’t care는 그리지 말 것, 바운딩박스 좌측상단에 객체명을 출력하라, cv2.puttext 함수 사용할 것
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import numpy as np import cv2 import label as lb label_file_path = "../../dataset/data_object_label_2/training/label_2/000010.txt" image_file_path = "../../dataset/data_object_image_2/training/image_2/000010.png" # 이미지 로드 image = cv2.imread(image_file_path) if image is None: raise FileNotFoundError("이미지를 불러올 수 없습니다.") # RGB 색상 목록 (최대 10개 정도) distinct_colors = [ (255, 0, 0), # 빨강 (0, 255, 0), # 초록 (0, 0, 255), # 파랑 (255, 255, 0), # 노랑 (255, 0, 255), # 마젠타 (0, 255, 255), # 시안 (255, 128, 0), # 주황 (128, 0, 255), # 보라 (0, 128, 255), # 하늘 (128, 255, 0), # 연두 ] # 객체 타입 → 고유 색상 매핑 color_map = {} color_idx = 0 # 레이블별 처리 for data in lb.labels: if data['type'].lower() == "dontcare": continue obj_type = data['type'] bbox = list(map(int, data['bbox'])) # (x1, y1, x2, y2) if obj_type not in color_map: color_map[obj_type] = distinct_colors[color_idx % len(distinct_colors)] color_idx += 1 color = color_map[obj_type] # 바운딩 박스 cv2.rectangle(image, (bbox[0], bbox[1]), (bbox[2], bbox[3]), color, 2) # 객체 이름 출력 cv2.putText(image, obj_type, (bbox[0], bbox[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1, cv2.LINE_AA) # 출력 cv2.imshow('2D Bounding Boxes (Distinct Colors)', image) cv2.waitKey(0) cv2.destroyAllWindows() | cs |
5. 레이블 파일명을 받아서 파싱하고 결과 리스트를 리턴하는 함수를 작성하고 예제를 만들어서 검증해보라
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import numpy as np def parse_label_file(label_file_path): labels = [] with open(label_file_path) as f: for line in f.readlines(): obj_label = line.strip().split() obj_type = obj_label[0] truncated = float(obj_label[1]) occluded = int(obj_label[2]) alpha = float(obj_label[3]) bbox = np.array(obj_label[4:8]).astype(float) # [x1, y1, x2, y2] dimensions = np.array(obj_label[8:11]).astype(float) # [h, w, l] location = np.array(obj_label[11:14]).astype(float) # [x, y, z] location[1] -= dimensions[0] / 2 # 중심 y좌표 보정 (KITTI 기준) rotation = float(obj_label[14]) label = { 'type': obj_type, 'truncated': truncated, 'occluded': occluded, 'alpha': alpha, 'bbox': bbox, 'dimensions': dimensions, 'location': location, 'rotation_y': rotation } labels.append(label) return labels # 실행 if __name__ == "__main__": label_file_path = "../../dataset/data_object_label_2/training/label_2/000010.txt" parsed_labels = parse_label_file(label_file_path) print(f"총 객체 수: {len(parsed_labels)}") for i, data in enumerate(parsed_labels): print(f"[{i}] {data['type']}") print(f" - Truncated: {data['truncated']}") print(f" - Occluded: {data['occluded']}") print(f" - Alpha: {data['alpha']}") print(f" - BBox: {data['bbox']}") print(f" - Dimensions (h, w, l): {data['dimensions']}") print(f" - Location (x, y, z): {data['location']}") print(f" - Rotation_y: {data['rotation_y']}") | cs |