Add scripts for leap motion video capture
This commit is contained in:
parent
b83466f469
commit
c774f2fdf8
80
scripts/leap-view
Executable file
80
scripts/leap-view
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
# Handle program arguments
|
||||||
|
ap = argparse.ArgumentParser(
|
||||||
|
prog="leap-view",
|
||||||
|
description="View the camera feeds from a Leap Motion controller",
|
||||||
|
)
|
||||||
|
ap.add_argument("device", help="Path to the video device")
|
||||||
|
ap.add_argument(
|
||||||
|
"-r",
|
||||||
|
"--resolution",
|
||||||
|
help="Resolution of the camera",
|
||||||
|
choices=["640x120", "640x240", "640x480", "752x120", "752x240", "752x480"],
|
||||||
|
default="640x480",
|
||||||
|
)
|
||||||
|
ap.add_argument("--only", help="Only show the left or right camera", choices=["left", "right"])
|
||||||
|
ap.add_argument(
|
||||||
|
"-v", "--verbose", help="Enable verbose logging", action="store_true"
|
||||||
|
)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
||||||
|
format="%(levelname)s: %(message)s",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Open the video device
|
||||||
|
cap = cv2.VideoCapture(args.device)
|
||||||
|
|
||||||
|
if not cap.isOpened():
|
||||||
|
logger.error("Failed to open video device")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Set the resolution
|
||||||
|
width, height = map(int, args.resolution.split("x"))
|
||||||
|
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
|
||||||
|
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
|
||||||
|
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)
|
||||||
|
|
||||||
|
# Read frames
|
||||||
|
while True:
|
||||||
|
ret, frame = cap.read()
|
||||||
|
|
||||||
|
if not ret:
|
||||||
|
logger.error("Failed to read frame")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Reshape the frame
|
||||||
|
frame = np.reshape(frame, (height, width * 2))
|
||||||
|
|
||||||
|
# Split into left and right frames (every other byte)
|
||||||
|
left_frame = frame[:, 0::2]
|
||||||
|
right_frame = frame[:, 1::2]
|
||||||
|
|
||||||
|
# Show the frame
|
||||||
|
if not args.only or args.only == "left":
|
||||||
|
cv2.imshow("Left", left_frame)
|
||||||
|
if not args.only or args.only == "right":
|
||||||
|
cv2.imshow("Right", right_frame)
|
||||||
|
|
||||||
|
# Check if one of the windows was closed
|
||||||
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||||
|
break
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
111
scripts/leap-virtual-camera
Executable file
111
scripts/leap-virtual-camera
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import cv2
|
||||||
|
import pyvirtualcam
|
||||||
|
import subprocess
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
# Handle program arguments
|
||||||
|
ap = argparse.ArgumentParser(
|
||||||
|
prog="leap-view",
|
||||||
|
description="View the camera feeds from a Leap Motion controller",
|
||||||
|
)
|
||||||
|
ap.add_argument("device", help="Path to the video device")
|
||||||
|
ap.add_argument(
|
||||||
|
"-r",
|
||||||
|
"--resolution",
|
||||||
|
help="Resolution of the camera",
|
||||||
|
choices=["640x120", "640x240", "640x480", "752x120", "752x240", "752x480"],
|
||||||
|
default="640x480",
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
"-v", "--verbose", help="Enable verbose logging", action="store_true"
|
||||||
|
)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
||||||
|
format="%(levelname)s: %(message)s",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Open the video device
|
||||||
|
cap = cv2.VideoCapture(args.device)
|
||||||
|
|
||||||
|
if not cap.isOpened():
|
||||||
|
logger.error("Failed to open video device")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Set the resolution
|
||||||
|
width, height = map(int, args.resolution.split("x"))
|
||||||
|
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
|
||||||
|
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
|
||||||
|
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)
|
||||||
|
|
||||||
|
# Call v4l2loopback to create two virtual cameras
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"sudo",
|
||||||
|
"modprobe",
|
||||||
|
"v4l2loopback",
|
||||||
|
"video_nr=31,32",
|
||||||
|
'card_label="Leap Motion Left","Leap Motion Right"',
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create left and right virtual cameras
|
||||||
|
virtual_cam_left = pyvirtualcam.Camera(
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
fps=30,
|
||||||
|
fmt=pyvirtualcam.PixelFormat.GRAY,
|
||||||
|
device="/dev/video31",
|
||||||
|
)
|
||||||
|
virtual_cam_right = pyvirtualcam.Camera(
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
fps=30,
|
||||||
|
fmt=pyvirtualcam.PixelFormat.GRAY,
|
||||||
|
device="/dev/video32",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Read frames
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
ret, frame = cap.read()
|
||||||
|
|
||||||
|
if not ret:
|
||||||
|
logger.error("Failed to read frame")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Reshape the frame
|
||||||
|
frame = np.reshape(frame, (height, width * 2))
|
||||||
|
|
||||||
|
# Split into left and right frames (every other byte)
|
||||||
|
left_frame = frame[:, 0::2]
|
||||||
|
right_frame = frame[:, 1::2]
|
||||||
|
|
||||||
|
# Write the frames to the virtual cameras
|
||||||
|
virtual_cam_left.send(left_frame)
|
||||||
|
virtual_cam_right.send(right_frame)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
cap.release()
|
||||||
|
virtual_cam_left.close()
|
||||||
|
virtual_cam_right.close()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
Loading…
x
Reference in New Issue
Block a user