2022.07.01 - [Knowhow] - Open3d RGB/Depth image rendering 에서 기록한 코드와 크게 다른 것은 없으나 intrinsic, camera pose를 미리 알고 있을 때가 아니라, 그저 Open3d visualizer 상에서 손(drag)으로 돌려가며 구도를 잡은 뒤 해당 구도로 이미지를 rendering하고 싶을 때가 많길래 추가 정리한다.
다시 말하면, 구체적인 카메라 파라미터는 필요없고 대충 open3d GUI에서 손으로 구도 잡은 뒤, 그 구도의 RGB/Depth를 얻을 때 자주 썼다.
먼저 이 코드는 준비물이 필요한데, 일단 o3d.visualization.draw_geometries()를 이용해 먼저 visualizer를 켠다.
그리고 원하는 구도로 마우스 드래그를 통해 이동/회전시킨 뒤, P 버튼을 누른다.
그러면 o3d.visualization.draw_geometries()를 실행한 코드가 있는 위치에 ScreenCamera_xx.json 파일이 생성되는 것을 볼 수 있다.
이 ScreenCamera_xx.json 파일이 현 visualizer가 사용하는 카메라 파라미터를 담고 있는 파일이다. 아래 코드는 이 파일을 읽어 일일이 손으로 드래그하지 않아도 그 구도로 계속해서 렌더링을 해주는 클래스 코드다.
import numpy as np
import open3d as o3d
class Renderer():
def __init__(self):
self.vis = o3d.visualization.Visualizer()
self.vis.create_window(visible=False)
self.opt = self.vis.get_render_option()
self.opt.background_color = np.asarray([0, 0, 0])
self.opt.mesh_color_option = o3d.visualization.MeshColorOption.Color
self.ctr = self.vis.get_view_control()
print("Field of view (before changing) %.2f" % self.ctr.get_field_of_view())
self.ctr.set_constant_z_near(0.001)
self.ctr.set_constant_z_far(10.)
self.curr_target = None
def render(self, target, screen_camera_path):
if self.curr_target is not None:
self.vis.remove_geometry(self.curr_target)
self.vis.add_geometry(target)
self.curr_target = target
else:
self.vis.add_geometry(target)
self.curr_target = target
parameters = o3d.io.read_pinhole_camera_parameters(screen_camera_path)
self.ctr.convert_from_pinhole_camera_parameters(parameters)
self.vis.poll_events()
self.vis.update_renderer()
depth_rn = np.asarray(self.vis.capture_depth_float_buffer(True))
depth_rn = depth_rn.astype(np.float32)
rgb_rn = np.asarray(self.vis.capture_screen_float_buffer(True))
rgb_rn = rgb_rn.astype(np.float32)
return depth_rn, rgb_rn
def close(self):
self.vis.clear_geometries()
self.vis.destroy_window()
코드가 간단해서 별도의 설명은 필요없어보이지만, 약간의 부가 설명을 더하면 target은 open3d visualizer가 다루는 point cloud나 mesh 파일이 되겠다. 경로(path)가 아닌 o3d.geometry 객체로 넣어주어야 한다.
screen_camera_path는 앞서 P버튼을 통해 얻은 ScreenCamera_xx.json 파일까지의 경로를 넣어주면 된다. 만약 구도를 바꿔주고 싶다면 미리 많은 구도를 저장해두고 매번 다른 경로를 넣어주면 된다.
주의
open3d 0.17.0 버전에서는 convert_from_pinhole_camera_paramters()가 안 먹는 버그가 있다. (2023.10.27)
'Knowhow > Vision' 카테고리의 다른 글
Epipolar line visualization (0) | 2023.03.24 |
---|---|
Open3d manual registration (손으로 point cloud 정합하기) (0) | 2023.03.20 |
Stereo image rectification (0) | 2023.03.16 |
Axis angle(Rodrigues notation) to Rotation matrix (0) | 2023.03.15 |
Disparity generation (1) | 2023.03.08 |