Adding support for v4l2 devices directly in python

v4l2l.py is included in src dir. The version you get from pip install does not work with python3 (at least not on my system), so I had to modify a bunch of the functions returning a list() of range() instead of the original range().
This commit is contained in:
Tim Welch 2018-12-23 12:08:18 -05:00
parent 54998e9a97
commit 6a73634ac2
4 changed files with 2034 additions and 6 deletions

View file

@ -95,11 +95,13 @@ insert_model = {
# Check if the user explicitly set ffmpeg as recorder
if config.get("video", "recording_plugin") == "ffmpeg":
from ffmpeg_reader import ffmpeg_reader
# Set the capture source for ffmpeg
from ffmpeg_reader import ffmpeg_reader
video_capture = ffmpeg_reader(config.get("video", "device_path"), config.get("video", "device_format"))
elif config.get("video", "recording_plugin") == "pyv4l2":
# Set the capture source for pyv4l2
from pyv4l2_reader import pyv4l2_reader
video_capture = pyv4l2_reader(config.get("video", "device_path"), config.get("video", "device_format"))
else:
# Start video capture on the IR camera through OpenCV
video_capture = cv2.VideoCapture(config.get("video", "device_path"))

View file

@ -108,11 +108,13 @@ timings['ic'] = time.time()
# Check if the user explicitly set ffmpeg as recorder
if config.get("video", "recording_plugin") == "ffmpeg":
from ffmpeg_reader import ffmpeg_reader
# Set the capture source for ffmpeg
from ffmpeg_reader import ffmpeg_reader
video_capture = ffmpeg_reader(config.get("video", "device_path"), config.get("video", "device_format"))
elif config.get("video", "recording_plugin") == "pyv4l2":
# Set the capture source for pyv4l2
from pyv4l2_reader import pyv4l2_reader
video_capture = pyv4l2_reader(config.get("video", "device_path"), config.get("video", "device_format"))
else:
# Start video capture on the IR camera through OpenCV
video_capture = cv2.VideoCapture(config.get("video", "device_path"))

110
src/pyv4l2_reader.py Normal file
View file

@ -0,0 +1,110 @@
# Class that simulates the functionality of opencv so howdy can use v4l2 devices seamlessly
# Import required modules. lib4l-dev package is also required.
import v4l2
import fcntl
import numpy
import sys
from cv2 import cvtColor, COLOR_GRAY2BGR, CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT
try:
from pyv4l2.frame import Frame
except ImportError:
print("Missing pyv4l2 module, please run:")
print(" pip3 install pyv4l2\n")
sys.exit(13)
class pyv4l2_reader:
""" This class was created to look as similar to the openCV features used in Howdy as possible for overall code cleanliness. """
# Init
def __init__(self, device_name, device_format):
self.device_name = device_name
self.device_format = device_format
self.height = 0
self.width = 0
self.probe()
self.frame = ""
def set(self, prop, setting):
""" Setter method for height and width """
if prop == CAP_PROP_FRAME_WIDTH:
self.width = setting
elif prop == CAP_PROP_FRAME_HEIGHT:
self.height = setting
def get(self, prop):
""" Getter method for height and width """
if prop == CAP_PROP_FRAME_WIDTH:
return self.width
elif prop == CAP_PROP_FRAME_HEIGHT:
return self.height
def probe(self):
""" Probe the video device to get height and width info """
vd = open(self.device_name, 'r')
fmt = v4l2.v4l2_format()
fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
ret = fcntl.ioctl(vd, v4l2.VIDIOC_G_FMT, fmt)
vd.close()
if ret == 0:
height = fmt.fmt.pix.height
width = fmt.fmt.pix.width
else:
# Could not determine the resolution from ioctl call. Reverting to slower ffmpeg.probe() method
import ffmpeg
probe = ffmpeg.probe(self.device_name)
height = int(probe['streams'][0]['height'])
width = int(probe['streams'][0]['width'])
if self.get(CAP_PROP_FRAME_HEIGHT) == 0:
self.set(CAP_PROP_FRAME_HEIGHT, int(height))
if self.get(CAP_PROP_FRAME_WIDTH) == 0:
self.set(CAP_PROP_FRAME_WIDTH, int(width))
def record(self):
""" Start recording """
self.frame = Frame(self.device_name)
def grab(self):
""" Read a sigle frame from the IR camera. """
self.read()
def read(self):
""" Read a sigle frame from the IR camera. """
if not self.frame:
self.record()
# Grab a raw frame from the camera
frame_data = self.frame.get_frame()
# Convert the raw frame_date to a numpy array
img = (
numpy
.frombuffer(frame_data, numpy.uint8)
)
# Convert the numpy array to a proper grayscale image array
img_bgr = cvtColor(img, COLOR_GRAY2BGR)
# Convert the grayscale image array into a proper RGB style numpy array
img2 = (
numpy
.frombuffer(img_bgr, numpy.uint8)
.reshape([352, 352, 3])
)
# Return a single frame of video
return 0, img2
def release(self):
""" Empty our array. If we had a hold on the camera, we would give it back here. """
self.video = ()
self.num_frames_read = 0
if self.frame:
self.frame.close()

1914
src/v4l2.py Normal file

File diff suppressed because it is too large Load diff