You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C++与OpenCV在Jetson Nano上调用摄像头失败求助

问题:Jetson Nano无头模式下OpenCV+C++捕获摄像头失败

问题场景

在Jetson Nano的无头模式下,使用C++结合OpenCV尝试捕获摄像头输入,程序无法正常获取摄像头流。

程序代码

#include <iostream>
#include <sstream>
#include <new>
#include <string>
#include <sstream>

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

#define INPUT_WIDTH 3264
#define INPUT_HEIGHT 2464

#define DISPLAY_WIDTH 640
#define DISPLAY_HEIGHT 480

#define CAMERA_FRAMERATE 21/1
#define FLIP 2

void DisplayVersion()
{
    std::cout << "OpenCV version: " << cv::getVersionMajor() << "." << cv::getVersionMinor() << "." << cv::getVersionRevision() << std::endl;
}

int main(int argc, const char** argv)
{
    DisplayVersion();

    std::stringstream ss;

    ss << "nvarguscamerasrc !  video/x-raw(memory:NVMM), width=3264, height=2464, format=NV12, framerate=21/1 ! nvvidconv flip-method=2 ! video/x-raw, width=480, height=680, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink";

    //ss << "nvarguscamerasrc !  video/x-raw(memory:NVMM), width=" << INPUT_WIDTH <<
    //", height=" << INPUT_HEIGHT <<
    //", format=NV12, framerate=" << CAMERA_FRAMERATE <<
    //" ! nvvidconv flip-method=" << FLIP <<
    //" ! video/x-raw, width=" << DISPLAY_WIDTH <<
    //", height=" << DISPLAY_HEIGHT <<
    //", format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink";

    cv::VideoCapture video;

    video.open(ss.str());

    if (!video.isOpened())
    {
        std::cout << "Unable to get video from the camera!" << std::endl;

        return -1;
    }

    std::cout << "Got here!" << std::endl;

    cv::Mat frame;

    while (video.read(frame))
    {
        cv::imshow("Video feed", frame);

        if (cv::waitKey(25) >= 0)
        {
            break;
        }
   }

    std::cout << "Finished!" << std::endl;

    return 0;
}

运行输出

使用当前未注释的video.open()命令时:

OpenCV version: 4.6.0
nvbuf_utils: Could not get EGL display connection
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:751 Failed to create CaptureSession
[ WARN:0@0.269] global /tmp/build_opencv/opencv/modules/videoio/src/cap_gstreamer.cpp (1405) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1
Got here!
Finished!

使用注释掉的video.open()命令时:

OpenCV version: 4.6.0
nvbuf_utils: Could not get EGL display connection
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:751 Failed to create CaptureSession

已完成的验证

  • 确认OpenCV与xlaunch可正常工作:能通过mjpeg streamer接收笔记本摄像头流并显示。
  • 通过v4l2-ctl命令确认摄像头已被正确识别:
$ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'RG10'
        Name        : 10-bit Bayer RGRG/GBGB
                Size: Discrete 3264x2464
                        Interval: Discrete 0.048s (21.000 fps)
                Size: Discrete 3264x1848
                        Interval: Discrete 0.036s (28.000 fps)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1640x1232
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.017s (60.000 fps)

解决思路

1. 处理EGL显示连接问题

nvarguscamerasrc依赖EGL硬件加速环境,无头模式下容易缺失,可尝试两种方案:

  • 配置X11显示环境:SSH连接时添加-X参数启用X11转发,本地启动X服务器(如Windows的XLaunch),并在运行程序前执行export DISPLAY=:0。
  • 改用v4l2src替代nvarguscamerasrc:避开EGL依赖,直接使用V4L2接口,修改GStreamer管道为:
    v4l2src device=/dev/video0 ! video/x-raw, width=3264, height=2464, format=RG10, framerate=21/1 ! videoconvert ! video/x-raw, format=BGR ! appsink
    
    注意匹配v4l2-ctl输出的RG10像素格式,而非nvarguscamerasrc的NV12格式。

2. 修复宏定义错误

代码中#define CAMERA_FRAMERATE 21/1会被预处理为整数21,但GStreamer需要num/den格式的字符串。建议直接在管道中写死21/1,或改为字符串宏:#define CAMERA_FRAMERATE "21/1"。

3. 调整管道分辨率匹配

未注释的管道中nvvidconv输出的width=480, height=680比例颠倒(原输入为4:3,正确比例应为680x480),易导致处理失败。建议保持分辨率比例一致,或去掉显式宽高设置,让nvvidconv自动适配。

4. 检查OpenCV编译配置

确保OpenCV针对Jetson Nano编译,且启用GStreamer和CUDA支持。可通过cv::getBuildInformation()输出编译信息,确认GStreamer: YES和CUDA: YES。

5. 独立测试GStreamer管道

脱离OpenCV,先验证GStreamer命令能否正常获取摄像头流:

  • 测试nvarguscamerasrc(需EGL环境):
    gst-launch-1.0 nvarguscamerasrc ! video/x-raw(memory:NVMM), width=3264, height=2464, framerate=21/1 ! nvvidconv ! video/x-raw, format=BGR ! videoconvert ! ximagesink
    
  • 测试v4l2src:
    gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw, width=3264, height=2464, format=RG10, framerate=21/1 ! videoconvert ! ximagesink
    

若命令可正常输出,再调整OpenCV中的管道参数。

内容的提问来源于stack exchange,提问作者onetrillionquestions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 01:25:30