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

OpenCV 3.4.1-dev在Ubuntu调用USB相机报libv4l2 set_fmt错误求助

解决Ubuntu下OpenCV调用USB相机报错libv4l2: error set_fmt gave us a different result then try_fmt!

我之前也碰到过这个问题,这本质是OpenCV与USB相机通过libv4l2进行格式协商时,相机返回的格式与OpenCV尝试设置的格式不匹配,导致初始化失败或运行崩溃。下面是一步步的解决方案:

1. 先确认相机支持的格式和分辨率

首先用Linux下的v4l2-ctl工具查看相机的所有支持参数,这是解决问题的关键前提:

sudo apt-get install v4l-utils  # 没安装的话先执行这条
v4l2-ctl --list-formats-ext

这个命令会输出相机支持的所有像素格式(比如YUYV、MJPG),以及每个格式对应的分辨率、帧率列表。你可能会看到类似这样的输出:

Size: Discrete 640x480
    Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1280x720
    Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 640x480
    Interval: Discrete 0.017s (60.000 fps)

2. 在代码中显式指定相机支持的参数

不要依赖OpenCV的默认设置,手动指定相机支持的格式、分辨率和帧率,避免协商失败。

Python3 示例代码

import cv2

# 初始化相机,设备号0对应第一个USB相机,多相机时可能是1、2等
cap = cv2.VideoCapture(0)

# 根据v4l2-ctl的结果,设置相机支持的格式(比如YUYV)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y','U','Y','V'))
# 设置支持的分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# 设置帧率(可选,根据支持的列表选择)
cap.set(cv2.CAP_PROP_FPS, 30)

# 检查相机是否成功打开
if not cap.isOpened():
    print("无法打开相机,请检查设备连接或权限")
    exit()

# 验证实际生效的参数(可选,确认设置是否成功)
print(f"实际分辨率: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}x{cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
print(f"实际格式FourCC: {int(cap.get(cv2.CAP_PROP_FOURCC))}")

# 后续的视频读取、导出逻辑
while True:
    ret, frame = cap.read()
    if not ret:
        print("无法获取帧,可能是流中断")
        break
    cv2.imshow('Camera Feed', frame)
    
    # 按需导出PNG或AVI的逻辑示例
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
    elif key == ord('s'):
        cv2.imwrite('captured_frame.png', frame)
        print("已导出PNG图片")
    # AVI导出可以参考OpenCV的VideoWriter类实现

cap.release()
cv2.destroyAllWindows()

C++ 示例代码

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

using namespace cv;
using namespace std;

int main() {
    // 初始化相机
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cerr << "无法打开相机,请检查设备连接或权限" << endl;
        return -1;
    }

    // 设置相机支持的格式(比如YUYV)
    cap.set(CAP_PROP_FOURCC, VideoWriter::fourcc('Y','U','Y','V'));
    // 设置支持的分辨率
    cap.set(CAP_PROP_FRAME_WIDTH, 640);
    cap.set(CAP_PROP_FRAME_HEIGHT, 480);
    // 设置帧率
    cap.set(CAP_PROP_FPS, 30);

    // 验证实际参数
    cout << "实际分辨率: " << cap.get(CAP_PROP_FRAME_WIDTH) << "x" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
    cout << "实际格式FourCC: " << (int)cap.get(CAP_PROP_FOURCC) << endl;

    Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) {
            cerr << "无法获取帧,流中断" << endl;
            break;
        }
        imshow("Camera Feed", frame);

        char key = waitKey(1);
        if (key == 'q') {
            break;
        } else if (key == 's') {
            imwrite("captured_frame.png", frame);
            cout << "已导出PNG图片" << endl;
        }
        // AVI导出逻辑可通过VideoWriter实现
    }

    cap.release();
    destroyAllWindows();
    return 0;
}

3. 尝试切换到V4L1后端(兼容老相机)

如果上面的方法还是不行,可能你的相机对v4l2支持不好,可以强制OpenCV使用更老的v4l1后端:

Python中修改初始化代码

cap = cv2.VideoCapture(0, cv2.CAP_V4L)

C++中修改初始化代码

VideoCapture cap(0, CAP_V4L);

4. 其他可能的修复手段

  • 检查相机权限:确保当前用户有权限访问/dev/video0设备,可以用sudo chmod 666 /dev/video0临时解决,或者将用户加入video组:sudo usermod -aG video $USER(重启后生效)。
  • 更新libv4l库:执行sudo apt-get update && sudo apt-get install --reinstall libv4l-0 libv4l-dev,修复可能的库损坏或版本不兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:53:42