1
ewconfig/scripts/leap-virtual-camera

112 lines
2.7 KiB
Python
Executable File

#! /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())