我正在尝试构建一个应用程序来简单地获取,保存和显示一些帧从我的相机,一个DMK 41BU02(您可以在以下链接中查阅设备的规格:数据表)
我的代码就这么简单:
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int, char**)
{
String path="~/proof.jpg";
VideoCapture cap(1); // /dev/video0 is the integrated webcam of my laptop, while /dev/video1 is the DMK41BU02 camera
cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE );
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat frame;
cap >> frame;
imwrite(path, frame);
imshow("Video", frame);
waitkey(0);
return 0;
}
代码编译和执行没有任何问题,但是当图像显示在窗口上或保存在jpg文件中时,错误就出现了,因为我得到了类似以下jpg的东西,其中图像是三倍的在框架中:
上面显示的代码的结果图像
需要注意的几个方面:
- 代码正常执行,工作时返回正常图像
- DMK41BU02相机工作正常,并返回正常图像时,与其他应用程序,如fswebcam或VLC工作。
- 相机数据表显示它与OpenCV兼容。
- 我也尝试了无限循环的代码,因为我知道第一帧抓取可以是空白的或有某种类型的错误,但问题仍然存在。我在安装相机驱动程序时遇到了一些问题,但我认为它们都解决了。
- 笔记本电脑是32位机器,安装了Ubuntu。这里可以看到
uname -a
的输出:Linux AsusPC 3.11.0-18-generic #32~precise1-Ubuntu SMP Thu Feb 20 17:54:21 UTC 2014 i686 i686 i386 GNU/Linux
我不知道如何调试这个问题,当然,我不知道错误可能在哪里。你能给我点提示吗?
非常感谢。
UPDATE:我忘记在程序开始时发布应用程序在终端中写入的奇怪输出:
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
libv4l2: error set_fmt gave us a different result then try_fmt!
HIGHGUI ERROR: libv4l unable convert to requested pixfmt
libv4l2: error set_fmt gave us a different result then try_fmt!
init done
opengl support available
我也遇到过同样的问题。问题是在openCV本身,或更多;cap_v41 .hpp(在highgui模块中)和cap_libv41 .hpp是如何实现的。
这里的问题是OpenCV显然使用了错误的视频类型或通道类型来读取数据。尝试在opencv库中使用不同的类型(yuyv变体等)。
由于一些神奇的原因,cap_v4l.hpp是opencv实际使用的代码,而cap_lib4l中的代码没有使用,但似乎支持更多的视频格式(它可以切换,我不确定)。
切换这些文件并重新编译opencv确实改善了我的东西。
由于在调用cap>>frame之后,您有三个通道(type=16),因此您的捕获不知道您的相机是单色的。请使用抓取-检索对,因为检索指定了通道数。
bool VideoCapture::grab()
bool VideoCapture::retrieve(Mat& image, int channel=0)
下面是示例代码,还显示了如何设置相机参数。你也可以尝试设置一些明确声明单色模式的相机参数。如果一切都失败了,你可以用
从你的三组图片中剪切出一张Rect rect(0, 0, frame.cols/3, frame.rows);
Mat true_img = frame(rect).clone();
然而,我有点喜欢你的情况。你有一个自然的帧队列,可以通过观察连续三帧发生的情况来分析运动和可能的结构。