标签: v4l2

Android相机零快门延迟

在正常的快门延迟中,传感器驱动程序将捕获的图像缓冲区提供给v4l2层,这里jpeg(硬件)标头添加了一些额外的数据(exif信息和缩略图),并且该层使图像缓冲区预览堆(在HAL层中)以进行进一步处理.但是在零快门滞后的情况下拍摄照片的过程是什么.这与正常的快门滞后相同吗?如何缩短拍照和图像处理之间的时间.如果不是解释.

embedded-linux v4l2 android-camera

6
推荐指数
1
解决办法
3995
查看次数

用于从视频源(网络摄像头)发出新帧信号的 Gstreamer 消息

我正在尝试使用 gstreamer 将网络摄像头的流保存为一系列图像。到目前为止我已经写了这段代码......

#!/usr/bin/python
import sys, os
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst

 def __init__(self):
      #.... 
      # Code to create a gtk Window
      #....
      self.player = gst.Pipeline("player")
      source = gst.element_factory_make("v4l2src", "video-source")
      sink = gst.element_factory_make("xvimagesink", "video-output")
      caps = gst.Caps("video/x-raw-yuv, width=640, height=480")
      filter = gst.element_factory_make("capsfilter", "filter")
      filter.set_property("caps", caps)
      self.player.add(source, filter, sink)
      gst.element_link_many(source, filter, sink)
Run Code Online (Sandbox Code Playgroud)

之后,我尝试通过总线创建一个信号来侦听来自源或接收器的任何消息,以指示已发送或接收新帧,以便可以保存它。

      bus = self.player.get_bus()
      bus.add_signal_watch()
      bus.connect("message::any", self.save_file,"Save file")
Run Code Online (Sandbox Code Playgroud)

其中 save_file 是我的回调,我要在其中保存文件。

def save_file(self, bus, msg):
      print  "SAVED A NEW FILE"
Run Code Online (Sandbox Code Playgroud)

我有两个问题,

  1. 我如何调用这个回调。消息::any 不起作用。
  2. 当调用此消息时,如何访问图像缓冲区。

更新(2012 …

python gstreamer v4l2

5
推荐指数
1
解决办法
3913
查看次数

v4l2 fcntl.ioctl VIDIOC_S_PARM 用于设置相机捕获的 fps 和分辨率

我正在尝试设置网络摄像头的 fps 和分辨率,并通过 v4l2 Python 进行捕获。

v4l2 Python 文档仅限于;

>>> import v4l2
>>> import fcntl
>>> vd = open('/dev/video0', 'rw')
>>> cp = v4l2.v4l2_capability()
>>> fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp)
0
>>> cp.driver
'ov534'
>>> cp.card
'USB Camera-B4.09.24.1'
Run Code Online (Sandbox Code Playgroud)

查看 videodev2.h ;

#define VIDIOC_S_PARM       _IOWR('V', 22, struct v4l2_streamparm)
Run Code Online (Sandbox Code Playgroud)

VIDIOC_S_PARM 与 v4l2_streamparm 相关;

struct v4l2_streamparm {
    enum v4l2_buf_type type;
union {
    struct v4l2_captureparm capture;
    struct v4l2_outputparm  output;
    __u8    raw_data[200];  /* user-defined */
} parm;
};
Run Code Online (Sandbox Code Playgroud)

如果我想设置参数;

import v4l2
import fcntl
vd = open('/dev/video1', 'rw') …
Run Code Online (Sandbox Code Playgroud)

python webcam v4l2

5
推荐指数
1
解决办法
7726
查看次数

如何查询ffmpeg中的所有设备?

如何使用libavdevice正确查询系统中的所有视频设备?打开输入int err = avformat_open_input(&context, NULL, fmt, NULL);失败,因为未提供设备名称(第二个参数是设备名称,"/dev/video0"例如,如果提供,则仅找到该设备):

    avcodec_register_all();
    avdevice_register_all();
    AVFormatContext* context = avformat_alloc_context();
    AVInputFormat *fmt = av_find_input_format("video4linux");
    printf("trying to open input");
    int err = avformat_open_input(&context, "/dev/video0", fmt, NULL);
    if(err != 0){
        fprintf(stderr, "ffmpeg failed to open input");
    }
    static struct AVDeviceInfoList* devices_list;
    avdevice_list_devices(context, &devices_list);
    int devices_count = devices_list->nb_devices;
    for(int i = 0; i < devices_count; i++){
        printf("Checking device nr. %d \n", i);
        AVDeviceInfo* current_device_info = devices_list->devices[i];

       printf("Find Device: %s", current_device_info->device_description);
    }

    avformat_free_context(context);
