罗技Brio OpenCV捕捉设置

5
我将尝试以60fps的帧率从Logitech Brio录制视频,最好是1080p的分辨率。 这应该是可行的,因为我可以在OBS上成功运行,并且许多人都已经实现了这些设置。
以下是我使用的代码,试图以此帧率进行捕获:
    // Do some grabbing
    cv::VideoCapture video_capture;
    video_capture.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
    video_capture.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
    video_capture.set(cv::CAP_PROP_FPS, 60);
    {
        INFO_STREAM("Attempting to capture from device: " << device);
        video_capture = cv::VideoCapture(device);

        // Read a first frame often empty in camera
        cv::Mat captured_image;
        video_capture >> captured_image;
    }

    if (!video_capture.isOpened())
    {
        FATAL_STREAM("Failed to open video source");
        return 1;
    }
    else INFO_STREAM("Device or file opened");

    cv::Mat captured_image;
    video_capture >> captured_image;

我应该针对Brio做出哪些不同的操作?


具体是什么出了问题? - Max Walczak
5个回答

5

我曾经遇到同样的问题:同样的摄像头,无法更改分辨率或帧速率。经过数小时的努力和在互联网上的搜索,我找到了一个解决方案:需要使用DSHOW,并且需要从捕获设备1(而不是0)读取。下面是参考代码:

fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
cap = cv2.VideoCapture()
cap.open(cameraNumber + 1 + cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FOURCC, fourcc)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 60)

抱歉,我只用Python完成了这个任务,但我希望相同的解决方案也适用于c++。我假设您可以按照以下方式进行操作:
video_capture = cv::VideoCapture(device + 1 + cv::CAP_DSHOW);

1
这解决了我的问题。似乎无论我将帧大小更改为什么,它都始终输出480p。使用DSHOW而不仅仅是平面的cv2.VideoCapture(0)使其清晰明了。我唯一需要做出的更改是我的cap.open(cameraNumber + cv2.CAP_DSHOW),而我的cameraNumber是0。 - biggi_

4

在OpenCV 4.1.0下,我使用Logitech BRIO在Windows系统下实现了4K视频。最后关键似乎是使用CAP_DSHOW,并且在初始化相机之后设置分辨率,而不是之前。

cv::VideoCapture capture;
capture = cv::VideoCapture(cv::CAP_DSHOW);
if (!capture.isOpened())
{
    cerr << "ERROR: Can't initialize camera capture" << endl;
    return 1;
}

capture.set(cv::CAP_PROP_FRAME_WIDTH, 3840);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 2160);
capture.set(cv::CAP_PROP_FPS, 30);

2

我认为这个问题与相机无关。可能是因为你在打开视频捕获时创建了一个单独的作用域。当退出该作用域时,video_capture实例的析构函数将被调用,因此!isOpened()检查将始终返回true。我不明白为什么你要使用那些大括号。相反,应该是:

    INFO_STREAM("Attempting to capture from device: " << device);
    auto video_capture = cv::VideoCapture(device);
    if (!video_capture.isOpened())
    {
        FATAL_STREAM("Failed to open video source");
        return 1;
    }

    cv::Mat captured_image;
    video_capture.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
    video_capture.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
    video_capture.set(cv::CAP_PROP_FPS, 60);

    INFO_STREAM("Device or file opened");
    video_capture >> captured_image;

