Skip to content

Commit

Permalink
Merge pull request #318 from luxonis/release_0411
Browse files Browse the repository at this point in the history
Release 0.4.1.1
  • Loading branch information
SzabolcsGergely authored Jan 22, 2021
2 parents 1ca167a + f6ee9e4 commit 391bc4c
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 59 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ __Documentation is available at [https://docs.luxonis.com](https://docs.luxonis.
DepthAI Demo requires [numpy](https://numpy.org/), [opencv-python](https://pypi.org/project/opencv-python/) and [depthai](https://github.com/luxonis/depthai-api).
To get the versions of these packages you need for the program, use pip: (Make sure pip is upgraded: ` python3 -m pip install -U pip`)
```
python3 -m pip install -r requirements.txt
python3 install_requirements.py
```

Optional:
Expand Down
65 changes: 49 additions & 16 deletions calibrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,30 +78,21 @@ def parse_args():
parser.add_argument("-brd", "--board", default=None, type=str,
help="BW1097, BW1098OBC - Board type from resources/boards/ (not case-sensitive). "
"Or path to a custom .json board config. Mutually exclusive with [-fv -b -w]")
parser.add_argument("-fv", "--field-of-view", default=None, type=float,
help="Horizontal field of view (HFOV) for the stereo cameras in [deg]. Default: 71.86deg.")
parser.add_argument("-b", "--baseline", default=None, type=float,
help="Left/Right camera baseline in [cm]. Default: 9.0cm.")
parser.add_argument("-w", "--no-swap-lr", dest="swap_lr", default=None, action="store_false",
help="Do not swap the Left and Right cameras.")
parser.add_argument("-debug", "--dev_debug", default=None, action='store_true',
help="Used by board developers for debugging.")
parser.add_argument("-fusb2", "--force_usb2", default=False, action="store_true",
help="Force usb2 connection")
parser.add_argument("-iv", "--invert-vertical", dest="invert_v", default=False, action="store_true",
help="Invert vertical axis of the camera for the display")
parser.add_argument("-ih", "--invert-horizontal", dest="invert_h", default=False, action="store_true",
help="Invert horizontal axis of the camera for the display")

options = parser.parse_args()

if (options.board is not None) and ((options.field_of_view is not None)
or (options.baseline is not None)
or (options.swap_lr is not None)):
parser.error("[-brd] is mutually exclusive with [-fv -b -w]")

# Set some defaults after the above check
if options.field_of_view is None: options.field_of_view = 71.86
if options.baseline is None: options.baseline = 9.0
if options.swap_lr is None: options.swap_lr = True
# Set some extra defaults, `-brd` would override them
options.field_of_view = 71.86
options.baseline = 7.5
options.swap_lr = True

return options

Expand All @@ -112,6 +103,24 @@ def find_chessboard(frame):
return cv2.findChessboardCorners(small_frame, (9, 6), chessboard_flags)[0] and \
cv2.findChessboardCorners(frame, (9, 6), chessboard_flags)[0]

def test_camera_orientation(frame_l, frame_r):
chessboard_flags = cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE
# termination criteria
frame_l = cv2.cvtColor(frame_l, cv2.COLOR_RGB2GRAY)
frame_r = cv2.cvtColor(frame_r, cv2.COLOR_RGB2GRAY)
criteria = (cv2.TERM_CRITERIA_MAX_ITER +
cv2.TERM_CRITERIA_EPS, 30, 0.001)
ret, corners_l = cv2.findChessboardCorners(frame_l, (9, 6), chessboard_flags)
ret, corners_r = cv2.findChessboardCorners(frame_r, (9, 6), chessboard_flags)
rt = cv2.cornerSubPix(frame_l, corners_l, (5, 5),
(-1, -1), criteria)
rt = cv2.cornerSubPix(frame_r, corners_r, (5, 5),
(-1, -1), criteria)

for left, right in zip(corners_l, corners_r):
if left[0][0] - right[0][0] < 0:
return False
return True

def ts(packet):
return packet.getMetadata().getTimestamp()
Expand Down Expand Up @@ -202,7 +211,7 @@ def get_pipeline(self):
pipeline = None

try:
device = depthai.Device("", False)
device = depthai.Device("", self.args['force_usb2'])
pipeline = device.create_pipeline(self.config)
except RuntimeError:
raise RuntimeError("Unable to initialize device. Try to reset it")
Expand Down Expand Up @@ -265,6 +274,25 @@ def show(position, text):
# cv2.imshow("right", info_frame)
cv2.imshow("left + right",info_frame)
cv2.waitKey(2000)

def show_failed_orientation(self):
width, height = int(self.width * self.output_scale_factor), int(self.height * self.output_scale_factor)
info_frame = np.zeros((height, width, 3), np.uint8)
print("py: Capture failed, Swap the camera's ")

def show(position, text):
cv2.putText(info_frame, text, position, cv2.FONT_HERSHEY_TRIPLEX, 0.7, (0, 255, 0))

show((60, int(height / 2 - 40)), "Calibration failed, Left and ")
show((60, int(height /2)), "right camera are swapped!")
show((60, int(height / 2 + 40)), "Fix \"swap_left_and_right_cameras\"")
show((60, int(height / 2 + 80)), "and start again")

# cv2.imshow("left", info_frame)
# cv2.imshow("right", info_frame)
cv2.imshow("left + right",info_frame)
cv2.waitKey(0)
raise Exception("Calibration failed, Left and right camera are swapped. Fix \"swap_left_and_right_cameras\" and start again!!")

def capture_images(self):
finished = False
Expand Down Expand Up @@ -308,9 +336,11 @@ def capture_images(self):
if packet.stream_name == 'left' and not tried_left:
captured_left = self.parse_frame(frame, packet.stream_name)
tried_left = True
captured_left_frame = frame.copy()
elif packet.stream_name == 'right' and not tried_right:
captured_right = self.parse_frame(frame, packet.stream_name)
tried_right = True
captured_right_frame = frame.copy()

has_success = (packet.stream_name == "left" and captured_left) or \
(packet.stream_name == "right" and captured_right)
Expand Down Expand Up @@ -340,6 +370,9 @@ def capture_images(self):
frame_list.append(small_frame)

if captured_left and captured_right:
print(f"Images captured --> {self.images_captured}")
if not self.images_captured and not test_camera_orientation(captured_left_frame, captured_right_frame):
self.show_failed_orientation()
self.images_captured += 1
self.images_captured_polygon += 1
capturing = False
Expand Down
21 changes: 16 additions & 5 deletions depthai_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ def print_packet_info(packet, stream_name):
return

def keypress_handler(self, key, stream_names):
cams = ['rgb', 'mono']
self.cam_idx = getattr(self, 'cam_idx', 0) # default: 'rgb'
cam = cams[self.cam_idx]
cam_c = depthai.CameraControl.CamId.RGB
cam_l = depthai.CameraControl.CamId.LEFT
cam_r = depthai.CameraControl.CamId.RIGHT
Expand All @@ -149,7 +152,7 @@ def keypress_handler(self, key, stream_names):
ord('f'): lambda: self.device.request_af_trigger(),
ord('1'): lambda: self.device.request_af_mode(depthai.AutofocusMode.AF_MODE_AUTO),
ord('2'): lambda: self.device.request_af_mode(depthai.AutofocusMode.AF_MODE_CONTINUOUS_VIDEO),
# 5,6,7,8,9,0: short example for using ISP 3A controls
# 5,6,7,8,9,0: short example for using ISP 3A controls for Mono cameras
ord('5'): lambda: self.device.send_camera_control(cam_l, cmd_ae_region, '0 0 200 200 1'),
ord('6'): lambda: self.device.send_camera_control(cam_l, cmd_ae_region, '1000 0 200 200 1'),
ord('7'): lambda: self.device.send_camera_control(cam_l, cmd_exp_comp, '-2'),
Expand All @@ -164,27 +167,35 @@ def keypress_handler(self, key, stream_names):
self.device.request_jpeg()
else:
print("'jpegout' stream not enabled. Try settings -s jpegout to enable it")
elif key == ord('s'): # switch selected camera for manual exposure control
self.cam_idx = (self.cam_idx + 1) % len(cams)
print("======================= Current camera to control:", cams[self.cam_idx])
# RGB manual focus/exposure controls:
# Control: key[dec/inc] min..max
# exposure time: i o 1..33333 [us]
# sensitivity iso: k l 100..1600
# focus: , . 0..255 [far..near]
elif key == ord('i') or key == ord('o') or key == ord('k') or key == ord('l'):
max_exp_us = int(1000*1000 / config['camera'][cam]['fps'])
self.rgb_exp = getattr(self, 'rgb_exp', 20000) # initial
self.rgb_iso = getattr(self, 'rgb_iso', 800) # initial
rgb_iso_step = 50
rgb_exp_step = 500
rgb_exp_step = max_exp_us // 20 # split in 20 steps
if key == ord('i'): self.rgb_exp -= rgb_exp_step
if key == ord('o'): self.rgb_exp += rgb_exp_step
if key == ord('k'): self.rgb_iso -= rgb_iso_step
if key == ord('l'): self.rgb_iso += rgb_iso_step
if self.rgb_exp < 1: self.rgb_exp = 1
if self.rgb_exp > 33333: self.rgb_exp = 33333
if self.rgb_exp > max_exp_us: self.rgb_exp = max_exp_us
if self.rgb_iso < 100: self.rgb_iso = 100
if self.rgb_iso > 1600: self.rgb_iso = 1600
print("=================================== RGB set exposure:", self.rgb_exp, "iso:", self.rgb_iso)
print("===================================", cam, "set exposure:", self.rgb_exp, "iso:", self.rgb_iso)
exp_arg = str(self.rgb_exp) + ' ' + str(self.rgb_iso) + ' 33333'
self.device.send_camera_control(cam_c, cmd_set_exp, exp_arg)
if cam == 'rgb':
self.device.send_camera_control(cam_c, cmd_set_exp, exp_arg)
elif cam == 'mono':
self.device.send_camera_control(cam_l, cmd_set_exp, exp_arg)
self.device.send_camera_control(cam_r, cmd_set_exp, exp_arg)
elif key == ord(',') or key == ord('.'):
self.rgb_manual_focus = getattr(self, 'rgb_manual_focus', 200) # initial
rgb_focus_step = 3
Expand Down
37 changes: 9 additions & 28 deletions depthai_helpers/arg_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def _get_immediate_subdirectories(a_dir):

_stream_choices = ("metaout", "previewout", "jpegout", "left", "right", "depth", "disparity", "disparity_color",
"meta_d2h", "object_tracker", "rectified_left", "rectified_right", "color")
_CNN_choices = _get_immediate_subdirectories(consts.resource_paths.nn_resource_path)
_CNN2_choices = ['landmarks-regression-retail-0009', 'facial-landmarks-35-adas-0002', 'emotions-recognition-retail-0003']
_CNN_choices = [item for item in _get_immediate_subdirectories(consts.resource_paths.nn_resource_path) if item not in _CNN2_choices]

def _stream_type(option):
max_fps = None
Expand Down Expand Up @@ -100,7 +100,7 @@ def parse_args(self):
parser.add_argument("-cs", "--color_scale", default=1.0, type=float,
help="Scale factor for 'color' stream preview window. Default: %(default)s")

parser.add_argument("-monor", "--mono_resolution", default=720, type=int, choices=[400, 720, 800],
parser.add_argument("-monor", "--mono_resolution", default=400, type=int, choices=[400, 720, 800],
help="Mono cam res height: (1280x)720, (1280x)800 or (640x)400 - binning. Default: %(default)s")

parser.add_argument("-monof", "--mono_fps", default=30.0, type=float,
Expand All @@ -115,21 +115,7 @@ def parse_args(self):

parser.add_argument("-lrc", "--stereo_lr_check", default=False, action="store_true",
help="Enable stereo 'Left-Right check' feature.")
parser.add_argument("-fv", "--field-of-view", default=None, type=float,
help="Horizontal field of view (HFOV) for the stereo cameras in [deg]. Default: 71.86deg.")

parser.add_argument("-rfv", "--rgb-field-of-view", default=None, type=float,
help="Horizontal field of view (HFOV) for the RGB camera in [deg]. Default: 68.7938deg.")

parser.add_argument("-b", "--baseline", default=None, type=float,
help="Left/Right camera baseline in [cm]. Default: 9.0cm.")

parser.add_argument("-r", "--rgb-baseline", default=None, type=float,
help="Distance the RGB camera is from the Left camera. Default: 2.0cm.")

parser.add_argument("-w", "--no-swap-lr", dest="swap_lr", default=None, action="store_false",
help="Do not swap the Left and Right cameras.")

parser.add_argument("-e", "--store-eeprom", default=False, action="store_true",
help="Store the calibration and board_config (fov, baselines, swap-lr) in the EEPROM onboard")

Expand Down Expand Up @@ -207,17 +193,12 @@ def parse_args(self):
argcomplete.autocomplete(parser)

options = parser.parse_args()
any_options_set = any([options.field_of_view, options.rgb_field_of_view, options.baseline, options.rgb_baseline,
options.swap_lr])
if (options.board is not None) and any_options_set:
parser.error("[-brd] is mutually exclusive with [-fv -rfv -b -r -w]")

# Set some defaults after the above check
if not options.board:
options.field_of_view = 71.86
options.rgb_field_of_view = 68.7938
options.baseline = 9.0
options.rgb_baseline = 2.0
options.swap_lr = True

# Set some extra defaults, `-brd` would override them
options.field_of_view = 71.86
options.rgb_field_of_view = 68.7938
options.baseline = 7.5
options.rgb_baseline = 3.75
options.swap_lr = True

return options
4 changes: 2 additions & 2 deletions depthai_helpers/calibration_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def setPolygonCoordinates(height, width):
slope = 150

p_coordinates = [
[[margin,margin], [margin, height-margin], [width-margin, height-margin], [width-margin, margin]],

[[margin,0], [margin,height], [width//2, height-slope], [width//2, slope]],
[[horizontal_shift, 0], [horizontal_shift, height], [width//2 + horizontal_shift, height-slope], [width//2 + horizontal_shift, slope]],
[[horizontal_shift*2-margin, 0], [horizontal_shift*2-margin, height], [width//2 + horizontal_shift*2-margin, height-slope], [width//2 + horizontal_shift*2-margin, slope]],

[[margin,margin], [margin, height-margin], [width-margin, height-margin], [width-margin, margin]],

[[width-margin, 0], [width-margin, height], [width//2, height-slope], [width//2, slope]],
[[width-horizontal_shift, 0], [width-horizontal_shift, height], [width//2-horizontal_shift, height-slope], [width//2-horizontal_shift, slope]],
[[width-horizontal_shift*2+margin, 0], [width-horizontal_shift*2+margin, height], [width//2-horizontal_shift*2+margin, height-slope], [width//2-horizontal_shift*2+margin, slope]],
Expand Down
12 changes: 10 additions & 2 deletions depthai_helpers/projector_3d.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#!/usr/bin/env python3
import traceback
import sys

try:
import open3d as o3d
except ImportError:
traceback.print_exc()
print("Importing open3d failed, please run the following command or visit https://pypi.org/project/open3d/")
print()
print(sys.executable + " -m pip install open3d")

import numpy as np
import open3d as o3d

class PointCloudVisualizer():
def __init__(self, intrinsic_matrix, width, height):
Expand Down
1 change: 0 additions & 1 deletion depthai_helpers/version_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ def get_version_from_requirements():
def check_depthai_version():
version_required = get_version_from_requirements()
if version_required is not None:
print('Depthai version required: ', version_required)
if depthai.__version__.endswith('+dev'):
print('Depthai development version found, skipping check.')
elif version_required != depthai.__version__:
Expand Down
4 changes: 4 additions & 0 deletions install_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@
# temporary workaroud for issue between main and develop
subprocess.check_call([*pip_call, "uninstall", "depthai", "--yes"])
subprocess.check_call([*pip_install, "-r", "requirements.txt"])
try:
subprocess.check_call([*pip_install, "-r", "requirements-optional.txt"])
except subprocess.CalledProcessError as ex:
print(f"Optional dependencies were not installed (exit code {ex.returncode})")
1 change: 1 addition & 0 deletions requirements-optional.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
open3d==0.10.0.0; platform_machine != "armv7l" and python_version < "3.9"
7 changes: 3 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ numpy==1.19.5
opencv-python==4.5.1.48
requests==2.24.0
argcomplete==1.12.1
open3d==0.10.0.0; platform_machine != "armv7l" and python_version < "3.9"
pyyaml==5.3.1
depthai==0.4.0.0
depthai==0.4.1.1

#--extra-index-url https://artifacts.luxonis.com/artifactory/luxonis-python-snapshot-local/
#depthai==0.3.0.0+cd9672d8a8eb48811889241a131a655caa2aeee7
# --extra-index-url https://artifacts.luxonis.com/artifactory/luxonis-python-snapshot-local/
# depthai==0.4.1.1+91ba9cbf941592371a7246887a491f0c82632e9d

0 comments on commit 391bc4c

Please sign in to comment.