I am using two IMX296 camera modules from arducam on sockets B and C.
Regarding the calibration file, I am now using oliver-batchelor/multical to calibrate the cameras. It outputs a file such as
{
"cameras": {
"left": {
"model": "standard",
"image_size": [
1440,
1080
],
"K": [
[
534.4490859893428,
0.0,
743.6944390234372
],
[
0.0,
533.8012319294733,
566.7320589263045
],
[
0.0,
0.0,
1.0
]
],
"dist": [
[
-0.002347468452143151
],
[
-0.005754227547204775
],
[
0.002404067276881313
],
[
-0.0014484508120246326
]
]
},
"right": {
"model": "standard",
"image_size": [
1440,
1080
],
"K": [
[
534.0006009633154,
0.0,
758.1256479174064
],
[
0.0,
533.4418232450114,
551.789253072289
],
[
0.0,
0.0,
1.0
]
],
"dist": [
[
-0.0022340112129016
],
[
-0.004959847168109543
],
[
0.000706020387133204
],
[
-0.0007061690270508019
]
]
}
},
"camera_poses": {
"left": {
"R": [
[
1.0,
-4.4552087420585785e-41,
0.0
],
[
-4.446774813811104e-40,
1.0,
0.0
],
[
0.0,
0.0,
1.0
]
],
"T": [
0.0,
0.0,
0.0
]
},
"right_to_left": {
"R": [
[
0.9999797586338518,
-0.004770253136726304,
0.004210345305912925
],
[
0.004798912809891702,
0.9999652057963907,
-0.006823315354363221
],
[
-0.00417764986882906,
0.0068433823211614024,
0.999967857163409
]
],
"T": [
-0.06478756102540092,
-0.0006380282827874789,
0.00011930474545511953
]
}
},
}
Then I have a custom function that flashes the cameras with these settings
# multical_calibration_json_path is the path to the json file generated by multical
def flash(self, multical_calibration_json_path, fisheye=False):
# Backing up device calibration
device_calibration_backup_file = "CALIBRATION_BACKUP.json"
deviceCalib = self.device.readCalibration()
deviceCalib.eepromToJsonFile(device_calibration_backup_file)
print("Backup of device calibration saved to", device_calibration_backup_file)
ch = dai.CalibrationHandler()
os.environ["DEPTHAI_ALLOW_FACTORY_FLASHING"] = "235539980"
if multical_calibration_json_path is None:
print("No calibration file provided")
return
calibration_data = json.load(open(multical_calibration_json_path))
# Loading multical calibration
cameras = calibration_data["cameras"]
camera_poses = calibration_data["camera_poses"]
for cam_name, params in cameras.items():
K = np.array(params["K"])
dist = np.array(params["dist"][0])
im_size = params["image_size"]
cam_id = self.cam_info_reverse[cam_name]
cam_id = stringToCam[cam_id]
ch.setCameraIntrinsics(cam_id, K, im_size)
ch.setDistortionCoefficients(cam_id, dist)
if fisheye:
ch.setCameraType(cam_id, dai.CameraModel.Fisheye)
for cam_name, pose in camera_poses.items():
if "to" not in cam_name: # means left
src_id = self.cam_info_reverse[cam_name]
src_id = stringToCam[src_id]
R = np.array(pose["R"])
ch.setStereoLeft(src_id, R)
continue
src = cam_name.split("_to_")[0]
dst = cam_name.split("_to_")[1]
R = np.array(pose["R"])
T = np.array(pose["T"]) * 100 # weird units out of multical ?
src_id = self.cam_info_reverse[src]
dst_id = self.cam_info_reverse[dst]
src_id = stringToCam[src_id]
dst_id = stringToCam[dst_id]
ch.setCameraExtrinsics(src_id, dst_id, R, T, specTranslation=T)
ch.setStereoRight(src_id, R)
pose = np.eye(4)
pose[:3, :3] = R
pose[:3, 3] = T
inv_pose = np.linalg.inv(pose)
inv_R = inv_pose[:3, :3]
inv_T = inv_pose[:3, 3]
ch.setCameraExtrinsics(dst_id, src_id, inv_R, inv_T, specTranslation=inv_T)
try:
self.device.flashCalibration2(ch)
print("Flashing successful")
except Exception as e:
print("Flashing failed")
print(e)
exit()
The StereoDepth node works with a camera flashed like above
Thanks !