Skip to content

Commit f5b5bad

Browse files
committed
feat: add argument parsing for camera settings
1 parent 74bf343 commit f5b5bad

File tree

2 files changed

+74
-23
lines changed

2 files changed

+74
-23
lines changed

example/virtual_cam.py renamed to examples/virtual_cam.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
"""
22
Camera Stream to Virtual V4L2 Device
33
------------------------------------
4-
This script captures images from the Raspberry Pi camera and streams them
4+
This script captures images from the Raspberry Pi camera and streams them
55
to a virtual V4L2 loopback device using OpenCV.
66
77
Usage:
88
1. Install required dependencies:
99
pip install opencv-python picamera2
10-
10+
1111
2. Load v4l2loopback module (if not already loaded):
12-
sudo modprobe v4l2loopback devices=1 video_nr=16 card_label=ProcessedCam max_buffers=4 exclusive_caps=1
13-
12+
sudo modprobe v4l2loopback devices=1 video_nr=8 card_label=ProcessedCam max_buffers=4 exclusive_caps=1
13+
1414
3. Run the script:
1515
python virtual_cam.py
1616
1717
4. Test the video output:
18-
/path/to/pi-webrtc --camera=v4l2:16 --width=1920 --height=1080 ... # View the processed feed by WebRTC
19-
ffplay /dev/video16 # View the processed feed by ffplay
18+
/path/to/pi-webrtc --camera=v4l2:8 --width=1920 --height=1080 ... # View the processed feed by WebRTC
19+
ffplay /dev/video8 # View the processed feed by ffplay
2020
2121
Requirements:
2222
- Raspberry Pi with Camera Module
@@ -29,6 +29,7 @@
2929
import fcntl
3030
import v4l2
3131
import logging
32+
import argparse
3233
from picamera2 import Picamera2, MappedArray
3334

3435
logging.basicConfig(
@@ -37,11 +38,11 @@
3738

3839

3940
class VirtualCameraStreamer:
40-
def __init__(self, video_nr, camera_id=0, width=1920, height=1080):
41+
def __init__(self, width, height, camera_id, virtual_camera):
4142
self.width = width
4243
self.height = height
4344
self.camera_id = camera_id
44-
self.virtual_camera = f"/dev/video{video_nr}"
45+
self.virtual_camera = virtual_camera
4546
self.fd = None
4647
self.picam2 = None
4748

@@ -88,13 +89,17 @@ def _process_frame(self, request):
8889
self.stop()
8990

9091
def start(self):
92+
logging.info(f"Starting streamer with:")
93+
logging.info(f" Resolution: {self.width}x{self.height}")
94+
logging.info(f" Camera ID: {self.camera_id}")
95+
logging.info(f" Output To Virtual Device: {self.virtual_camera}")
96+
9197
if not self.fd:
9298
logging.error("Cannot start streaming without virtual device.")
9399
return
94100

95101
self.picam2.pre_callback = self._process_frame
96102
self.picam2.start()
97-
logging.info(f"Start streaming to {self.virtual_camera}...")
98103

99104
try:
100105
while True:
@@ -113,5 +118,23 @@ def stop(self):
113118

114119

115120
if __name__ == "__main__":
116-
streamer = VirtualCameraStreamer(16, camera_id=1)
121+
parser = argparse.ArgumentParser(description="Start virtual camera streamer")
122+
parser.add_argument("--width", type=int, default=1920, help="Frame width")
123+
parser.add_argument("--height", type=int, default=1080, help="Frame height")
124+
parser.add_argument("--camera-id", type=int, default=0, help="Camera input ID")
125+
parser.add_argument(
126+
"--virtual-device",
127+
type=str,
128+
default="/dev/video8",
129+
help="Virtual video device path",
130+
)
131+
args = parser.parse_args()
132+
133+
streamer = VirtualCameraStreamer(
134+
width=args.width,
135+
height=args.height,
136+
camera_id=args.camera_id,
137+
virtual_camera=args.virtual_device,
138+
)
139+
117140
streamer.start()

example/yolo_cam.py renamed to examples/yolo_cam.py

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
"""
22
Camera Stream to Virtual V4L2 Device
33
------------------------------------
4-
This script captures images from the Raspberry Pi camera and streams them
5-
to a virtual V4L2 loopback device using OpenCV.
4+
This script captures images from the Raspberry Pi camera and streams them
5+
to a virtual V4L2 loopback device using OpenCV.
66
7-
It allows real-time object detection using YOLO while keeping the original
7+
It allows real-time object detection using YOLO while keeping the original
88
camera feed accessible without delay.
99
1010
Usage:
1111
1. Install required dependencies:
1212
pip install opencv-python ultralytics
13-
14-
2. Load v4l2loopback module:
15-
sudo modprobe v4l2loopback devices=2 video_nr=16,17 card_label=RelayCam,YoloCam max_buffers=4 exclusive_caps=1,1
16-
13+
14+
2. Reload v4l2loopback module:
15+
sudo modprobe -r v4l2loopback
16+
sudo modprobe v4l2loopback devices=2 video_nr=8,9 card_label=RelayCam,YoloCam max_buffers=4 exclusive_caps=1,1
17+
1718
3. Start `virtual_cam.py` first:
18-
python virtual_cam.py
19-
19+
python ./examples/virtual_cam.py --width 1920 --height 1080 --camera-id 0 --virtual-device /dev/video8
20+
2021
4. Run `yolo_cam.py` to apply YOLO detection:
21-
python yolo_cam.py
22+
python ./examples/yolo_cam.py --input-device /dev/video8 --output-device /dev/video9 --width 1920 --height 1080
2223
2324
5. Test the video output:
24-
/path/to/pi-webrtc --camera=v4l2:16 --width=1920 --height=1080 ... # View original camera feed
25-
/path/to/pi-webrtc --camera=v4l2:17 --width=1920 --height=1080 ... # View YOLO-processed feed
25+
/path/to/pi-webrtc --camera=v4l2:8 --width=1920 --height=1080 ... # View original camera feed
26+
/path/to/pi-webrtc --camera=v4l2:9 --width=1920 --height=1080 ... # View YOLO-processed feed
2627
2728
Requirements:
2829
- Raspberry Pi with Camera Module
@@ -36,6 +37,7 @@
3637
import fcntl
3738
import v4l2
3839
import logging
40+
import argparse
3941
from ultralytics import YOLO
4042

4143
model = YOLO("/home/pi/yolo11n.pt")
@@ -155,5 +157,31 @@ def stop(self):
155157

156158

157159
if __name__ == "__main__":
158-
streamer = VirtualCameraStreamer("/dev/video16", "/dev/video17")
160+
logging.basicConfig(level=logging.INFO)
161+
162+
parser = argparse.ArgumentParser(description="Virtual camera streamer")
163+
parser.add_argument(
164+
"--input-device",
165+
type=str,
166+
default="/dev/video8",
167+
help="Input camera device path",
168+
)
169+
parser.add_argument(
170+
"--output-device",
171+
type=str,
172+
default="/dev/video",
173+
help="Output virtual camera path",
174+
)
175+
parser.add_argument("--width", type=int, default=1920, help="Frame width")
176+
parser.add_argument("--height", type=int, default=1080, help="Frame height")
177+
178+
args = parser.parse_args()
179+
180+
streamer = VirtualCameraStreamer(
181+
input_device=args.input_device,
182+
output_device=args.output_device,
183+
width=args.width,
184+
height=args.height,
185+
)
186+
159187
streamer.start()

0 commit comments

Comments
 (0)