如何从Linux上的网络摄像头捕获静止图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16378944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:51:35  来源:igfitidea点击:

How to capture still image from webcam on linux

linuxwebcamphoto

提问by locomotion

I am trying to write a C++/Qt program for linux, where I take a still image photo from a webcam, make some transformations to a photo (cropping, resizing, etc.), and save it to a jpeg file.

我正在尝试为 linux 编写一个 C++/Qt 程序,我从网络摄像头拍摄静止图像照片,对照片进行一些转换(裁剪、调整大小等),并将其保存到 jpeg 文件。

But I have encountered some problems. The main problem is that standart UVC (usb video device class) linux driver currently does not support direct still image capture: http://www.ideasonboard.org/uvc/.

但是我遇到了一些问题。主要问题是标准 UVC(USB 视频设备类)linux 驱动程序目前不支持直接静态图像捕获:http: //www.ideasonboard.org/uvc/

So, there are two possible ways to capture still image. You can take one frame from the video stream from the camera, or you can take a separate photo, like a digital portable camera. The second way is not supported in linux uvc driver, so the first method is the only way. But the problem is, that if you want to take a frame from the video stream, the size of the photo can't be bigger than the size of video in the video preview window. So, if I want to take 2 megapixel photo, I must start videostream with the size 1600x1200, which is not so comfortable (At least, in Qt the size of the videostream depends on the videopreview window size).

因此,有两种可能的方式来捕捉静止图像。您可以从相机的视频流中拍摄一帧,也可以拍摄单独的照片,如便携式数码相机。linux uvc驱动不支持第二种方式,所以只能用第一种方式。但问题是,如果要从视频流中取一帧,照片的大小不能大于视频预览窗口中的视频大小。所以,如果我想拍摄 2 兆像素的照片,我必须以 1600x1200 的大小启动视频流,这不太舒服(至少,在 Qt 中,视频流的大小取决于视频预览窗口的大小)。

I know that there is video for linux 2 API, which may be helpful in this task, but I don't know how to use it. I am currently learning gstreamer, but I can't now figure out how to do what I need using these tools.

我知道有 linux 2 API 的视频,这可能对这个任务有帮助,但我不知道如何使用它。我目前正在学习 gstreamer,但我现在不知道如何使用这些工具做我需要的事情。

So, I will appreciate any help. I think it is not a hard problem for people who know Linux, GStreamer, v4l2 API, and other linux-specific things.

所以,我会感谢任何帮助。我认为对于了解 Linux、GStreamer、v4l2 API 和其他特定于 linux 的东西的人来说,这不是一个难题。

By the way, the program will be used only with web-camera Logitech C270 HD.

顺便说一下,该程序将仅用于网络摄像头 Logitech C270 HD。

Please, help me. I don't know what API or framework can help me do this. May be you know.

请帮我。我不知道什么 API 或框架可以帮助我做到这一点。也许你知道。

回答by M. Haris Azfar

**Download And Install 'mplayer'** 
mplayer -vo png -frames 1 tv://

回答by Md. Minhazul Haque

What about this program?

这个程序怎么样?

#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
    VideoCapture webcam;
    webcam.open(0);
    Mat frame;
    char key;

    while(true)
    {
        webcam >> frame;
        imshow("My Webcam",frame);
        key = waitKey(10);

        if(key=='s')
        break;
    }
    imwrite("webcam_capture.jpg", frame);
    webcam.release();
    return 0;
}

This will capture a picture of maximum size allowed by your webcam. Now you can add effects or resize the captured image with Qt. And OpenCV is very very easy to integrate with Qt, :)

这将捕获网络摄像头允许的最大尺寸的图片。现在您可以使用 Qt 添加效果或调整捕获的图像大小。而且 OpenCV 很容易与 Qt 集成,:)

回答by Sani Elfishawy

Unfortunately the C4V2 calls in opencv did not work for still image capture with any camera I have tried out of the box using the UVC driver.

不幸的是,opencv 中的 C4V2 调用不适用于我使用 UVC 驱动程序开箱即用的任何相机捕捉静态图像。

To debug the issue I have been playing with trying to accomplish this with c code calling c4v2 directly.

为了调试这个问题,我一直在尝试使用直接调用 c4v2 的 c 代码来完成这个问题。

I have been playing with the example code found here. It uses the method of pulling frames from the video stream.

我一直在使用此处找到的示例代码。它使用从视频流中提取帧的方法。

You can compile it with:

你可以编译它:

gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename

I have experimented with 3 logitech cameras. The best of the lot seems to be the Logitech C910. But even it has significant issues.

我已经尝试过 3 台罗技相机。最好的似乎是罗技 C910。但即使它也有重大问题。

Here are the problems I have encountered trying to accomplish your same task with this code.

