Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 97 additions & 23 deletions calibrate.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
#!/usr/bin/env python3
from datetime import datetime, timedelta
from argparse import ArgumentParser
from collections import deque
from pathlib import Path
import itertools
import traceback
import argparse

import json
from pydoc import render_doc
import shutil
import traceback
from argparse import ArgumentParser
from pathlib import Path

import time
from datetime import datetime, timedelta
from collections import deque
from scipy.spatial.transform import Rotation
import traceback
import itertools
import math

import cv2
from cv2 import resize
import sys
import os

def check_opencv_version(REQUIRED_VERSION = "4.5.5"):
installed = cv2.__version__
if installed != REQUIRED_VERSION:
print(f"[ERROR] OpenCV version mismatch!")
print(f"Installed: {installed}")
print(f"Required : {REQUIRED_VERSION}")
print("Please re-run:")
print(" pip install -r calib_requirements.txt")
sys.exit(1)
else:
print(f"[OK] OpenCV version {installed} is correct.")

check_opencv_version()

import depthai as dai
import numpy as np
import copy
from packaging import version
import sys

import depthai_calibration.calibration_utils as calibUtils

Expand Down Expand Up @@ -166,6 +182,8 @@ def parse_args():
help="Enable the display of polynoms.")
parser.add_argument('-dbg', '--debugProcessingMode', default=False, action="store_true",
help="Enable processing of images without using the camera.")
parser.add_argument('-v3', '--useDepthaiV3', default=True, action="store_true",
help="Use depthai v3.")
options = parser.parse_args()
# Set some extra defaults, `-brd` would override them
if options.defaultBoard is not None:
Expand Down Expand Up @@ -351,6 +369,7 @@ class Main:

