首页 > 技术知识 > 正文

nvidia tx2平台 Allied vision Alvium相机调试2

1.前言 2.修改代码 3.尝试使用gstreamer后端 4.灰度采集问题 5.分析格式设置问题 6.解决问题 1. 前言

承接上篇 https://www.ebaina.com/articles/140000012925

2. 修改代码

也许是capture没能打开 试一试:

cv::VideoCapture cap(0, cv2.CAP_V4L); if (!cap.isOpened()) { std::cout << “Failed to open camera\n”; exit(-1); } unsigned int width = (unsigned int) cap.get (cv::CAP_PROP_FRAME_WIDTH); unsigned int height = (unsigned int) cap.get (cv::CAP_PROP_FRAME_HEIGHT); double fps = cap.get (cv::CAP_PROP_FPS); std::cout << “Framing: ” << width << ” x ” << height << ” @” << fps << ” FPS (” << width*height*fps/1000000.f << ” MPixels/s)” <<std::endl; cv::Mat frame_in; if (!cap.read (frame_in)) { std::cout << “Failed to read frame from capture” << std::endl; cap.release(); exit(-3); } std::cout << “Got frame with width=” << frame_in.cols << ” and height=” << frame_in.rows << std::endl; /* You can access V4L API for reading/setting controls that are not available from videocapture */ FILE* fp = popen(“/usr/bin/v4l2-ctl -d0 –get-ctrl=gain”, “r”); if (fp == NULL) { std::cout << “Failed to run v4l2-ctl command\n”; exit(-2); } char buf[128]; if (fgets(buf, sizeof(buf), fp)) printf(“%s”, buf); pclose(fp); … cap.release();
<

当运行此代码,得到的输出

Framing: 700 x 544 @30 FPS (11.424 MPixels/s) Failed to read frame from capture

由于某些原因,不能复制帧从视频捕捉到Mat。 当运行Gstreamer时,这是有效的,不是V4L2

当运行

gst-launch-1.0 v4l2src ! video/x-raw,format=xRGB ! videoconvert ! xvimagesink sync=false

在终端中,能够看到帧

3 .尝试使用gstreamer后端 cv::VideoCapture cap(“v4l2src device=/dev/video0 ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1”, cv::CAP_GSTREAMER);

可以正常工作

为了改变相机设置,还需要使用这个吗? 可以访问V4L API来读取/设置视频捕获中不可用的控件

FILE fp = popen(“/usr/bin/v4l2-ctl -d0 –get-ctrl=gain”, “r”);* if (fp == NULL) { std::cout << “Failed to run v4l2-ctl command\n”; exit(-2); } char buf[128]; if (fgets(buf, sizeof(buf), fp)) printf(“%s”, buf); pclose(fp);

现在不能使用cap.get()或cap.set() 得到一个GSTREAMER错误 GStreamer warning: GStreamer: unhandled property

如果需要设置曝光时间,使用FILE *fp的语法会是什么样子? 另外,在流水线中,可以在灰度捕获帧吗? 这台相机可以用灰度来捕捉 所以不转换到RBG,我可以只在灰度传输数据吗?

4. 灰度采集问题

如果gstreamer管道正在使用摄像头 那么尝试从V4L API更改它将是一个糟糕的主意

可以运行给定数量的帧,从中计算新的曝光或增益, 从V4L API应用并重新运行gstreamer管道 这可能会给一些延迟之间的试验,因为管道设置 也可以像以前一样尝试使用V4L API。

可以在打开相机前尝试设置格式BGRx (V4L中的XR24)

v4l2-ctl -d /dev/video0 –set-fmt-video=width=720,height=544,pixelformat=XR24

重新运行opencv应用程序打开摄像头:

cv:VideoCapture cap(0, cv::CAP_V4L);

当尝试运行v4l2-ctl命令时,得到了这个错误

VIDIOC_S_FMT: failed: Invalid argument

有没有办法在IDE中设置这些?

5. 分析格式设置问题 v4l2src device=/dev/video0 ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1

设法通过将pixelformat更改为相应的数值来绕过VIDIOC_S_FMT问题 但是使用cv::CAP_V4L再次导致无法将视频捕获传输到Mat的问题

在使用Gstreamer时,有没有办法改变相机设置? 有没有一种方法可以在不使用视频捕捉的情况下访问相机框架? 有没有一种方法可以Mat.read(相机,IMREAD_GRAYSCALE)? 这将是最理想的

对于gstreamer管道到gray8类似于:

cv::VideoCapture cap(“v4l2src device=/dev/video0 ! video/x-raw,format=GRAY8 ! appsink drop=1”, cv::CAP_GSTREAMER);

运行此命令后,可以尝试从v4l2-ctl获取V4L格式, 并将其设置为从opencv进一步使用V4L后端

这是我用的代码

FILE* fp = popen(“/usr/bin/v4l2-ctl -d /dev/video0 –set-fmt-video=width=500,height=544,pixelformat=1”, “r”); if (fp == NULL) { std::cout << “Failed to run v4l2-ctl command\n”; exit(-2); } char buf[128]; if (fgets(buf, sizeof(buf), fp)) printf(“%s”, buf); pclose(fp); std::string pipeline = “v4l2src device=/dev/video0 ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=GRAY8 ! appsink drop=1”; cv::VideoCapture cap(pipeline,cv::CAP_GSTREAMER); if (!cap.isOpened()) { std::cout << “Failed to open camera\n”; exit(-1); } cv::Mat frame_in; if (!cap.read(frame_in)) { std::cout << “Failed to read frame from capture” << std::endl; cap.release(); exit(-3); } cv::imshow(“frame”,frame_in); cv::waitKey(); std::cout << “Got frame with width=” << frame_in.cols << ” and height=” << frame_i
<

输出总是得到帧的宽度=704和高度=544。 不反映宽度和高度我设置在v2l2-ctl

6. 解决问题

从V4L API中设置v42-ctl——list-format -ext所提供的模式来进行捕获。 只有一些驱动可能支持缩放 在大多数情况下一个传感器模式支持帧长宽比

可以使用opencv或gstreamer缩放或裁剪到500×544分辨率

运行正常

猜你喜欢