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:
parent
54998e9a97
commit
6a73634ac2
4 changed files with 2034 additions and 6 deletions
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -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
110
src/pyv4l2_reader.py
Normal 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
1914
src/v4l2.py
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue