Add support for Linux to opencv

This commit is contained in:
Remi Cadene 2024-07-29 19:14:59 +02:00
parent cff0347fb2
commit 163e81fbc8
1 changed files with 28 additions and 11 deletions

View File

@ -5,6 +5,7 @@ This file contains utilities for recording frames from cameras. For more info lo
import argparse import argparse
import concurrent.futures import concurrent.futures
import math import math
import platform
import shutil import shutil
import threading import threading
import time import time
@ -33,8 +34,18 @@ MAX_OPENCV_INDEX = 60
def find_camera_indices(raise_when_empty=False, max_index_search_range=MAX_OPENCV_INDEX): def find_camera_indices(raise_when_empty=False, max_index_search_range=MAX_OPENCV_INDEX):
if platform.system() == "Linux":
# Linux uses camera ports
print("Linux detected. Finding available camera indices through scanning '/dev/video*' ports")
possible_camera_ids = [int(port.replace("/dev/video", "")) for port in Path("/dev").glob("video*")]
else:
print(
f"Mac or Windows dtected. Finding available camera indices through scanning all indices from 0 to {MAX_OPENCV_INDEX}"
)
possible_camera_ids = range(max_index_search_range)
camera_ids = [] camera_ids = []
for camera_idx in range(max_index_search_range): for camera_idx in possible_camera_ids:
camera = cv2.VideoCapture(camera_idx) camera = cv2.VideoCapture(camera_idx)
is_open = camera.isOpened() is_open = camera.isOpened()
camera.release() camera.release()
@ -59,10 +70,9 @@ def save_image(img_array, camera_index, frame_index, images_dir):
def save_images_from_cameras( def save_images_from_cameras(
images_dir: Path, camera_ids=None, fps=None, width=None, height=None, record_time_s=2 images_dir: Path, camera_ids: list[int] | None = None, fps=None, width=None, height=None, record_time_s=2
): ):
if camera_ids is None: if camera_ids is None:
print("Finding available camera indices")
camera_ids = find_camera_indices() camera_ids = find_camera_indices()
print("Connecting cameras") print("Connecting cameras")
@ -75,9 +85,7 @@ def save_images_from_cameras(
) )
cameras.append(camera) cameras.append(camera)
images_dir = Path( images_dir = Path(images_dir)
images_dir,
)
if images_dir.exists(): if images_dir.exists():
shutil.rmtree( shutil.rmtree(
images_dir, images_dir,
@ -99,7 +107,7 @@ def save_images_from_cameras(
executor.submit( executor.submit(
save_image, save_image,
image, image,
camera.camera_index, camera.index,
frame_index, frame_index,
images_dir, images_dir,
) )
@ -160,7 +168,7 @@ class OpenCVCamera:
When an OpenCVCamera is instantiated, if no specific config is provided, the default fps, width, height and color_mode When an OpenCVCamera is instantiated, if no specific config is provided, the default fps, width, height and color_mode
of the given camera will be used. of the given camera will be used.
Example of usage of the class: Example of usage:
```python ```python
camera = OpenCVCamera(camera_index=0) camera = OpenCVCamera(camera_index=0)
camera.connect() camera.connect()
@ -182,7 +190,7 @@ class OpenCVCamera:
``` ```
""" """
def __init__(self, camera_index: int | str, config: OpenCVCameraConfig | None = None, **kwargs): def __init__(self, camera_index: int, config: OpenCVCameraConfig | None = None, **kwargs):
if config is None: if config is None:
config = OpenCVCameraConfig() config = OpenCVCameraConfig()
# Overwrite config arguments using kwargs # Overwrite config arguments using kwargs
@ -207,7 +215,13 @@ class OpenCVCamera:
# First create a temporary camera trying to access `camera_index`, # First create a temporary camera trying to access `camera_index`,
# and verify it is a valid camera by calling `isOpened`. # and verify it is a valid camera by calling `isOpened`.
tmp_camera = cv2.VideoCapture(self.camera_index)
if platform.system() == "Linux":
# Linux uses ports for connecting to cameras
tmp_camera = cv2.VideoCapture(f"/dev/video{self.camera_index}")
else:
tmp_camera = cv2.VideoCapture(self.camera_index)
is_camera_open = tmp_camera.isOpened() is_camera_open = tmp_camera.isOpened()
# Release camera to make it accessible for `find_camera_indices` # Release camera to make it accessible for `find_camera_indices`
del tmp_camera del tmp_camera
@ -227,7 +241,10 @@ class OpenCVCamera:
# Secondly, create the camera that will be used downstream. # Secondly, create the camera that will be used downstream.
# Note: For some unknown reason, calling `isOpened` blocks the camera which then # Note: For some unknown reason, calling `isOpened` blocks the camera which then
# needs to be re-created. # needs to be re-created.
self.camera = cv2.VideoCapture(self.camera_index) if platform.system() == "Linux":
self.camera = cv2.VideoCapture(f"/dev/video{self.camera_index}")
else:
self.camera = cv2.VideoCapture(self.camera_index)
if self.fps is not None: if self.fps is not None:
self.camera.set(cv2.CAP_PROP_FPS, self.fps) self.camera.set(cv2.CAP_PROP_FPS, self.fps)