Run Code Online (Sandbox Code Playgroud)

如何初始化 AVFormatContext 以查找所有 v4l2 …

ffmpeg v4l2

5
推荐指数
0
解决办法
1493
查看次数

如何更改 OpenCV 不支持但 v4l2 API 支持的网络摄像头属性?

我正在使用OpenCV 3.1Python 2.7从我的网络摄像头Logitech C270捕获视频帧。我也在使用video4linux2(v4l2)来设置我的相机的属性,但这导致了一些问题。我的操作系统是Ubuntu 15.04

我要更改的特定属性是absolute_exposure

我可以通过终端使用v4l2 API手动更改它,使用命令v4l2-ctl --set-ctrl exposure_absolute=40,它工作得很好,但我需要为此任务编写脚本。

使用 OpenCVset(cv2.CAP_PROP_EXPOSURE, 20)会导致“VIDEOIO ERROR: V4L: Property Exposure(15) not supported by device”。我确定网络摄像头支持更改此属性,因为可以使用 v4l2 这样做,然后我假设问题出在 OpenCV 的包装器上。

我还试图用LIB发送终端命令,并使用更改属性V4L2。命令是subprocess.call('v4l2-ctl --device=/dev/video0 --set-ctrl exposure_absolute=20', shell=True).

结果是 Exposure_absolute 发生了变化,但它不适用于我当前的视频捕获。图 1 显示了通过脚本设置属性后的结果。图 2 显示了通过终端设置相同属性后的结果,相同的视频捕获处于活动状态。

通过脚本设置exposure_absolute(图1)

通过终端设置exposure_absolute(图2)

图 2 是在图 1 之后拍摄的,突出显示的线与图 1 相同。

我在子流程调用上做错了什么吗?或者如何使用脚本更改此属性?

另外,为什么要cv2.VideoCapture(id)重置相机属性,在运行脚本之前更改它们是没有用的,是否可以停止?

__________________________________________________

编辑:我可能找到了解决此问题的方法。子进程调用确实是正确的,我只需要cv2.read()在更改属性之前使用一次,显然第一个 …

python opencv subprocess v4l2 ubuntu-15.04

5
推荐指数
1
解决办法
4934
查看次数

v4l2 Python-流视频-映射缓冲区

我正在为Raspbian(Raspberry Pi 2)中的Python开发视频捕获脚本,由于在内存映射缓冲区方面没有成功,因此无法为v4l2使用Python绑定。

我需要的:

  • 从HD-WebCam捕获视频(稍后将同时捕获其中的2个视频)。
  • 能够通过WLAN流传输该视频(在网络负载和处理速度之间妥协)。
  • 将来,可以在流式传输之前对图像应用滤镜(不是必须的)。

我尝试过的

  • 使用OpenCV(cv2)。它非常易于使用,但是由于它将网络摄像头的JPEG帧转换为原始图像,因此增加了很多处理负载,然后我不得不将它们转换回JPEG,然后再通过WLAN发送。
  • 直接从“ / dev / video0”读取。太好了,因为网络摄像头发送已压缩的帧,而我可以读取并发送它们,但是看来我的相机不支持该帧。
  • 对Python使用v4l2绑定。到目前为止,这是最有前途的选择,但是当我不得不映射视频缓冲区时,我陷入了困境。我发现没有办法克服这些东西似乎需要的“内存指针/映射”。

我读过的东西:

我的问题:

  1. 有一个更好的方法吗?否则
  2. 我可以告诉OpenCV不要解压缩图像吗?最好使用OpenCV来应用将来的扩展。我在这里发现这是不允许的。
  3. 如何解决Python中的映射步骤?(任何可行的例子吗?)

这是我的(缓慢的)OpenCV工作示例:

import cv2
import time

video = cv2.VideoCapture(0)

print 'Starting video-capture test...'

t0 = time.time()
for i in xrange(100):
    success, image = video.read()
    ret, jpeg = cv2.imencode('.jpg',image)

t1 = time.time()
t = ( t1 - t0 ) / 100.0
fps = 1.0 / t …
Run Code Online (Sandbox Code Playgroud)

opencv video-capture v4l2 python-2.7

5
推荐指数
2
解决办法
3219
查看次数

