Examples
Read stereo camera data
import cv2
import phase.pyphase as phase
# Define information about the virtual camera
left_serial = "0815-0000"
right_serial = "0815-0001"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_GENERIC_PYLON
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_VIRTUAL
# Define parameters for read process
downsample_factor = 1.0
display_downsample = 0.25
capture_count = 20
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, "virtual-camera",
device_type,
interface_type
)
# Create stereo camera
cam = phase.stereocamera.createStereoCamera(device_info)
# Connect camera and start data capture
print("Connecting to camera...")
ret = cam.connect()
if (ret):
cam.startCapture()
print("Running camera capture...")
for i in range(0, capture_count):
# Read frame from camera
read_result = cam.read()
if (read_result.valid):
print("Stereo frame received")
print("Framerate: {}".format(cam.getFrameRate()))
# Display stereo images
img_left = phase.scaleImage(
read_result.left, display_downsample)
img_right = phase.scaleImage(
read_result.right, display_downsample)
cv2.imshow("left", img_left)
cv2.imshow("right", img_right)
c = cv2.waitKey(1)
# Quit data capture if 'q' is pressed
if c == ord('q'):
break
else:
cam.disconnect()
raise Exception("Failed to read stereo result")
Compute disparity from stereo camera
import os
import cv2
import phase.pyphase as phase
# Define information about the virtual camera
left_serial = "0815-0000"
right_serial = "0815-0001"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_GENERIC_PYLON
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_VIRTUAL
# Define parameters for process
downsample_factor = 1.0
display_downsample = 0.25
capture_count = 20
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, "virtual-camera",
device_type,
interface_type
)
# Create stereo camera
cam = phase.stereocamera.createStereoCamera(device_info)
# Define calibration files
script_path = os.path.dirname(os.path.realpath(__file__))
data_folder = os.path.join(script_path, "..", "data")
left_yaml = os.path.join(data_folder, "left.yaml")
right_yaml = os.path.join(data_folder, "right.yaml")
# Check for I3DRSGM license
license_valid = phase.stereomatcher.StereoI3DRSGM().isLicenseValid()
if license_valid:
print("I3DRSGM license accepted")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_I3DRSGM,
9, 0, 49, False
)
else:
print("Missing or invalid I3DRSGM license. Will use StereoBM")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_BM,
11, 0, 25, False
)
# Load calibration
calibration = phase.calib.StereoCameraCalibration.calibrationFromYAML(
left_yaml, right_yaml)
# Create stereo matcher
matcher = phase.stereomatcher.createStereoMatcher(stereo_params)
# Connect camera and start data capture
print("Connecting to camera...")
ret = cam.connect()
if (ret):
cam.startCapture()
print("Running camera capture...")
for i in range(0, capture_count):
read_result = cam.read()
if (read_result.valid):
print("Stereo result received")
# Rectify stereo image pair
rect = calibration.rectify(read_result.left, read_result.right)
# Compute stereo match
match_result = matcher.compute(rect.left, rect.right)
# Check compute is valid
if not match_result.valid:
print("Failed to compute match")
continue
# Display stereo and disparity images
img_left = phase.scaleImage(
rect.left, display_downsample)
img_right = phase.scaleImage(
rect.right, display_downsample)
img_disp = phase.scaleImage(
phase.normaliseDisparity(
match_result.disparity), display_downsample)
cv2.imshow("left", img_left)
cv2.imshow("right", img_right)
cv2.imshow("disparity", img_disp)
c = cv2.waitKey(1)
if c == ord('q'):
break
else:
cam.disconnect()
raise Exception("Failed to read stereo result")
Read data from Titania camera and generate 3D
import cv2
import os
import phase.pyphase as phase
# Define information about the Titania camera
# Each camera has unique camera_name, left_serial, and right_serial
camera_name = "746974616e24317"
left_serial = "40098272"
right_serial = "40098282"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_TITANIA
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_USB
script_path = os.path.dirname(os.path.realpath(__file__))
# Define calibration files
test_folder = os.path.join(script_path, "..", ".phase_test")
data_folder = os.path.join(script_path, "..", "data")
left_yaml = os.path.join(data_folder, "titania_left.yaml")
right_yaml = os.path.join(data_folder, "titania_right.yaml")
out_ply = os.path.join(test_folder, "titania_out.ply")
# Define parameters for read process
downsample_factor = 1.0
display_downsample = 0.25
exposure_value = 10000
# Check for I3DRSGM license
license_valid = phase.stereomatcher.StereoI3DRSGM().isLicenseValid()
if license_valid:
print("I3DRSGM license accepted")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_I3DRSGM,
9, 0, 49, False
)
else:
print("Missing or invalid I3DRSGM license. Will use StereoBM")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_BM,
11, 0, 25, False
)
# Load calibration
calibration = phase.calib.StereoCameraCalibration.calibrationFromYAML(
left_yaml, right_yaml)
# Create stereo matcher
matcher = phase.stereomatcher.createStereoMatcher(stereo_params)
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, camera_name,
device_type,
interface_type)
# Create stereo camera
tinaniaCam = phase.stereocamera.TitaniaStereoCamera(device_info)
# Connect camera and start data capture
print("Connecting to camera...")
ret = tinaniaCam.connect()
if (ret):
tinaniaCam.startCapture()
# Set camera exposure value
tinaniaCam.setExposure(exposure_value)
print("Running camera capture...")
while not tinaniaCam.isConnected():
read_result = tinaniaCam.read()
if read_result.valid:
# Rectify stereo image pair
rect_image_pair = calibration.rectify(read_result.left, read_result.right)
rect_img_left = rect_image_pair.left
rect_img_right = rect_image_pair.right
match_result = matcher.compute(rect_img_left, rect_img_right)
# Check compute is valid
if not match_result.valid:
print("Failed to compute match")
continue
# Find the disparity from matcher
disparity = match_result.disparity
# Convert disparity into 3D pointcloud
xyz = phase.disparity2xyz(
disparity, calibration.getQ())
# Display stereo and disparity images
img_left = phase.scaleImage(
rect_img_left, display_downsample)
img_right = phase.scaleImage(
rect_img_right, display_downsample)
img_disp = phase.scaleImage(
phase.normaliseDisparity(
disparity), display_downsample)
cv2.imshow("Left", img_left)
cv2.imshow("Right", img_right)
cv2.imshow("Disparity", img_disp)
c = cv2.waitKey(1)
# Save the pointcloud of current frame if 'p' is pressed
if c == ord('p'):
save_success = phase.savePLY(out_ply, xyz, rect_img_left)
if save_success:
print("Pointcloud saved to " + out_ply)
else:
print("Failed to save pointcloud")
# Quit data capture if 'q' is pressed
if c == ord('q'):
break
else:
tinaniaCam.disconnect()
raise Exception("Failed to read stereo result")
cv2.destroyAllWindows()
Generate point cloud from stereo camera
import os
import cv2
import phase.pyphase as phase
# Define information about the virtual camera
left_serial = "0815-0000"
right_serial = "0815-0001"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_GENERIC_PYLON
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_VIRTUAL
# Define parameters for process
downsample_factor = 1.0
display_downsample = 0.25
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, "virtual-camera",
device_type,
interface_type
)
# Create stereo camera
cam = phase.stereocamera.createStereoCamera(device_info)
# Define calibration files and save pointcloud path
script_path = os.path.dirname(os.path.realpath(__file__))
test_folder = os.path.join(script_path, "..", ".phase_test")
data_folder = os.path.join(script_path, "..", "data")
left_yaml = os.path.join(data_folder, "left.yaml")
right_yaml = os.path.join(data_folder, "right.yaml")
out_ply = os.path.join(test_folder, "out.ply")
# Define calibration files
script_path = os.path.dirname(os.path.realpath(__file__))
data_folder = os.path.join(script_path, "..", "data")
left_yaml = os.path.join(data_folder, "left.yaml")
right_yaml = os.path.join(data_folder, "right.yaml")
# Check for I3DRSGM license
license_valid = phase.stereomatcher.StereoI3DRSGM().isLicenseValid()
if license_valid:
print("I3DRSGM license accepted")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_I3DRSGM,
9, 0, 49, False
)
else:
print("Missing or invalid I3DRSGM license. Will use StereoBM")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_BM,
11, 0, 25, False
)
# Load calibration
calibration = phase.calib.StereoCameraCalibration.calibrationFromYAML(
left_yaml, right_yaml)
# Create stereo matcher
matcher = phase.stereomatcher.createStereoMatcher(stereo_params)
# Connect camera and start data capture
print("Connecting to camera...")
ret = cam.connect()
if (ret):
cam.startCapture()
print("Running camera capture...")
read_result = cam.read()
if (read_result.valid):
print("Stereo result received")
rect = calibration.rectify(read_result.left, read_result.right)
match_result = matcher.compute(rect.left, rect.right)
# Convert disparity to 3D xyz pointcloud
xyz = phase.disparity2xyz(
match_result.disparity, calibration.getQ())
# Display stereo and disparity images
img_left = phase.scaleImage(
rect.left, display_downsample)
img_right = phase.scaleImage(
rect.right, display_downsample)
img_disp = phase.scaleImage(
phase.normaliseDisparity(
match_result.disparity), display_downsample)
cv2.imshow("left", img_left)
cv2.imshow("right", img_right)
cv2.imshow("disparity", img_disp)
c = cv2.waitKey(1)
# Save the pointcloud
save_success = phase.savePLY(out_ply, xyz, rect.left)
if save_success:
print("Pointcloud saved to " + out_ply)
else:
cam.disconnect()
raise Exception("Failed to read stereo result")
Generate calibration from images
import os
import phase.pyphase as phase
# Define data paths
script_path = os.path.dirname(os.path.realpath(__file__))
test_folder = os.path.join(script_path, "..", ".phase_test")
data_folder = os.path.join(
script_path, "..", "data", "checker_sample")
left_cal_folder = data_folder
right_cal_folder = data_folder
output_folder = os.path.join(test_folder, "cal")
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Define calibration files
left_yaml = os.path.join(output_folder, "left.yaml")
right_yaml = os.path.join(output_folder, "right.yaml")
left_img_wildcard = "*_l.png"
right_img_wildcard = "*_r.png"
image_type = phase.calib.CalibrationBoardType.CHECKERBOARD
# Load calibration from images
cal = phase.calib.StereoCameraCalibration.calibrationFromImages(
left_cal_folder, right_cal_folder,
left_img_wildcard, right_img_wildcard,
image_type, 10, 6, 0.039)
if not cal.isValid():
print("Calibration is invalid")
# Save calibration to YAML
save_success = cal.saveToYAML(
left_yaml, right_yaml,
phase.calib.CalibrationFileType.ROS_YAML)
if not save_success:
print("Failed to save calibration to YAML")
Read stereo camera data in thread
import time
import datetime
import cv2
import phase.pyphase as phase
# Define information about the virtual camera
left_serial = "0815-0000"
right_serial = "0815-0001"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_GENERIC_PYLON
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_VIRTUAL
# Define parameters for read process
downsample_factor = 1.0
display_downsample = 0.25
frames = 20
timeout = 30
waitkey_delay = 1
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, "virtual-camera",
device_type,
interface_type
)
# Create stereo camera
cam = phase.stereocamera.createStereoCamera(device_info)
# Callback funtion to run when a frame is read from the camera
def read_callback(read_result: phase.stereocamera.CameraReadResult):
# Display stereo and disparity images
if read_result.valid:
print("Stereo result received")
disp_image_left = phase.scaleImage(read_result.left, 0.25)
disp_image_right = phase.scaleImage(read_result.right, 0.25)
cv2.imshow("left", disp_image_left)
cv2.imshow("right", disp_image_right)
cv2.waitKey(waitkey_delay)
else:
print("Failed to read stereo result")
# Set the callback function to call on new frame
cam.setReadThreadCallback(read_callback)
# Connect camera and start data capture
print("Connecting to camera...")
ret = cam.connect()
if (ret):
cam.startCapture()
print("Running threaded camera capture...")
cam.startContinousReadThread()
start = datetime.datetime.now()
capture_count = cam.getCaptureCount()
while capture_count < frames:
capture_count = cam.getCaptureCount()
frame_rate = cam.getFrameRate()
print("Count {}".format(capture_count))
print("Internal framerate {}".format(frame_rate))
end = datetime.datetime.now()
duration = (end - start).total_seconds()
# Stop if thread reading is too long
if duration > timeout:
break
time.sleep(1)
cam.stopContinousReadThread()
cam.disconnect()
Compute disparity from stereo camera in thread
import os
import datetime
import cv2
import phase.pyphase as phase
# Define information about the virtual camera
left_serial = "0815-0000"
right_serial = "0815-0001"
device_type = phase.stereocamera.CameraDeviceType.DEVICE_TYPE_GENERIC_PYLON
interface_type = phase.stereocamera.CameraInterfaceType.INTERFACE_TYPE_VIRTUAL
# Define parameters for process
downsample_factor = 1.0
display_downsample = 0.25
capture_count = 20
# Create stereo camera device information from parameters
device_info = phase.stereocamera.CameraDeviceInfo(
left_serial, right_serial, "virtual-camera",
device_type,
interface_type
)
# Create stereo camera
cam = phase.stereocamera.createStereoCamera(device_info)
# Define calibration files
script_path = os.path.dirname(os.path.realpath(__file__))
data_folder = os.path.join(script_path, "..", "data")
left_yaml = os.path.join(data_folder, "left.yaml")
right_yaml = os.path.join(data_folder, "right.yaml")
# Check for I3DRSGM license
license_valid = phase.stereomatcher.StereoI3DRSGM().isLicenseValid()
if license_valid:
print("I3DRSGM license accepted")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_I3DRSGM,
9, 0, 49, False
)
else:
print("Missing or invalid I3DRSGM license. Will use StereoBM")
stereo_params = phase.stereomatcher.StereoParams(
phase.stereomatcher.StereoMatcherType.STEREO_MATCHER_BM,
11, 0, 25, False
)
# Load calibration
calibration = phase.calib.StereoCameraCalibration.calibrationFromYAML(
left_yaml, right_yaml)
# Create stereo matcher
matcher = phase.stereomatcher.createStereoMatcher(stereo_params)
# Connect camera and start data capture
print("Connecting to camera...")
ret = cam.connect()
if (ret):
cam.startCapture()
print("Running camera capture...")
for i in range(0, capture_count):
if (read_result.valid):
print("Stereo result received")
# Rectify stereo image pair
rect = calibration.rectify(read_result.left, read_result.right)
print("Running threaded stereo matcher...")
# Start compute threaded stereo matcher
matcher.startComputeThread(rect.left, rect.right)
start = datetime.datetime.now()
capture_count = cam.getCaptureCount()
frame_rate = cam.getFrameRate()
print("Count {}".format(capture_count))
print("Internal framerate {}".format(frame_rate))
while matcher.isComputeThreadRunning():
# check stereo matching is not taking too long, else stop thread
end = datetime.datetime.now()
duration = (end - start).total_seconds()
if duration > timeout:
break
if capture_count > capture_count:
break
# Get the result of threaded stereo matcher
match_result = matcher.getComputeThreadResult()
# Display stereo and disparity images
img_left = phase.scaleImage(
rect.left, display_downsample)
img_right = phase.scaleImage(
rect.right, display_downsample)
img_disp = phase.scaleImage(
phase.normaliseDisparity(
match_result.disparity), display_downsample)
cv2.imshow("left", img_left)
cv2.imshow("right", img_right)
cv2.imshow("disparity", img_disp)
c = cv2.waitKey(1)
if c == ord('q'):
break
# Once finished, stop to read thread
cam.disconnect()