WSL2通过OpenCV调用并展示本机摄像头的RTSP视频流

本文介绍了如何在WSL2环境下,通过CMake安装OpenCV和FFmpeg,利用EasyDarwin启动RTSP视频流,然后使用OpenCV在Linux下接收和显示Windows本机的摄像头视频流。同时,文章提到了开启防火墙的必要情况以及推流和接收的命令行参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本篇博客的由来如上图哈哈,WSL2 相关安装教程可以参考我之前的博客:Win11安装WSL2和Nvidia驱动

更多文章欢迎来我的博客小站看呀,会有更多的技术细节~

安装 CMake

ubuntu上请执行

sudo apt install cmake -y

或者编译安装

# 以v3.25.1版本为例
git clone -b v3.25.1 https://github.com/Kitware/CMake.git 
cd CMake
# 你使用`--prefix`来指定安装路径,或者去掉`--prefix`,安装在默认路径。
./bootstrap --prefix=<安装路径> && make && sudo make install

# 验证
cmake --version

如果报错Could NOT find OpenSSL,安装如下依赖即可解决

sudo apt update
sudo apt upgrade
sudo apt install libssl-dev

安装 OpenCV 和 FFmpeg

sudo apt install libopencv-dev
sudo apt install ffmpeg

启动 Windows 本机的 RTSP 视频流

下载解压 EasyDarwin

Easydarwin是国内团队开发的开源流媒体框架。它是基于Go语言研发,从2012年12月创建并发展至今,从原有的单服务的流媒体服务器形式,扩展成现在的云平台架构开源项目,属于高性能开源RTSP流媒体服务器,在Github上受到广大欢迎。

特点:RTSP推模式转发、RTSP拉模式转发、录像、检索、回放、关键帧缓存、秒开画面、RESTful接口、WEB后台管理、分布式负载均衡。

下载解压 release 包

直接运行 EasyDarwin.exe

以 Ctrl + C 停止服务。打开浏览器输入 http://localhost:10008, 进入控制页面,默认用户名密码是admin/admin

查看本机摄像头设备

Windows 本机安装 ffmpeg 这里不再赘述啦,网上教程很多~

查看本机摄像头设备命令如下

ffmpeg -list_devices true -f dshow -i dummy

开始推流

ffmpeg -f dshow -i video="USB2.0 Camera" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://192.168.1.101/test

参数解释

  • -f dshow -i video="摄像头名称" 指定从本地摄像头中读取视频流。将“摄像头名称”替换为您的摄像头名称,例如“USB2.0 Camera”。
  • -vcodec libx264 指定使用 x264 编码器进行视频编码。
  • -preset ultrafast 设置编码速度。这里使用的是最快的编码速度,但可能会导致视频质量下降。
  • -tune zerolatency 设置编码器以实现零延迟。
  • -f rtsp 指定输出流的格式为 RTSP。
  • rtsp://<IP地址>/<路径> 指定 RTSP 流的目标地址。请将 <IP地址> 替换为 Windows 本机 IP 地址,将 <路径> 替换为您想要为流指定的路径。

成功推流如下,注意保持控制台的运行

在这里插入图片描述

开放本机防火墙(可选)

因为我们要在 WSL2 里访问本机的 RTSP 视频流,所以需要打开本机的防火墙,如下图

关闭专用网络和公用网络即可

用 OpenCV 接收视频流