使用 mmap 环形缓冲区捕获 v4l2 相机是否对跟踪应用程序有意义

我正在开发一个 v4l2 API,用于从嵌入式平台上的原始传感器捕获图像。我的捕获例程与[1]上的示例有关。建议的流式传输方法是使用 mmaped 缓冲区作为环形缓冲区。
对于初始化,使用带有 VIDIOC_REQBUFS 标识符的 ioctl 请求缓冲区(默认 = 4 个缓冲区)。随后,它们使用 VIDIOC_QBUF 排队。此处描述了整个流式传输过程[2]。一旦流开始,驱动程序就会用数据填充排队的缓冲区。v4l2_buffer 结构的时间戳表示捕获的第一个字节的时间,在我的情况下,这导致缓冲区之间的时间间隔约为 8.3 ms (=120fps)。到现在为止还挺好。
现在我对环形缓冲区的期望是新捕获以循环方式自动覆盖旧捕获。但事实并非如此。只有当缓冲区在出队 (VIDIOC_DQBUF) 和处理(去马赛克、跟踪步骤等)后再次排队 (VIDIOC_QBUF) 时,才会将新帧分配给缓冲区。如果我确实满足时序条件(处理 < 8.3 ms),则出队时我不会得到最新捕获的帧,而是最旧的捕获帧(根据 FIFO),因此是当前帧之前 3x8.3 ms 的帧。如果不满足时序条件,则时间跨度会变得更大,因为缓冲区不会被覆盖。

所以我有几个问题:
1. 这个跟踪应用程序有一个环形缓冲区是否有意义,因为我真的不需要帧的历史记录?我当然对此表示怀疑,但是通过使用建议的 mmap 方法,驱动程序通常需要请求最少数量的缓冲区。
2. 一个单独的线程是否应该连续使用 DQBUF 和 QBUF 来完成缓冲区覆盖?这怎么可能实现?
3. 作为一种解决方法,您可能会在每次捕获时使所有缓冲区出队和重新入队,但这听起来不对。是否有人在实时捕获和流式传输方面具有更多经验,可以指出“正确”的方法?
4. 目前,我正在 DQBUF 和 QBUF 之间进行预处理步骤(去马赛克)以及之后的跟踪步骤。在再次调用 QBUF 之前是否也应该执行跟踪步骤?

所以主要代码基本上是在一个while循环中依次执行Capture()和Track()。Capture 例程如下所示:

