-
Notifications
You must be signed in to change notification settings - Fork 84
Refactor capture and transformation handles #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
lpasselin
merged 84 commits into
etiennedub:develop
from
shagren:refactor-transformation
Sep 17, 2020
Merged
Changes from 72 commits
Commits
Show all changes
84 commits
Select commit
Hold shift + click to select a range
2535591
Simple test
shagren 29716b2
More functions supported
shagren 009148a
Merge pull request #1 from shagren/threading-gil-releasing
shagren 68e9505
Fixes, Example
shagren 0b2ab2f
Merge pull request #2 from shagren/threading-gil-releasing
shagren 21f38a2
Merge remote-tracking branch 'upstream/develop' into develop
shagren 516bfb1
Merge remote-tracking branch 'upstream/develop' into develop
shagren 1b0c0b1
Merge remote-tracking branch 'upstream/develop' into develop
shagren 3fa1349
Merge remote-tracking branch 'upstream/develop' into develop
shagren 889072f
Add code quality tool
shagren 6411a4a
Add .mypy_cache to .gitignore
shagren 58005f0
Make line length 120 chars
shagren c94b0da
Initial playback support
shagren 1e88ed5
Seek support
shagren d0264c2
Add tests
shagren 44982bb
Format tests too
shagren fa2323d
Remove commented code
shagren 04b0639
Smaller asset.
shagren 52c6a64
Fix build
shagren e66dad4
Remove debug
shagren 4af8758
Validate if open() method called twice
shagren 9a7765a
Remove unused file placeholder
shagren 146536f
Better typing
shagren da8fdd7
Merge branch 'develop' into mkv-support-3
lpasselin 1264175
Merge branch 'develop' into mkv-support-3
shagren 60f892b
Merge develop
shagren b5ce7b2
CI changes
shagren f6efd0a
CI changes
shagren 152a38a
CI changes
shagren 904aa25
CI changes
shagren ec25eac
CI changes
shagren 04ce188
CI changes
shagren f6ca706
Some changes in tests definitions
shagren 8009436
Fix Maklefile
shagren cbacd61
Fix
shagren ce95f04
Update playback_seek_timestamp function description
shagren 71b8871
Typofix
shagren f769915
Update readme with small details.
lpasselin e5e5f98
rename _thread_safe to thread_safe
lpasselin e0f54a1
reformat line for readability
lpasselin 36e63c9
force ubuntu-18.04. Version supported by SDK
lpasselin 1c09d70
WIP
shagren 1d938f9
WIP
shagren f091db3
Fix build
shagren 11cabd3
Rebase mkv-support-3
shagren 79f3960
Refactor tests
shagren 063eacf
WIP: color controls
shagren 337eed6
More color-module tests
shagren 9f9125d
Refactor device_get_color_control_capabilities()
shagren c9f22ea
WIP: IMU support
shagren d6599fe
Merge remote-tracking branch 'upstream/develop' into refactor-transfo…
shagren 0569641
CI fix
shagren cdec3e7
start/stop cameras support
shagren bed83b1
device_get_capture support
shagren c707908
Remove debug lines
shagren 29d50b2
support of get_capture, get_imu_sample
shagren c4e4448
WIP: Calibration
shagren b1e2a11
WIP: Capture
shagren 444e4b1
Support device_get_raw_calibration
shagren 471b236
Merge branch 'develop' into refactor-transformation
shagren 5ed8db0
Support creating calibration from json file
shagren b447310
convert_3d_to_3d support
shagren 4757c0b
calibration_2d_to_3d support
shagren 8dfb34d
WIP: Transformations support
shagren 0798eba
Transformation functions
shagren b2ad1d5
Refactor transformation
shagren 97ef4bc
Refactor examples
shagren 2be3314
Add benchmark example
shagren 8289354
Fix tests
shagren ac6ca02
Better playback example
shagren 55145a5
Fix playback example
shagren 7dd0034
Rollback some text changes
shagren 5dfd125
rename capsule_xxxx_name to CAPSULE_XXXX_NAME
shagren 8ede0c7
Text fix
shagren af0a144
Typo fix
shagren de36550
Refactor examples
shagren cc99d74
CR changes
shagren 622092e
CR changes
shagren 2013b63
CR changes
shagren 8538aca
CR changes
shagren c95b9db
CR changes
shagren 7cb043d
add py.typed to distribution
shagren 9e37a8f
remove not required _start_imu() call
lpasselin d58ba19
fix PytestAssertRewriteWarning
lpasselin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,4 +65,4 @@ jobs: | |
pip install -e . | ||
- name: Run tests | ||
run: | | ||
make test | ||
make test-no-hardware |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
from argparse import Action, ArgumentParser, Namespace | ||
from enum import Enum | ||
from time import monotonic | ||
|
||
from pyk4a import FPS, ColorResolution, Config, DepthMode, ImageFormat, PyK4A, WiredSyncMode | ||
|
||
|
||
class EnumAction(Action): | ||
""" | ||
Argparse action for handling Enums | ||
""" | ||
|
||
def __init__(self, **kwargs): | ||
# Pop off the type value | ||
enum = kwargs.pop("type", None) | ||
|
||
# Ensure an Enum subclass is provided | ||
if enum is None: | ||
raise ValueError("type must be assigned an Enum when using EnumAction") | ||
if not issubclass(enum, Enum): | ||
raise TypeError("type must be an Enum when using EnumAction") | ||
|
||
# Generate choices from the Enum | ||
kwargs.setdefault("choices", tuple(e.name for e in enum)) | ||
|
||
super(EnumAction, self).__init__(**kwargs) | ||
|
||
self._enum = enum | ||
|
||
def __call__(self, parser, namespace, values, option_string=None): | ||
# Convert value back into an Enum | ||
setattr(namespace, self.dest, self._enum(values)) | ||
|
||
|
||
class EnumActionTuned(Action): | ||
""" | ||
Argparse action for handling Enums | ||
""" | ||
|
||
def __init__(self, **kwargs): | ||
# Pop off the type value | ||
enum = kwargs.pop("type", None) | ||
|
||
# Ensure an Enum subclass is provided | ||
if enum is None: | ||
raise ValueError("type must be assigned an Enum when using EnumAction") | ||
if not issubclass(enum, Enum): | ||
raise TypeError("type must be an Enum when using EnumAction") | ||
|
||
# Generate choices from the Enum | ||
kwargs.setdefault("choices", tuple(e.name.split("_")[-1] for e in enum)) | ||
|
||
super(EnumActionTuned, self).__init__(**kwargs) | ||
|
||
self._enum = enum | ||
|
||
def __call__(self, parser, namespace, values, option_string=None): | ||
# Convert value back into an Enum | ||
items = {item.name.split("_")[-1]: item.value for item in self._enum} | ||
setattr(namespace, self.dest, self._enum(items[values])) | ||
|
||
|
||
def parse_args() -> Namespace: | ||
parser = ArgumentParser( | ||
description="Bench camera captures transfer speed. \n" | ||
lpasselin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"You can check if you USB controller/cable has enough performance." | ||
) | ||
parser.add_argument("--device-id", type=int, default=0, help="Device ID, from zero. Default: 0") | ||
parser.add_argument( | ||
"--color-resolution", | ||
type=ColorResolution, | ||
action=EnumActionTuned, | ||
default=ColorResolution.RES_720P, | ||
help="Color sensor resoultion. Default: 720P", | ||
) | ||
parser.add_argument( | ||
"--color-color_format", | ||
type=ImageFormat, | ||
action=EnumActionTuned, | ||
default=ImageFormat.COLOR_BGRA32, | ||
help="Color color_image color_format. Default: BGRA32", | ||
) | ||
parser.add_argument( | ||
"--depth-mode", | ||
type=DepthMode, | ||
action=EnumAction, | ||
default=DepthMode.NFOV_UNBINNED, | ||
help="Depth sensor mode. Default: NFOV_UNBINNED", | ||
) | ||
parser.add_argument( | ||
"--camera-fps", type=FPS, action=EnumActionTuned, default=FPS.FPS_30, help="Camera FPS. Default: 30" | ||
) | ||
parser.add_argument( | ||
"--synchronized-images-only", | ||
action="store_true", | ||
dest="synchronized_images_only", | ||
help="Only synchronized color and depth images, default", | ||
) | ||
parser.add_argument( | ||
"--no-synchronized-images", | ||
action="store_false", | ||
dest="synchronized_images_only", | ||
help="Color and Depth images can be non synced.", | ||
) | ||
parser.set_defaults(synchronized_images_only=True) | ||
parser.add_argument( | ||
"--wired-sync-mode", | ||
type=WiredSyncMode, | ||
action=EnumActionTuned, | ||
default=WiredSyncMode.STANDALONE, | ||
help="Wired sync mode. Default: STANDALONE", | ||
) | ||
return parser.parse_args() | ||
|
||
|
||
def bench(config: Config, device_id: int): | ||
device = PyK4A(config=config, device_id=device_id) | ||
device.connect() | ||
depth = color = depth_period = color_period = 0 | ||
print("Press CTRL-C top stop benchmark") | ||
started_at = started_at_period = monotonic() | ||
while True: | ||
try: | ||
capture = device.get_capture() | ||
if capture.color is not None: | ||
color += 1 | ||
color_period += 1 | ||
if capture.depth is not None: | ||
depth += 1 | ||
depth_period += 1 | ||
elapsed_period = monotonic() - started_at_period | ||
if elapsed_period >= 2: | ||
print( | ||
f"Color: {color_period / elapsed_period:0.2f} FPS, Depth: {depth_period / elapsed_period: 0.2f} FPS" | ||
) | ||
color_period = depth_period = 0 | ||
started_at_period = monotonic() | ||
except KeyboardInterrupt: | ||
break | ||
elapsed = monotonic() - started_at | ||
device.disconnect() | ||
print() | ||
print(f"Result: Color: {color / elapsed:0.2f} FPS, Depth: {depth / elapsed: 0.2f} FPS") | ||
|
||
|
||
def main(): | ||
args = parse_args() | ||
config = Config( | ||
color_resolution=args.color_resolution, | ||
color_format=args.color_format, | ||
depth_mode=args.depth_mode, | ||
synchronized_images_only=args.synchronized_images_only, | ||
wired_sync_mode=args.wired_sync_mode, | ||
) | ||
bench(config, args.device_id) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from typing import Optional, Tuple | ||
|
||
import cv2 | ||
import numpy as np | ||
|
||
import pyk4a | ||
from pyk4a import Config, PyK4A | ||
|
||
|
||
def colorize( | ||
image: np.ndarray, | ||
clipping_range: Tuple[Optional[int], Optional[int]] = (None, None), | ||
colormap: int = cv2.COLORMAP_HSV, | ||
) -> np.ndarray: | ||
if clipping_range[0] or clipping_range[1]: | ||
img = image.clip(clipping_range[0], clipping_range[1]) | ||
else: | ||
img = image.copy() | ||
img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) | ||
img = cv2.applyColorMap(img, colormap) | ||
return img | ||
|
||
|
||
def main(): | ||
k4a = PyK4A(Config(color_resolution=pyk4a.ColorResolution.RES_720P, depth_mode=pyk4a.DepthMode.NFOV_UNBINNED,)) | ||
k4a.connect() | ||
|
||
while True: | ||
capture = k4a.get_capture() | ||
if capture.depth is not None: | ||
cv2.imshow("Depth", colorize(capture.depth, (None, 5000))) | ||
if capture.ir is not None: | ||
cv2.imshow("IR", colorize(capture.ir, (None, 500), colormap=cv2.COLORMAP_JET)) | ||
if capture.color is not None: | ||
cv2.imshow("Color", capture.color) | ||
if capture.transformed_depth is not None: | ||
cv2.imshow("Transformed Depth", colorize(capture.transformed_depth, (None, 5000))) | ||
if capture.transformed_color is not None: | ||
cv2.imshow("Transformed Color", capture.transformed_color) | ||
lpasselin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
key = cv2.waitKey(10) | ||
if key != -1: | ||
cv2.destroyAllWindows() | ||
break | ||
|
||
k4a.disconnect() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.