|
2D object detection 모델은 크게 one-step 방식 two-step 방식의 모델로 나뉜다.
2가지 모델의 차이를 설명하고 각 경우 모델의 종류를 조사하라.
3D object detection 모델은 크게 point 기반모델과 voxel기반 모델로 나뉜다.
2가지 모델의 차이를 설명하고 각 경우 모델의 종류를 조사하라.
심층신경망이란 무엇인가?
심층신경망(DNN: Deep Neural Network)
은닉층 2개 이상을 가진 인공신경망을 뜻함
비선형 문제를 해결하기 위해 설계됨
각 계층은 뉴런 또는 노드로 구성 > 가중치와 활성화 함수를 통해 서로 연결됨
입력에 가중치를 곱하고 편향을 더한 뒤 활성화 함수를 거쳐 출력되는 형식
딥러닝이란 무엇인가?
심층신경망을 학습시키는 알고리즘
사람의 뇌처럼 작동하는 인공 신경망을 기반으로 함
특징을 스스로 추출하고 복잡한 데이터를 잘 처리함
데이터가 많을수록 성능이 좋음
https://kind-slip-86b.notion.site/Chapter-16-3-1738a2c2bfdb809fb660e2a441ab5565?source=copy_link
딥러닝 라이브러리를 조사하라.
09. KITTI dataset visualization
포인트 클라우드에서 라이다 중심에서 반경 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 | import numpy as np import open3d as o3d points = np.fromfile("../data/000000.bin", dtype=np.float32).reshape(-1, 4) xyz = points[:, :3] dist = np.linalg.norm(xyz, axis=1) mask = dist < 5.0 filtered_xyz = xyz[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(filtered_xyz) pcd.colors = o3d.utility.Vector3dVector(np.ones((filtered_xyz.shape[0], 3))) # 흰색 유지 vis.add_geometry(pcd) vc = vis.get_view_control() vc.set_zoom(0.1) vc.set_front([0, -1, 1]) vc.set_lookat([0, 0, 0]) vc.set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
포인트 클라우드에서 도로에 해당하는 포인트는 삭제하고 출력하라
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 | import numpy as np import open3d as o3d points = np.fromfile("../data/000000.bin", dtype=np.float32).reshape(-1, 4) xyz = points[:, :3] pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(xyz) plane_model, inliers = pcd.segment_plane(distance_threshold=0.2, ransac_n=3, num_iterations=2000) outlier_pcd = pcd.select_by_index(inliers, invert=True) outlier_pcd.paint_uniform_color([1.0, 1.0, 1.0]) vis = o3d.visualization.Visualizer() vis.create_window(window_name='도로 제거 후 출력', width=960, height=540) opt = vis.get_render_option() opt.point_size = 1.0 opt.background_color = np.zeros(3) axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0) vis.add_geometry(axis) vis.add_geometry(outlier_pcd) vc = vis.get_view_control() vc.set_zoom(0.2) vc.set_front([0, -1, 1]) vc.set_lookat([0, 0, 0]) vc.set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
https://www.open3d.org/docs/latest/tutorial/Basic/pointcloud.html
포인트 클라우드에서 도로에 해당하는 포인트는 빨간색으로 출력하라
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 | import numpy as np import open3d as o3d points = np.fromfile("../data/000000.bin", dtype=np.float32).reshape(-1, 4) xyz = points[:, :3] pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(xyz) plane_model, inliers = pcd.segment_plane(distance_threshold=0.2, ransac_n=3, num_iterations=2000) inlier_pcd = pcd.select_by_index(inliers) outlier_pcd = pcd.select_by_index(inliers, invert=True) inlier_pcd.paint_uniform_color([1.0, 0.0, 0.0]) outlier_pcd.paint_uniform_color([1.0, 1.0, 1.0]) vis = o3d.visualization.Visualizer() vis.create_window(window_name='도로 빨간색 표시', width=960, height=540) opt = vis.get_render_option() opt.point_size = 1.0 opt.background_color = np.zeros(3) axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1.0) vis.add_geometry(axis) vis.add_geometry(inlier_pcd) vis.add_geometry(outlier_pcd) vc = vis.get_view_control() vc.set_zoom(0.2) vc.set_front([0, -1, 1]) vc.set_lookat([0, 0, 0]) vc.set_up([0, 1, 1]) vis.run() vis.destroy_window() | cs |
영상에 객체의 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 | import cv2 import numpy as np from label_parsing import parse_kitti_label_file image_file_path = "../data/000010.png" label_file_path = "../data/label_2/000010.txt" image = cv2.imread(image_file_path) colors = { "Car": (0, 255, 0), "Pedestrian": (255, 0, 0), } labels = parse_kitti_label_file(label_file_path) for label in labels: obj_type = label["type"] if obj_type == "DontCare" or obj_type == "Don'tCare": continue bbox = label["bbox"].astype(int) x1, y1, x2, y2 = bbox color = colors.get(obj_type, (255, 255, 255)) cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) cv2.putText(image, obj_type, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1, cv2.LINE_AA) cv2.imshow("Image with Bounding Boxes", image) cv2.waitKey(0) cv2.destroyAllWindows() | cs |
레이블 파일명을 받아서 파싱하고 결과 리스트를 리턴하는 함수를 작성하고 예제를 만들어서 검증해보라
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 | import numpy as np def parse_kitti_label_file(label_file_path): """ KITTI 객체 탐지 레이블 파일을 파싱하여 객체 정보 리스트로 반환 Parameters: label_file_path (str): 레이블 파일 경로 (.txt) Returns: list[dict]: 객체 정보를 담은 딕셔너리 리스트 """ labels = [] try: with open(label_file_path, "r") as f: for line in f: obj_label = line.strip().split() if len(obj_label) < 15: continue 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], dtype=float) dimensions = np.array(obj_label[8:11], dtype=float) location = np.array(obj_label[11:14], dtype=float) location[1] -= dimensions[0] / 2 rotation_y = float(obj_label[14]) label = { 'type': obj_type, 'truncated': truncated, 'occluded': occluded, 'alpha': alpha, 'bbox': bbox, 'dimensions': dimensions, 'location': location, 'rotation_y': rotation_y } labels.append(label) except Exception as e: print(f"[오류] 라벨 파일 파싱 실패: {e}") return labels | cs |
label_parsing.py로 만들어서 이전 과제에서 import해서 사용함