cv::Mat v4l2Camera::Capture( size_t timeout ) { 

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(mFD, &fds);

    struct timeval tv;

    tv.tv_sec  = 0;
    tv.tv_usec = 0;

    const bool …
Run Code Online (Sandbox Code Playgroud)

c++ video-capture v4l2

5
推荐指数
0
解决办法
809
查看次数

使用 V4l2 进行视频捕获时出现丢帧/丢失帧

我有一个科学应用程序,可以捕获 video4Linux 视频流。捕捉每一帧并且不丢失任何人是至关重要的。不幸的是,框架到处都不见了,我不知道为什么。

为了检测丢帧,我在读取帧后直接将 v4l2_buffer 的序列号与我自己的计数器进行比较:

void detectDroppedFrame(v4l2_buffer* buffer) {
        _frameCounter++;

        auto isLastFrame = buffer->sequence == 0 && _frameCounter > 1;
        if (!isLastFrame && _frameCounter != buffer->sequence+1)
        {
                std::cout << "\n####### WARNING! Missing frame detected!" << std::endl;               
                _frameCounter = buffer->sequence+1; // re-sync our counter with correct frame number from driver.
        }
}
Run Code Online (Sandbox Code Playgroud)

我的运行 1 文件示例要点可以在 github 上找到(基于官方 V4L2 捕获示例):https://gist.github.com/SebastianMartens/7d63f8300a0bcf0c7072a674b3ea4817

在笔记本硬件(uvcvideo 驱动程序)上的 Ubuntu 18.04 虚拟机上使用网络摄像头进行了测试,并在本地运行 ubuntu 18.04 的嵌入式硬件上使用 CSI 摄像头进行了测试。帧未处理,缓冲区似乎被足够快地抓取(使用 VIDIOC_QUERYBUF 检查缓冲区状态,这表明所有缓冲区都在驱动程序的传入队列中,并且未设置 V4L2_BUF_FLAG_DONE 标志)。我使用 MMAP 以及 UserPtr 方法丢失了帧。而且它似乎与像素格式、图像大小和帧速率无关!

对我来说,如果相机/v4l2驱动程序无法足够快地填充可用缓冲区,但使用VIDIOC_S_PRIORITY命令增加文件描述符优先级也没有帮助(仍然可能是线程调度问题?)。

=> …

c++ v4l2

5
推荐指数
1
解决办法
2545
查看次数

Chrome 检测到 v4l2loopback 设备,Zoom 或 Firefox 未发现

我正在尝试从我的网络摄像头创建一个环回设备,以便可以从 Zoom 和浏览器访问。我创建了三个 v4l2loopback 设备:

sudo modprobe v4l2loopback devices=3 video_nr=10,11,12 card_label="Loopback_1","Loopback_2","Virtual_cam" exclusive_caps=1,1,0
Run Code Online (Sandbox Code Playgroud)

其次是:

ffmpeg -i /dev/video0 -f v4l2 -vcodec rawvideo -pix_fmt yuv420p /dev/video10 -f v4l2 /dev/video11
Run Code Online (Sandbox Code Playgroud)

Chrome 可以检测到这两种设备,但 Zoom 和 Firefox 都无法检测到。根据 stackoverflow 上其他问题的建议,我尝试使用 v4l2loopback-ctl 设置设备属性,使用v4l2loopback-ctl set-caps "video/x-raw,format=UYVY,width=640,height=480" /dev/video10,并得到响应:

将管道设置为暂停...错误:管道不想暂停。错误:来自元素 /GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0:设备“/dev/video10”不是输出设备。附加调试信息:v4l2_calls.c(636):gst_v4l2_open():/GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0:功能:0x85208000将管道设置为NULL...释放管道...输出到/dev/video10失败

我还尝试使用 gst-launch-1.0:

gst-launch-1.0 v4l2src device=/dev/video0 ! v4l2sink device=/dev/video10
Run Code Online (Sandbox Code Playgroud)

这告诉我 /dev/video10 不是输出设备:

将管道设置为暂停...错误:管道不想暂停。错误:来自元素 /GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0:设备“/dev/video10”不是输出设备。附加调试信息:v4l2_calls.c(636):gst_v4l2_open():/GstPipeline:pipeline0/GstV4l2Sink:v4l2sink0:功能:0x85208000将管道设置为NULL...释放管道...

我正在运行 Xubuntu 20.04、内核版本 5.4.0-52-generic、v4l2loopback-dkms v.0.12.3-1ubuntu0.1 和 v4l2loopback-utils。

我的目标是让桌面 Node.js 服务器使用一个设备,该服务器将使用xdg-open(因此需要 Chrome 和 Firefox)打开一个 Web 应用程序,该应用程序将输出可被视频使用的已处理视频流聊天应用程序,例如 Zoom 或 Jitsi。

任何帮助将不胜感激。

ffmpeg gstreamer v4l2 v4l2loopback

5
推荐指数
2
解决办法
5919
查看次数

使用v4l2在c++中捕获图片,解释过程

我一直在努力编写 C++ 代码来从网络摄像头捕获图片。我成功地做到了,但我想对我所采取的过程进行一些澄清。

所以我的代码可以用6个步骤来描述,我将它们和我的问题一起写在这里: 一、步骤:初始化设备并设置图像格式。

    const char* dev_name = "/dev/video0";
    int width=320;
    int height=240;
    int fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
    struct v4l2_format format = {0};
    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    format.fmt.pix.width = width;
    format.fmt.pix.height = height;
    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//V4L2_PIX_FMT_YUYV //V4L2_PIX_FMT_RGB24
    format.fmt.pix.field = V4L2_FIELD_NONE; //V4L2_FIELD_NONE
    xioctl(fd, VIDIOC_S_FMT, &format);
Run Code Online (Sandbox Code Playgroud)

二. 步骤:请求缓冲区。

    struct v4l2_requestbuffers req = {0};
    req.count = 2;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
    xioctl(fd, VIDIOC_REQBUFS, &req);
Run Code Online (Sandbox Code Playgroud)
  1. 问题:这个“请求缓冲区”到底是做什么的?
  2. 问题:这个缓冲区实际上位于相机内部还是我的电脑上?

三.步骤:查询缓冲区和映射。

    struct v4l2_buffer buf;
    buffer* buffers;
    unsigned int i;
    buffers = (buffer*) …
Run Code Online (Sandbox Code Playgroud)

c++ image-capture v4l2

5
推荐指数
0
解决办法
1530
查看次数