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