Just to follow up, the answer is yes. Solution: simply use OpenCV's undistort() function.
#!/usr/bin/env python3
import depthai as dai
import cv2
import numpy as np
# Create the pipeline and Camera object
pipeline = dai.Pipeline()
cam_rgb = pipeline.create(dai.node.Camera)
cam_rgb.setBoardSocket(dai.CameraBoardSocket.CAM_A)
cam_rgb.setSize((1280, 800))
# Create the XLinkOut object
video_rgb_out_x = pipeline.create(dai.node.XLinkOut)
video_rgb_out_x.setStreamName("isp_rgb")
cam_rgb.isp.link(video_rgb_out_x.input)
with dai.Device(pipeline) as device:
video_rgb_queue = device.getOutputQueue(name="isp_rgb", maxSize=1, blocking=False)
calibData = device.readCalibration()
intrinsics_rgb = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_A))
distortion_rgb = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_A))
while True:
if video_rgb_queue.has():
# convert to opencv mat
cv_mat = video_rgb_queue.get().getCvFrame()
cv2.imshow("original isp_rgb", cv_mat)
# undistort
cv_mat_undistorted = cv2.undistort(cv_mat, intrinsics_rgb, distortion_rgb)
cv2.imshow("undistorted", cv_mat_undistorted)
if cv2.waitKey(1) == ord('q'):
break
For some reason, Foxglove is not performing the undistortion correctly. No idea why. The solution is to simply do it yourself.
Note: I also passed in the CameraInfo topic to ROS2's image_proc package, and it also correctly undistorted the image. This means the issue appears to be Foxglove's undistortion procedure, whatever that is. If anyone has any information on why this is happening, I would be very interested to know.