不幸的是,由于某种原因,我的captured_image仍然是480x640和30fps。除了OpenCV代码之外,还可能有其他问题吗? - calben
由于我没有硬件设备,无法复制问题。代码本身似乎没问题。可能存在目标分辨率与网络摄像头驱动程序握手的问题。480x640是VGA,有点像失效模式。这可能与一些特定设置(如apiPreference/codec)有关。请看这里:https://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html#a85b55cf6a4a50451367ba96b65218ba1 。只有某些特定的设置组合才能够实现全高清检索,否则可能根本无法工作。您尝试过使用gstreamer从该网络摄像头读取流吗? - Max Walczak
我不理解这段代码应该如何工作 - 你创建了一个未连接到相机的“VideoCapture”,设置分辨率和FPS,然后将其覆盖为与实际相机的连接。 - parsley72
你说得对!这是一个非常老的答案,我的代码确实有一个错误。我现在已经纠正了它。 - Max Walczak
只是一点小提示:在Opencv论坛上,我读到有时在打开捕获设备和设置参数之间需要一些延迟。因此,加入一些time.sleep(1)或C++等效代码可能会有所帮助。 - Rob

0

经过一些自己的故障排除,我发现@ffarhour的解决方案对我有用。

fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
cap = cv2.VideoCapture()
cap.open(cameraNumber + 1 + cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FOURCC, fourcc)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
cap.set(cv2.CAP_PROP_FPS, 60)

但是对于将来遇到这个问题的任何人,我还想补充一点,您需要一根好的USB电缆,并最好直接访问一个USB 3.0端口。我先把相机放在了我的坞站里,只有1080p可以工作。

一个好的检查方法是使用Windows 10内置的相机工具。我的经验是,如果您的电缆和USB端口支持高分辨率,则只会在此处显示高分辨率选项。因此,如果此方法不起作用,请不要费心使用Opencv。

另外,对于那些刚开始学习的人:上面的代码片段应该放在您的Opencv while循环之前。在while循环中添加以下内容:

while True:
 ret, frame = cap.read()
 frame = cv2.cvtColor(frame, 1)
 cv2.imshow('original image', frame)
 cv2.waitKey(2)

最后我想指出30 fps 对我来说效果最好(比 24 fps 更好),相机可用的最大分辨率不是 3840 x 2160 像素,而是4096 x 2160,多酷啊?
我还强烈建议下载 Brio 的罗技驱动程序,名为“罗技摄像头设置”,它允许您设置视野、自动对焦和其他您无法访问的功能。

0

已经有很多好的答案了,但我遇到了一些额外的问题,我想补充解决。

首先,让我们讨论一些可能的原因,如果您无法获得所需的FPS或分辨率:

  1. 确保您的网络摄像头插入正确的USB端口(A USB 3.0网络摄像头插入USB 2.0端口(或扩展线)将工作,但可能无法提供所有分辨率或帧速率)
  2. 使用正确的编解码器。例如 fourcc = cv2.VideoWriter_fourcc('M','J','P','G') 某些分辨率/fps需要相机以压缩方式传递数据。
  3. 选择适当的后端。在Windows上,使用 cv2.VideoCapture(0, cv2.CAP_DSHOW)cv2.VideoCapture(0, cv2.CAP_MSMF) 可能适合您。请记住,cv2.CAP_MSMFcv2.CAP_DSHOW 为同一台相机提供不同的分辨率/fps 等。

另外,您可以使用ffmpeg(如果已安装)检查您的网络摄像头支持的格式。使用以下命令列出所有设备:

ffmpeg -list_devices true -f dshow -i dummy

要列出特定设备(例如“BRIO 4K Stream Edition”)的所有格式,请使用以下命令:

ffmpeg -f dshow -list_options true -i video="BRIO 4K Stream Edition"

如果您确定您的设备支持所选后端的所需格式,则可以使用以下代码设置分辨率和其他属性:

cam_index = 1  # index of your camera
# vid = cv2.VideoCapture(cam_index, cv2.CAP_MSMF)
vid = cv2.VideoCapture(cam_index, cv2.CAP_DSHOW)
width = 1920
height = 1080
fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
vid.set(cv2.CAP_PROP_FOURCC, fourcc)
vid.set(cv2.CAP_PROP_FRAME_WIDTH, width)
vid.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
vid.set(cv2.CAP_PROP_FPS, 30)

if not vid.isOpened():
    print(f"Failed to open camera {cam_index}")
    return

希望这些信息能对您有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接