OpenCV集成与机器人的360度实时视频

随着人工智能的不断发展,机器人越来越被用来解放人类,使其免受检查危险地点或例行视觉监控枯燥工作的风险。为了提供一定程度的自主决策,机器人通常配备连接到搭载Linux计算机的摄像头,比如英伟达Jetson或x86单板计算机(SBC)。

如果应用需要实时360度视频,有两种方法。第一种更复杂的方法是使用多个摄像头,在计算机上拼接视频,或者分别处理每个视频源。使用的摄像头数量取决于每个摄像头的视场。如果机器人使用两个能展示超过180度的鱼眼镜头,只需要两个摄像头。通常使用三到四个摄像头。

更简单的方法是使用消费者360°摄像头。在自由独立的theta360.guide开发者社区上,开发者讨论的最热门话题之一是如何将360°视野添加到他们的机器人原型中,并将视频传输到OpenCV。

尽管有多种方法可以将360°相机的视频传输到Linux计算机,但最流行的方法是使用USB电缆。WiFi和以太网并不那么流行。RICOH THETA V、X和Z1型号可以在Linux计算机上显示为USB网络摄像头。然而,在Linux上需要进行一些工作。MacOS计算机可以直接使用RICOH THETA相机。对于Windows,RICOH提供了一个驱动程序。对于Linux,RICOH在GitHub上提供了一个名为libuvc-theta的修改版本的libuvc。

为了将相机显示为OpenCV的视频设备,RICOH提供了一个名为libuvc-theta-sample的示例程序。这可以与v4l2loopback一起使用,将一个/dev/video*设备提供给OpenCV。

为了测试相机与Linux计算机的连接,首先将相机与Linux计算机连接,然后运行以下步骤:

Shell

 

git clone https://github.com/ricohapi/libuvc-theta.git
sudo apt install libjpeg-dev
cd libuvc-theta
mkdir build
cd build
cmake ..
make
sudo make install
cd ../..
git clone https://github.com/ricohapi/libuvc-theta-sample.git
cd libuvc-theta-sample/gst
make

# 必须将THETA插入计算机,并处于 
# 实时流模式

./gst_viewer

使用gstreamer显示360°视频相机

如果编译失败,可能需要额外的gstreamer库。这将安装所有库。

Shell

 

sudo apt-get install \
    libgstreamer1.0-0 \
    gstreamer1.0-plugins-base \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    gstreamer1.0-doc \
    gstreamer1.0-tools \
    gstreamer1.0-x \
    gstreamer1.0-alsa \
    gstreamer1.0-gl \
    gstreamer1.0-gtk3 \
    gstreamer1.0-qt5 \
    gstreamer1.0-pulseaudio \
    libgstreamer-plugins-base1.0-dev

此外,由于缺乏4K H.264硬件解码支持,树莓派4将无法使用。

设置/dev/video*

要将libuvc设备作为视频设备可用,我们可以使用v4l2loopbacklibuvc-theta-sample应用程序将使用gstreamer将视频发送到v4l2。

如果您的计算机上只有一个视频摄像头,则应在构建之前修改这一行。下面的行用于连接RICOH THETA作为唯一网络摄像头的计算机:

Plain Text

 

"v4l2sink device=/dev/video0 sync=false";

从OpenCV访问

为了测试摄像头是否可以从OpenCV中使用,让我们从一个简单的帧调整开始。

Python

 

import cv2

cap = cv2.VideoCapture(0)

# 检查摄像头是否正确打开
if not cap.isOpened():
    raise IOError("Cannot open webcam")

while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, None, fx=0.25, fy=0.25, interpolation=cv2.INTER_AREA)
    cv2.imshow('Input', frame)

    c = cv2.waitKey(1)
    if c == 27:
        break

cap.release()
cv2.destroyAllWindows()

摄像头延迟

延迟是社区讨论中的一个重要问题。THETA摄像头的延迟约为350毫秒。对于许多需要机器人快速反应的应用程序来说,这个延迟太高了。如果您在控制一个绕过障碍物移动的无人机,那么这个延迟也太高了。延迟是由于摄像头内部两个镜头的拼接造成的。拼接无法在视频传输中禁用。

v4l2loopback的替代方案

由于v4l2loopback增加了复杂性和开销,gstthetauvc软件包可用于直接从gstreamer访问摄像头。

以下是使用gstthetauvc进行相同测试的示例。

Python

 

import cv2
# 以下管道有效
# cap = cv2.VideoCapture("thetauvcsrc \
#     ! decodebin \
#     ! autovideoconvert \
#     ! video/x-raw,format=BGRx \
#     ! queue ! videoconvert \
#     ! video/x-raw,format=BGR ! queue ! appsink")

# 感谢nickel110提供的管道建议
# 尝试强制硬件加速
# 在Ubuntu 22.04上使用旧的GTX 950测试了NVIDIA 510.73
cap = cv2.VideoCapture("thetauvcsrc \
    ! queue \
    ! h264parse \
    ! nvdec \
    ! gldownload \
    ! queue \
    ! videoconvert n-threads=0 \
    ! video/x-raw,format=BGR \
    ! queue \
    ! appsink")

if not cap.isOpened():
    raise IOError('Cannot open RICOH THETA')

while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
    cv2.imshow('frame', frame)


    c = cv2.waitKey(1)
    if c == 27:
        break

cap.release()
cv2.destroyAllWindows()

360度视频实时反馈示例

以下是使用OpenCV进行颜色转换和边缘检测的示例。

Python

 

# 转换为灰度图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 模糊图像以获得更好的边缘检测效果
img_blur = cv2.GaussianBlur(img_gray, (3,3), 0) 
# Canny边缘检测
edges = cv2.Canny(image=img_blur, threshold1=100, threshold2=200) # Canny边缘检测
# 显示Canny边缘检测图像
cv2.imshow('Canny Edge Detection', edges) 

检测现场人员和显示器。

相机有两个镜头。快门按钮相反的一侧是后置镜头,将放置在场景中心。当物体位于等距投影视图的中心时,对象检测最为准确。

人物位于后置镜头中心

然而,当人类处于等距投影视图的边缘时,检测效果还算不错,即使在夜晚也是如此。您可能需要在鱼眼镜头或360°图像数据库上训练您的模型。

在等距投影视图边缘检测到人类

提高检测准确度

现在您已经在来自实时360°视频源的等距投影帧上实现了基本检测,您可以尝试不同的技术来提高准确度。一种方法是从每一帧创建多个展平场景,然后在每个场景中检测物体。misoji工程师的视频在ROS2 rviz2和KR260中的360°目标检测(Yolo)提供了这种技术的很好演示。还有一种针对全景视频修改过的YOLO版本。请参考论文PV-YOLO:基于YOLOv4的全景视频物体检测模型

结论

使用消费级现成的360° 摄像头,您可以相当轻松地将360°视频显示为USB网络摄像头,以便软件如OpenCV能够访问。通过视频设备或通过gstreamer访问360°视频,标准的OpenCV或其他检测软件可以用于实时视频的等距投影帧。由于图像的失真,对象检测算法的效果不如标准的非360°网络摄像头。然而,即使没有修改,您仍然可以开始一些检测。

要实际将检测用于教育或研究项目之外的用途,您需要研究改进识别失真等距投影视图中物体的技术。

Source:
https://dzone.com/articles/opencv-integration-live-video-for-robotics