def __init__(self):
self.args = parse_args()
self.args.useDepthaiV3 = version.parse(dai.__version__) >= version.parse("3.0.0")
self.traceLevel= self.args.traceLevel
self.output_scale_factor = self.args.outputScaleFactor
self.aruco_dictionary = cv2.aruco.Dictionary_get(
Expand Down Expand Up @@ -462,14 +481,25 @@ def mouse_event_callback(self, event, x, y, flags, param):
self.mouseTrigger = True

def startPipeline(self):
pipeline = self.create_pipeline()
self.device.startPipeline(pipeline)

self.camera_queue = {}
for config_cam in self.board_config['cameras']:
cam = self.board_config['cameras'][config_cam]
if cam["name"] not in self.args.disableCamera:
self.camera_queue[cam['name']] = self.device.getOutputQueue(cam['name'], 1, False)
if version.parse(dai.__version__) < version.parse("3.0.0"):
if str(self.device.getDeviceInfo().platform) != "XLinkPlatform.X_LINK_MYRIAD_X":
sys.exit(
f"ERROR: RVC4 device detected, but DepthAI version {dai.__version__} is installed.\n"
"RVC4 is NOT supported on DepthAI 2.x.\n\n"
"Please upgrade to the latest DepthAI:\n"
" pip install depthai --upgrade --force-reinstall\n"
)
pipeline = self.create_pipeline()
self.device.startPipeline(pipeline)
self.camera_queue = {}
for config_cam in self.board_config['cameras']:
cam = self.board_config['cameras'][config_cam]
if cam["name"] not in self.args.disableCamera:
self.camera_queue[cam['name']] = self.device.getOutputQueue(cam['name'], 1, False)
else:
pipeline = self.create_pipeline_v3()
pipeline.start()
self.pipeline = pipeline

def is_markers_found(self, frame):
marker_corners, _, _ = cv2.aruco.detectMarkers(
Expand Down Expand Up @@ -579,6 +609,42 @@ def create_pipeline(self):

return pipeline

def create_pipeline_v3(self):
pipeline = dai.Pipeline(self.device)
self.camera_queue = {}
fps = self.args.framerate
sync = pipeline.create(dai.node.Sync)
sync.setSyncThreshold(timedelta(milliseconds=50))
for cam_id in self.board_config['cameras']:
cam_info = self.board_config['cameras'][cam_id]
if cam_info["name"] not in self.args.disableCamera:
if cam_info['type'] == 'mono':
cam_node = pipeline.create(dai.node.Camera, fps = fps).build(stringToCam[cam_id])
cam_output = cam_node.requestFullResolutionOutput(type=dai.ImgFrame.Type.NV12)
cam_output.link(sync.inputs[cam_info["name"]])
self.camera_queue[cam_info['name']] = cam_output
sensorName = cam_info['sensorName']
print(f'Sensor name for {cam_info["name"]} is {sensorName}')
else:
cam_node = pipeline.create(dai.node.Camera, fps = fps).build(stringToCam[cam_id])
self.camera_queue[cam_info['name']] = cam_node.requestFullResolutionOutput(type=dai.ImgFrame.Type.NV12).link(sync.inputs[cam_info["name"]])
if cam_info['sensorName'] == "OV9*82":
cam_node.initialControl.setSharpness(0)
cam_node.initialControl.setLumaDenoise(0)
cam_node.initialControl.setChromaDenoise(4)

if cam_info['hasAutofocus']:
if self.args.rgbLensPosition:
cam_node.initialControl.setManualFocus(int(self.args.rgbLensPosition[stringToCam[cam_id].name.lower()]))
else:
cam_node.initialControl.setManualFocusRaw(int(135 / 255))

self.control_queue = cam_node.inputControl.createInputQueue()
sensorName = cam_info['sensorName']
print(f'Sensor name for {cam_info["name"]} is {sensorName}')
#cam_node.initialControl.setAntiBandingMode(antibandingOpts[self.args.antibanding])
self.sync_queue = sync.out.createOutputQueue()
return pipeline

def parse_frame(self, frame, stream_name):
if not self.is_markers_found(frame):
Expand Down Expand Up @@ -717,14 +783,19 @@ def capture_images_sync(self):
sync_trys = 0
while not finished:
currImageList = {}
if self.args.useDepthaiV3:
msg_group = self.sync_queue.get()
for key in self.camera_queue.keys():
frameMsg = self.camera_queue[key].get()
if self.args.useDepthaiV3:
frameMsg = msg_group[key]
else:
frameMsg = self.camera_queue[key].get()

#print(f'Timestamp of {key} is {frameMsg.getTimestamp()}')

syncCollector.add_msg(key, frameMsg)
color_frame = None
if frameMsg.getType() in [dai.RawImgFrame.Type.RAW8, dai.RawImgFrame.Type.GRAY8] :
if not self.args.useDepthaiV3 and frameMsg.getType() in [dai.RawImgFrame.Type.RAW8, dai.RawImgFrame.Type.GRAY8] :
color_frame = cv2.cvtColor(frameMsg.getCvFrame(), cv2.COLOR_GRAY2BGR)
else:
color_frame = frameMsg.getCvFrame()
Expand Down Expand Up @@ -1082,7 +1153,10 @@ def calibrate(self):
print(f'EEPROM VERSION being flashed is -> {eeepromData.version}')
eeepromData.version = 7
print(f'EEPROM VERSION being flashed is -> {eeepromData.version}')
mx_serial_id = self.device.getDeviceInfo().getMxId()
if not self.args.useDepthaiV3:
mx_serial_id = self.device.getDeviceInfo().getMxId()
else:
mx_serial_id = self.device.getDeviceId()
date_time_string = datetime.now().strftime("_%m_%d_%y_%H_%M")
file_name = mx_serial_id + date_time_string
calib_dest_path = dest_path + '/' + file_name + '.json'
Expand All @@ -1091,7 +1165,7 @@ def calibrate(self):
Path(self.args.saveCalibPath).parent.mkdir(parents=True, exist_ok=True)
calibration_handler.eepromToJsonFile(self.args.saveCalibPath)
# try:
self.device.flashCalibration2(calibration_handler)
self.device.flashCalibration(calibration_handler)
is_write_succesful = True
# except RuntimeError as e:
# is_write_succesful = False
Expand Down
2 changes: 1 addition & 1 deletion depthai_calibration
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ opencv-contrib-python==4.5.5.62 # Last successful RPi build, also covers M1 with
--extra-index-url https://artifacts.luxonis.com/artifactory/luxonis-depthai-data-local/wheels/
pyqt5>5,<5.15.6 ; platform_machine != "armv6l" and platform_machine != "armv7l" and platform_machine != "aarch64" and platform_machine != "arm64"
--extra-index-url https://artifacts.luxonis.com/artifactory/luxonis-python-snapshot-local/
depthai==2.30.0.0
depthai
numpy>=1.26.4,<2.0.0 # For RPi Buster (last successful build) and macOS M1 (first build). But allow for higher versions, to support Python3.11 (not available in 1.21.4 yet)
Qt.py
scipy
matplotlib
2 changes: 1 addition & 1 deletion resources/depthai_boards
Submodule depthai_boards updated 64 files
+12 −0 batch/eeprom/DM9098_R7M2E7_oak_d_w.json
+12 −0 batch/eeprom/NG9093_R3M0E4_oak_1_ff_a00579_c5.json
+12 −0 batch/eeprom/NG9093_R3M0E4_oak_1_pcba_c3.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_af.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_ff.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_pro_af.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_pro_ff.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_pro_w.json
+12 −0 batch/eeprom/NG9498_ASM_P10D0_oak4_d_w.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_af.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_ff.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_pro_af.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_pro_ff.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_pro_w.json
+12 −0 batch/eeprom/NG9498_ASM_P10D2_oak4_d_w.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_af.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_ff.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_pro_af.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_pro_ff.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_pro_w.json
+1 −1 batch/eeprom/NG9498_ASM_P7D1_oak4_d_w.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_af.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_ff.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_pro_af.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_pro_ff.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_pro_w.json
+1 −1 batch/eeprom/NG9498_ASM_P9D1_oak4_d_w.json
+12 −0 batch/eeprom/SL3443_ASM_P10D1_oak4_cs_imx586.json
+12 −0 batch/eeprom/SL3443_ASM_P10D1_oak4_cs_og05b10.json
+12 −0 batch/eeprom/SL3443_ASM_P10D1_oak4_s_af.json
+12 −0 batch/eeprom/SL3443_ASM_P10D1_oak4_s_ff.json
+12 −0 batch/eeprom/SL3443_ASM_P10D1_oak4_s_w.json
+12 −0 batch/eeprom/SL3443_ASM_P10D3_oak4_s_af.json
+12 −0 batch/eeprom/SL3443_ASM_P10D3_oak4_s_ff.json
+12 −0 batch/eeprom/SL3443_ASM_P10D3_oak4_s_w.json
+1 −1 batch/eeprom/SL3443_ASM_P5D1_oak4_s_af.json
+1 −1 batch/eeprom/SL3443_ASM_P5D1_oak4_s_ff.json
+1 −1 batch/eeprom/SL3443_ASM_P5D1_oak4_s_w.json
+1 −1 batch/eeprom/SL3443_ASM_P9D1_oak4_s_af.json
+1 −1 batch/eeprom/SL3443_ASM_P9D1_oak4_s_ff.json
+1 −1 batch/eeprom/SL3443_ASM_P9D1_oak4_s_w.json
+65 −0 batch/housing/OAK-4-D-AF.json
+65 −0 batch/housing/OAK-4-D-FF.json
+65 −0 batch/housing/OAK-4-D-W.json
+65 −0 batch/housing/OAK-4-PRO-AF.json
+65 −0 batch/housing/OAK-4-PRO-FF.json
+65 −0 batch/housing/OAK-4-PRO-W.json
+45 −0 batch/housing/OAK-4-S-AF.json
+45 −0 batch/housing/OAK-4-S-FF.json
+45 −0 batch/housing/OAK-4-S-W.json
+129 −33 batch/oak4_d.json
+83 −19 batch/oak4_s.json
+12 −0 batch/oak_1.json
+6 −0 batch/oak_d_w.json
+1 −0 boards/OAK-D-CM4-POE-C11.json
+1 −0 boards/OAK-D-CM4-POE-C24.json
+1 −0 boards/OAK-D-CM4-POE.json
+1 −0 boards/OAK-D-CM4.json
+1 −0 boards/OAK-D-LR.json
+1 −0 boards/OAK-D-POE-W-97.json
+1 −0 boards/OAK-D-PRO-W-97.json
+1 −0 boards/OAK-D-PRO-W-POE-97.json
+1 −0 boards/OAK-D.json
+1 −1 boards_reader.py
Loading