Ubuntu通过OpenCV使用摄像头
一、Ubuntu上安装opencv
参考链接
链接: link.
二、一个打开摄像头显示处理视频的程序
1.代码
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
VideoCapture capture(0);
while (1)
{
Mat frame;
capture >> frame;
imshow("读取视频帧", frame);
waitKey(30);
}
system("pause");
return 0;
}
2.编译
命令
g++ test.cpp -o test `pkg-config --cflags --libs opencv
注意:此处用的是反引号
3.运行
先查看是否可以使用摄像头
lsusb 查看usb设备列表
ls /dev/video* 查看摄像头驱动安装
sudo apt-get install cheese 如果已经安装,这步可以省略
cheese 打开摄像头
如果使用cheese打开摄像头发现,摄像头能打开,但是画面却无法显示(黑屏),这个问题不解决,运行程序任然会出现问题,导致程序出现打开摄像头失败超时的问题
解决办法:
首先虚拟机上打开虚拟机(M)->设置,接着点击USB控制器,更换USB兼容性,原来是USB 2.0就更换为USB 3.0,若是USB 3.0就更换为USB 2.0。选择确定,虚拟机就重新启动,启动完成,就重新设置摄像头的连接,完成后,使用cheese看摄像头是否能够看到画面,能看到画面就表示完成了。
编译过程获得opencv头文件、链接lib库文件的路径的方法:
如果编译没有指定路径,头文件就会查看gcc的环境变量和查找系统默认的目录:/usr/include;/usr/local/include,链接lib库gcc的环境变量和查找默认路径/lib;/usr/lib;/usr/local/lib。可以之后我们就可以运行:
4.问题分析
(1)如果要求打开你硬盘上一个视频文件来播放,如何修改?
将代码中的VideoCapture capture(0);修改为VideoCapture capture("/home/ubuntu/video/test.mp4")
即将0改为需要播放的视频名称以及它所存放的路径
(2)在while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
Mat是一个矩阵,每个图像都是由无数的点构成的,即Mat是一个图像矩阵。
waitKey()函数的功能是不断刷新图像,如果没有这个就无法实现画面的实时显示,即看不到画面的变化。
(3)此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进。
增加一个判断语句,来进行关闭
#三、 打开摄像头采集图像并保存
1.代码
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
void main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return;
}
//获得cap的分辨率
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
}
2.编译
编译过程会出现图片中的报错,有这个错误也不要担心,只需要将代码中判断摄像头是否能够打开的语句删掉或者将这段语句中的return语句后面加上0就可以解决了。
//删掉这样段代码
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return;
}
//将上面的这段代码修改为下面的代码
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return 0;
}
3.运行
#四、 心得
通过本次实验,我基本掌握如何通过opencv使用摄像头,虽然过程遇到了很多困难,但都通过查阅资料解决了。