33import json
44from typing import Dict , List , Optional , Tuple
55
6+ import cv2
67import depthai as dai
78import numpy as np
89import numpy .typing as npt
@@ -66,6 +67,10 @@ def __init__(
6667 }
6768 self .calib : dai .CalibrationHandler = dai .CalibrationHandler ()
6869
70+ # lazy init, camera needs to be connected to
71+ self .P_left : Optional [cv2 .UMat ] = None
72+ self .P_right : Optional [cv2 .UMat ] = None
73+
6974 def get_device_info (self ) -> dai .DeviceInfo :
7075 """Returns a dai.DeviceInfo object with the mx_id.
7176 This allows connecting to multiple devices plugged in the host machine at the same time,
@@ -147,6 +152,30 @@ def to_string(self) -> str:
147152
148153 return ret_string
149154
155+ def compute_projection_matrices (self ) -> Tuple [cv2 .UMat , cv2 .UMat ]:
156+ left_socket = get_socket_from_name ("left" , self .name_to_socket )
157+ right_socket = get_socket_from_name ("right" , self .name_to_socket )
158+
159+ left_D = np .array (self .calib .getDistortionCoefficients (left_socket ))
160+ right_D = np .array (self .calib .getDistortionCoefficients (right_socket ))
161+
162+ R = np .array (self .calib .getStereoRightRectificationRotation ())
163+
164+ T = np .array (self .calib .getCameraTranslationVector (left_socket , right_socket ))
165+ T *= 0.01 # to meter for ROS
166+
167+ R1 , R2 , P1 , P2 , Q , _ , _ = cv2 .stereoRectify (
168+ self .get_K_left (),
169+ left_D ,
170+ self .get_K_right (),
171+ right_D ,
172+ self .undistort_resolution ,
173+ R ,
174+ T ,
175+ flags = 0 ,
176+ )
177+ return P1 , P2
178+
150179 def to_ROS_msg (
151180 self , side : str = "left"
152181 ) -> Tuple [int , int , str , List [float ], npt .NDArray [np .float32 ], npt .NDArray [np .float32 ], npt .NDArray [np .float32 ]]:
@@ -159,24 +188,17 @@ def to_ROS_msg(
159188 distortion_model = "equidistant"
160189 D = self .calib .getDistortionCoefficients (get_socket_from_name (side , self .name_to_socket ))
161190
191+ if self .P_left is None or self .P_right is None :
192+ self .P_left , self .P_right = self .compute_projection_matrices ()
193+
162194 if side == "left" :
163195 K = self .get_K_left ().flatten ()
164196 R = np .array (self .calib .getStereoLeftRectificationRotation ()).flatten ()
165- P_t = np .zeros (3 ).reshape ((3 , 1 )) # Tx, Ty, 0
166- P = np .hstack ((self .get_K_left (), P_t )).flatten ()
197+ P = np .array (self .P_left ).flatten ()
167198
168199 else :
169200 K = self .get_K_right ().flatten ()
170201 R = np .array (self .calib .getStereoRightRectificationRotation ()).flatten ()
171- Extrinsics = np .array (
172- self .calib .getCameraExtrinsics (
173- srcCamera = get_socket_from_name ("left" , self .name_to_socket ),
174- dstCamera = get_socket_from_name ("right" , self .name_to_socket ),
175- )
176- ).reshape ((4 , 4 ))
177- P_t = np .zeros (3 ).reshape ((3 , 1 )) # Tx, Ty, 0
178- P_t [0 ] = Extrinsics [0 , 3 ] # Tx
179- P_t [1 ] = Extrinsics [1 , 3 ] # Ty
180- P = np .hstack ((self .get_K_right (), P_t )).flatten ()
202+ P = np .array (self .P_right ).flatten ()
181203
182204 return height , width , distortion_model , D , K , R , P
0 commit comments