我想得到一些想法,你们中的一些人会如何解决这个问题.我有一个机器人,运行linux并使用网络摄像头(带有v4l2驱动程序)作为其传感器之一.我用gtkmm写了一个控制面板.服务器和客户端都是用C++编写的.服务器是机器人,客户端是"控制面板".图像分析发生在机器人上,我想将视频从摄像机流回控制面板有两个原因:A)有趣B)叠加图像分析结果
所以我的问题是,有什么好的方法可以将视频从网络摄像头传输到控制面板,以及优先使用机器人代码来处理它?我对编写自己的视频压缩方案并将其放入现有的网络端口感兴趣,我认为新的网络端口(专用于视频数据)是最好的.问题的第二部分是如何在gtkmm中显示视频?视频数据是异步到达的,我无法控制gtkmm中的main(),所以我觉得这很棘手.
我愿意使用像vlc,gstreamer或任何其他我不了解的通用压缩库这样的东西.
谢谢!
编辑:该机器人有一个1GHz的处理器,运行像Linux版本的桌面,但没有X11.
我正在通过USB Terratec Grabster AV350(基于em2860芯片)捕获视频。
播放音频时我没有成功。如果我使用vlc或ffplay播放捕获的视频,我只会听到3秒钟的声音,然后其余视频保持静音...
在捕获过程中,我没有任何错误。最后,它指示捕获的视频和音频的大小。
我为此使用ffmpeg命令:
ffmpeg -f alsa -ac 2 -i硬件:3 -f video4linux2 -i / dev / video0 -acodec ac3 -ab 128k -vcodec mpeg4 -b 6000k -r 25 test5.avi
日志是:
[alsa @ 0x9bcd420]Estimating duration from bitrate, this may be inaccurate
Input #0, alsa, from 'hw:3':
Duration: N/A, start: 69930.998994, bitrate: N/A
Stream #0.0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s
[video4linux2 @ 0x9bf5d30]Estimating duration from bitrate, this may be inaccurate
Input #1, video4linux2, from '/dev/video0':
Duration: …Run Code Online (Sandbox Code Playgroud) 我一直在努力使用v4l2直接在OpenCV中抓取相机图像.这工作得非常好; 通过这种方式,我可以以YUYV格式和高分辨率获取图像(了解帧速率将下降).我无法通过OpenCV实现完成这项工作.功能上它的工作效果很好,但性能可能会好得多.由于这是我第一次直接使用v4l2,它对我来说仍然有点模糊.我已经对所有相关部分进行了计时,并发现v4l2选择方法需要花费一秒多的时间.当我降低时间间隔时,select方法花费的时间更少,但是出列的时间要长得多(也就是第二次).在其他功能中,相机被初始化,因此设置正确的格式等.我知道帧速率很低,没有压缩和高分辨率,但这是极低的.
下面是捕获图像功能.我跳过了缓冲区转换为Mat(YUYV - > RGB)的代码,因为我认为它现在不相关.
有谁知道如何使v4l2捕获图像更快?也许有些部分我不应该执行每个帧抓取?
谢谢!
Mat Camera::capture_image() {
Mat returnframe(10, 10, CV_8UC3);
struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
perror("Query Buffer");
return returnframe;
}
if (-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type)) {
perror("Start Capture");
return returnframe;
}
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {0};
tv.tv_sec = 2;
int r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) …Run Code Online (Sandbox Code Playgroud) 因此,使用OpenCV对映射的帧缓冲设备(例如/ dev/fb0)hwne进行memcopy有点困惑.
例如,查看C和C++的OpenCV捕获函数之一:
C: IplImage* cvQueryFrame(CvCapture* capture)
C++: bool VideoCapture::read(Mat& image)
Run Code Online (Sandbox Code Playgroud)
看起来图像数据存储在C++的矩阵结构(MAT)和C的CvCapture黑盒结构中.有很多关于如何在网络上使用它们的例子,所以很好.
但是,我没有找到任何好的(一致的)代码片段,它们展示了如何获取存储在这些结构中的图像数据并将其复制到帧缓冲区.
有没有人知道或有这个转换所需的例子?
(Noob同时适用于Linux和OpenCV)
这是我在这里发表的第一篇文章,希望能找到一些帮助
我正在使用三星ok6410主板和ov9650 cmos相机上的嵌入式Linux
我必须捕获视频并将其保存在SD卡上
我想使用一个捕获视频的循环缓冲区,当它已满时,允许新数据覆盖旧数据.
有一个标志,当提升时,捕获持续10秒然后停止.视频保存到SD卡应该包含提升标志前10秒和提升后10秒.
我在这里阅读了v4l2 API规范官方网站上的捕获示例
http://free-electrons.com/kerneldoc/latest/video4linux/API.html
但有一点我无法理解或不知道我是否理解正确
在这个例子中,有4个帧缓冲区,每个缓冲区可以容纳一个帧.这是正确的吗?
有一个变量(frame_count)被初始化为70,这是否意味着通过完成这个程序,我将有一个包含70帧的视频?
fns(主循环)和(读框)有什么作用?我知道他们应该做什么,但无法理解书面代码,循环......等等
如何在此代码中调整fps?或者我应该在相机寄存器中写入值?
捕获视频后,我将有一个填充原始数据的缓冲区,我想压缩它或使用编解码器将其保存为MPEG,我可以更改要压缩的像素格式(例如MPEG)而不是YUYV吗?或者我该怎么做才能压缩视频?编解码器还是什么?
我可以将缓冲区中的这些原始数据写入文件.yuv吗?我找到了一些可以播放这种格式视频的软件.
是否可以使用循环缓冲区而不是线性缓冲区来保存捕获的视频?
我知道我的帖子太长了,但我是新手,找不到任何可以帮助我编写代码的教程.
提前致谢
作为V4L的新手,我决定开始使用video4linux2库,以便从C中捕捉相机中的帧(我正在使用带有Ricoh Co.相机的uvcvideo模块).我遵循了几个指南和教程,并设法获得一个正在运行的程序.我的问题主要是关于这个通常的代码行:
struct v4l2_format format = {0};
format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
// ...
Run Code Online (Sandbox Code Playgroud)
这是我设置捕获时使用的实际视频格式的地方.如您所见,在此示例中,我使用的是MJPEG(http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L390).即使这可能是一个很好的格式,我的应用程序可能需要简单的RGB格式,我估计每像素像素.出于这个原因,我尝试使用RGB格式常量,如V4L2_PIX_FMT_RGB24.现在由于某种原因...... v4l2不喜欢它.我猜这与硬件有关,但我想尽可能避免MJPEG操作.出于测试目的,我尝试使用其他常量和格式,但无论我做什么,v4l2都不断改变pixelformat字段的值:
xioctl(fd, VIDIOC_S_FMT, &format); // This call succeeds with errno != EINTR.
if(format.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24){
// My program always enters this block when not using MJPEG.
fprintf(stderr, "Format wasn't accepted by v4l2.");
exit(4);
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:有没有办法可以得到一个已接受的视频格式列表(我的意思是,我的相机/ v4l2接受),我可以从中找到除MJPEG以外的其他内容?如果你认为我必须坚持MJPEG,你会推荐我允许我操纵它的任何库,并最终在GUI框架中回退捕获吗?
我使用以下技巧测试我硬件上的所有可用格式.首先,一些shell脚本来获取所有格式的列表......
grep 'V4L2_PIX_FMT' /usr/include/linux/videodev2.h | grep define | tr '\t' ' ' | cut -d' ' -f2 | sed 's/$/,/g'
Run Code Online (Sandbox Code Playgroud)
...其输出在此C程序中使用:
int formats[] = …Run Code Online (Sandbox Code Playgroud) 我需要播放多个视频来测试视频服务器。我正在使用 lubuntu 14.04 并安装了V4l2loopback来制作设备文件( /dev/videoN )
我正在使用 mplayer 从该设备播放视频,如mplayer cam 所述
我已经对源代码进行了修改并成功播放了视频并使用 xawtv 和 flashplayer(在 Firefox 28 上)进行了查看。我曾尝试使用 webRtc 查看,但无法正常工作。
你有什么想法可以做到这一点吗?在 examples/yuv4mpeg_to_v4l2.c 中定义了一些特定的像素格式?
.....
我正在尝试使用此脚本直接访问资源来查找问题:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test rtc</title>
<script type="text/javascript" charset="utf-8">
navigator.getUserMedia =
(
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia
);
var constraints =
{
audio: true,
video:true,
video:
{
mandatory:
{
minWidth: 640,
minHeight: 360
}
}
};
if( navigator.getUserMedia )
{
navigator.getUserMedia(
// constraints
constraints ,
// successCallback
function(localMediaStream) …Run Code Online (Sandbox Code Playgroud) 在过去的4天里,我试图让gstreamer1.0与v4l2驱动程序一起使用Raspberry Pi相机,但没有成功.
我正在运行最新的Raspbian图像(从19.9.2014.),启用了raspicam.Raspicam bcm2835_v4l2驱动程序是使用modprobe命令启动并成功测试的,都使用qv4l2 gui接口(预览工作正常),并直接从设备使用dd命令:
dd if=/dev/video0 of=test.jpeg count=1 bs=11M
Run Code Online (Sandbox Code Playgroud)
Gstreamer也可以使用基本的"Hello world"命令正常工作:
gst-launch-1.0 videotestsrc ! ximagesink
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚如何使用Gstreamer从v4l2 raspicam源成功显示视频预览(使用ximagesink或autovideosink等基本接收器).
以下管道都没有工作(对不起,如果其中一些是完全废话,我是一个gstreamer新手):
将v4l2-ctl像素格式设置为H264(这就是"v4l2-ctl -V"命令返回的内容)我试过:
gst-launch-1.0 v4l2src device=/dev/video0 ! 'video/x-h264,width=640,height=480,framerate=25/1' ! h264parse ! omxh264dec ! videoconvert ! ximagesink
gst-launch-1.0 v4l2src device=/dev/video0 ! 'video/x-h264,width=640,height=480,framerate=25/1' ! h264parse ! omxh264dec ! videoconvert ! autovideosink
Run Code Online (Sandbox Code Playgroud)将v4l2-ctl像素格式设置为YU12(4:2:0,压缩YUV)我试过:
gst-launch-1.0 v4l2src device=/dev/video0 ! autovideosink
gst-launch-1.0 v4l2src device=/dev/video0 ! ximagesink
Run Code Online (Sandbox Code Playgroud)因此以上命令都不起作用,相机LED无法打开并且gstream返回:
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: …Run Code Online (Sandbox Code Playgroud) 我正在使用Ubuntu(14.04),我在尝试使用gstreamer时收到此错误.
gst-launch-1.0 v4l2src ! video/x-raw,width=640,height=480 ! x264enc ! h264parse ! rtph264pay ! udpsink host=127.0.0.1 port=5000
Run Code Online (Sandbox Code Playgroud)
我检查了gst-inspect-1.0 v4l2src
它说元素没有找到"没有这样的元素或插件'v4l2src'"
我该怎么办 ?从哪里可以获得此元素或插件.我试过树脂整个gstreamer.但我无法这样做.
背景故事:我使用的一个直播网站不够智能,无法检测我的网络摄像头(Logitech Brio,4k)的功能,而是使用默认的每秒帧数设置,即 5fps。
(答案中的完整解决方案演练)
我能想到的最佳解决方案(除了更改直播提供商之外)是使用 v4l2loopback 创建一个环回虚拟网络摄像头,我可以强制使用我想在该直播网站上使用的确切设置。
对于 brio,更高的帧率来自 mjpeg,而不是默认的 yuyv。
问题1:
我可以很容易地阅读 mjpeg,但不幸的是我的头一直撞在墙上,因为 v4l2loopback 显然只想要 yuyv。
我试过这样的事情:
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-vcodec copy \
-f v4l2 /dev/video6
Run Code Online (Sandbox Code Playgroud)
和
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-vcodec yuyv422 \ # this line changed (even tried "copy")
-f v4l2 /dev/video6
Run Code Online (Sandbox Code Playgroud)
但他们不会工作。我收到如下错误:
与 yuvj422p 等效的未知 V4L2 像素格式
和
...使用过时的像素格式,请确保您正确设置了范围...
...V4L2 输出设备仅支持单个原始视频流... …