以下是我在尝试使用此代码完成相同任务时遇到的问题。

It works pretty much every time with width and height set to 1920x1080.

当宽度和高度设置为 1920x1080 时,它几乎每次都能工作。

When I query other possibilities directly from the command line using for example:

当我直接从命令行查询其他可能性时,例如:

v4l2-ctl --list-formats-ext

and I try some of the other "available" smaller sizes it hangs in the select waiting for the camera to release the buffer.

我尝试了一些其他“可用”较小的尺寸,它挂在选择中等待相机释放缓冲区。

Also when I try to set other sizes directly from the command line using for example:

此外,当我尝试直接从命令行设置其他尺寸时,例如:

v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV

Then check with

然后检查

v4l2-ctl -V

I find that it returns the correct pixel format but quite often not the correct size.

我发现它返回正确的像素格式,但通常不是正确的大小。

Apparently this camera which is listed on the UVC siteas being UVC and therefore v4l2 compatible is not up to snuff. I suspect it is just as bad for other cameras. The other two I tried were also listed as compatible on the site but had worse problems.

显然,这台在 UVC 网站上列为 UVC 且因此与 v4l2 兼容的相机不符合标准。我怀疑这对其他相机也一样糟糕。我试过的另外两个也被列为兼容网站,但有更严重的问题。

I did some more testing on the LogitechC910 after I posted this. I thought I would post the results in case it helps someone else out.

发布此信息后,我对 LogitechC910 进行了更多测试。我想我会发布结果,以防它帮助其他人。

I wrote a script to test v4l2 grabber code mentioned above on all the formats the camera claims it supports when it is queried with v4l2 here are the results:

我编写了一个脚本来测试上面提到的 v4l2 抓取器代码,用于在使用 v4l2 查询时相机声称支持的所有格式,结果如下:

640x480 => Hangs on clearing buffer
160x120 => Works
176x144 => Works
320x176 => Works
320x240 => Works
432x240 => Works
352x288 => Works
544x288 => Works
640x360 =>  Works
752x416 => Hangs on clearing buffer
800x448 => Hangs on clearing buffer
864x480 => Works
960x544 => Works
1024x576 => Works
800x600 => Works
1184x656 => Works
960x720 => Works
1280x720 => Works
1392x768 => Works
1504x832 => Works
1600x896 => Works
1280x960 => Works
1712x960 => Works
1792x1008 => Works
1920x1080 => Works
1600x1200 => Works
2048x1536 => Works
2592x1944 => Hangs on clearing buffer.

It turns out that the default setting of 640x480 doesnt work and that is what trapped me and most others who have posted on message boards.

事实证明,640x480 的默认设置不起作用,这就是我和大多数在留言板上发帖的其他人的困扰。

Since it is grabbing a video frame the first frame it grabs when starting up may have incorrect exposure (often black or close to it). I believe this is because since it is being used as a video camera it adjusts exposure as it goes and doesnt care about the first frames. I believe this also trapped me and other who saw the first frame as black or nearly black and thought it was some kind of error. Later frames have the correct exposure

由于它正在抓取视频帧,因此它在启动时抓取的第一帧可能曝光不正确(通常是黑色或接近它)。我相信这是因为因为它被用作摄像机,所以它会随着它调整曝光并且不关心第一帧。我相信这也困住了我和其他人,他们将第一帧视为黑色或接近黑色,并认为这是某种错误。后面的帧有正确的曝光

It turns out that opencv with python wrappers works fine with this camera if you avoid the land mines listed above and ignore all the error messages. The error messages are due to the fact while the camera accepts v4l2 commands it doesnt respond correctly. So if you set the width it actually gets set correctly but it responds with an incorrect width.

事实证明,如果您避开上面列出的地雷并忽略所有错误消息,那么带有 python 包装器的 opencv 可以很好地与此相机配合使用。错误消息是由于当相机接受 v4l2 命令时它没有正确响应的事实。因此,如果您设置宽度,它实际上设置正确,但它以不正确的宽度响应。

To run under opencv with python wrappers you can do the following:

要使用 python 包装器在 opencv 下运行,您可以执行以下操作:

import cv2
import numpy

cap = cv2.VideoCapture(0)  #ignore the errors
cap.set(3, 960)        #Set the width important because the default will timeout
                       #ignore the error or false response
cap.set(4, 544)        #Set the height ignore the errors
r, frame = cap.read()
cv2.imwrite("test.jpg", frame)

回答by Dave

mplayer -vo png -frames 1 tv://

might give a green screen output as the camera is not yet ready.

由于相机尚未准备好,可能会显示绿屏输出。

mplayer -vo png -frames 2 tv://

You can try increasing the number of frames and choose a number from which the camera gives correct images.

您可以尝试增加帧数并选择一个数字,以便相机提供正确的图像。