代码如下

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main(int argc, char **argv)
{
    // Ubuntu安装ffmpeg:sudo apt-get install ffmpeg
    // rtsp地址,模拟四路视频流进行展示
    std::string rtsp1 = "rtsp://172.27.148.34/test";
    std::string rtsp2 = rtsp1;
    std::string rtsp3 = rtsp1;
    std::string rtsp4 = rtsp1;

    // CAP_FFMPEG:使用ffmpeg解码
    cv::VideoCapture stream1 = cv::VideoCapture(rtsp1, cv::CAP_FFMPEG);
    cv::VideoCapture stream2 = cv::VideoCapture(rtsp2, cv::CAP_FFMPEG);
    cv::VideoCapture stream3 = cv::VideoCapture(rtsp3, cv::CAP_FFMPEG);
    cv::VideoCapture stream4 = cv::VideoCapture(rtsp4, cv::CAP_FFMPEG);

    if (!stream1.isOpened() || !stream2.isOpened() || !stream3.isOpened() || !stream4.isOpened())
    {
        std::cout << "有视频流未打开" << std::endl;
        return -1;
    }

    cv::Mat frame1;
    cv::Mat frame2;
    cv::Mat frame3;
    cv::Mat frame4;

    cv::Mat H1, H2, V, blur;

    // 使用namedWindow创建窗口,WINDOW_AUTOSIZE:自动调整窗口大小
    cv::namedWindow("rtsp_demo", cv::WINDOW_AUTOSIZE);

    while (true)
    {
        if (!stream1.read(frame1) || !stream2.read(frame2) || !stream3.read(frame3) || !stream4.read(frame4))
        {
            std::cout << "有视频流未读取" << std::endl;
            continue;
        }
        // 缩放等处理
        cv::resize(frame1, frame1, cv::Size(500, 300));

        cv::resize(frame2, frame2, cv::Size(500, 300));
        cv::flip(frame2, frame2, 1);

        cv::resize(frame3, frame3, cv::Size(500, 300));
        cv::cvtColor(frame1, frame1, cv::COLOR_BGR2GRAY);
        cv::cvtColor(frame1, frame1, cv::COLOR_GRAY2BGR);

        cv::resize(frame4, frame4, cv::Size(500, 300));
        cv::putText(frame4, "RTSP demo", cv::Point(100, 100), cv::FONT_ITALIC, 1, cv::Scalar(0, 0, 255), 2);
        // 拼接
        cv::hconcat(frame1, frame2, H1);
        cv::hconcat(frame3, frame4, H2);
        cv::vconcat(H1, H2, V);

        // 高斯模糊一下
        cv::GaussianBlur(V, blur, cv::Size(25, 25), 0);

        cv::imshow("rtsp_demo", blur);

        if (cv::waitKey(1) == 27)
        {
            break;
        }
    }

    return 0;
}

CMakeLists.txt 内容如下

# 最低版本要求
cmake_minimum_required(VERSION 3.10)

# 项目信息
project(rtsp_demo)

# 添加opencv库
find_package(OpenCV REQUIRED)

# 添加头文件
include_directories(${OpenCV_INCLUDE_DIRS})
# 添加库文件
link_libraries(${OpenCV_LIBS})

# 添加可执行程序
add_executable(rtsp_demo src/main.cpp)

启动 cmake 配置并构建

cmake -S . -B build 
cmake --build build 

运行可执行程序

./build/rtsp_demo

结果展示

成功用 WSL2 展示出四路 RTSP 视频流~

### 在 Windows Subsystem for Linux (WSL) 中使用 OpenCV 访问摄像头WSL 环境下尝试通过 OpenCV 使用摄像头会遇到一些挑战,因为默认情况下 WSL 不直接支持硬件设备如摄像头访问。当尝试打开摄像头时可能会收到错误提示 `VIDEOIO(V4L2:/dev/video0): can't open camera by index`[^1]。 然而,有几种方法可以实现这一目标: #### 方法一:利用 V4L2loopback 和 v4l2capture 实现虚拟摄像头传递 一种解决方案是在 Windows 上创建一个虚拟摄像头将其实例化到 WSL 的 `/dev/videoX` 设备节点中。这通常涉及以下几个方面的工作: - **安装依赖项** 需要在 Ubuntu 下安装必要的软件包来处理视频流: ```bash sudo apt-get update && sudo apt-get install -y v4l-utils ffmpeg ``` - **配置V4L2Loopback模块** 创建加载自定义内核模块以允许从主机捕获图像通过虚拟设备提供给Linux子系统。 这一步骤较为复杂,可能需要编译特定版本的驱动程序与当前使用的WSL环境相匹配。 #### 方法二:借助第三方工具和服务转发摄像头数据至WSL 另一种更简便的方式是采用专门设计用于解决此类问题的应用程序或服务,它们可以在后台运行于Windows之上,将来自物理相机的数据桥接到Linux端口供应用程序消费。 例如,可以通过设置SSH隧道或者使用类似CamTwist这样的应用把实际拍摄的画面转码成网络直播的形式传送给位于WSL中的接收者进程解析播放。 #### Python代码示例展示如何尝试连接本地摄像头 尽管上述两种方案都需要额外的努力去实施,下面给出了一段简单的Python脚本用来测试一旦成功建立了通往真实/模拟摄像装置的有效路径之后怎样用OpenCV库来进行基本操作: ```python import cv2 cap = cv2.VideoCapture(0) if not cap.isOpened(): print("Error: Could not open video.") else: while True: ret, frame = cap.read() if not ret: break gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow('Video Stream', gray_frame) key = cv2.waitKey(1) & 0xFF if key == ord('q'): break cap.release() cv2.destroyAllWindows() ``` 这段代码试图获取编号为0的第一个可用摄像头资源,将其转换为灰度模式实时预览直到按下 'q' 键退出循环停止录制过程。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Apple_Coco

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值