Ubuntu上使用opencv——摄像头的相关使用

本文章使用的系统时Ubuntu 18.04 desktop

一、Ubuntu上安装opencv

安装及下载参考此链接,我就不详细说明
https://blog.csdn.net/qq_43279579/article/details/109231383

二、一个打开摄像头显示处理视频的程序

  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;
}
  1. 编译

g++ test.cpp -o test `pkg-config --cflags --libs opencv`
注意:此处用的是反引号

在这里插入图片描述

  1. 运行

在这里插入图片描述
程序出现无法打开摄像头
解决方法:
①查看摄像头标志是否高亮
在这里插入图片描述
②如果摄像头不是高亮,就点击它,选择连接
在这里插入图片描述
第一次连接可能会连接失败或没有下面这个界面弹出,如果遇到这个情况按照以下操作进行
打开此电脑(Win10)->管理->服务和应用程序->VMware USB Arbitration,重启动此服务,回到虚拟机查看就会弹出上面的界面
在这里插入图片描述
③查看是否可以使用摄像头

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. 问题分析
①如果要求打开你硬盘上一个视频文件来播放,如何修改?

将代码中的VideoCapture capture(0);修改为VideoCapture capture("/home/ubuntu/video/test.mp4")
即将0改为需要播放的视频名称以及它所存放的路径

②在while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?

Mat是一个矩阵,每个图像都是由无数的点构成的,即Mat是一个图像矩阵。
waitKey()函数的功能是不断刷新图像,如果没有这个就无法实现画面的实时显示,即看不到画面的变化。

③此代码会在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();
}

  1. 编译
    编译过程会出现图片中的报错,有这个错误也不要担心,只需要将代码中判断摄像头是否能够打开的语句删掉或者将这段语句中的return语句后面加上0就可以解决了。
//删掉这样段代码
if (!cap.isOpened())
{
	cout << "error" << endl;
	waitKey(0);
	return;
}
//将上面的这段代码修改为下面的代码
if (!cap.isOpened())
{
	cout << "error" << endl;
	waitKey(0);
	return 0;
}

在这里插入图片描述

  1. 运行

在这里插入图片描述
这个是视频采集画面的记录过程,当按下ESC按键时,视频采集画面就会关闭,采集记录过程也就结束了。(摄像头采集的画面就不展示了,就展示采集记录的过程)

四、小结

通过这个简单的摄像头采集的程序,基本能够掌握在Ubuntu下,该怎么使用opencv,怎么来完成这个过程。虽然,这个过程开始就遇到摄像头打不开的情况,但是,再查找资料后,也顺利的解决了。所以,遇到问题的小伙伴们,不要就此放弃,查找资料解决也是很快的。

五、参考资料

  1. 虚拟机Ubuntu打开摄像头失败及OpenCV打开摄像头超时的问题
  2. 程序编译运行时头文件或动态链接库的查找
  • 9
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C#中使用OpenCV打开摄像头,并在Windows窗体应用程序中展示摄像头的视频流,可以使用以下代码: 1. 引用OpenCV库,将其添加到项目引用中。 2. 在代码中创建一个`VideoCapture`对象,并指定摄像头的索引号。例如,打开默认的摄像头: ``` VideoCapture videoCapture = new VideoCapture(0); ``` 或者,指定摄像头的索引号: ``` VideoCapture videoCapture = new VideoCapture(1); ``` 3. 创建一个`PictureBox`控件,用于显示摄像头的视频流。 ``` PictureBox pictureBox = new PictureBox(); this.Controls.Add(pictureBox); ``` 4. 在每个循环迭代中,使用`VideoCapture`对象的方法获取视频帧,并将其转换为`Bitmap`对象。然后,将`Bitmap`对象显示在`PictureBox`控件中。 ``` Mat frame = new Mat(); videoCapture.Read(frame); Bitmap bitmap = new Bitmap(frame.Bitmap); pictureBox.Image = bitmap; ``` 5. 在处理完所有帧后,释放`VideoCapture`对象: ``` videoCapture.Dispose(); ``` 完整的示例代码如下: ``` VideoCapture videoCapture = new VideoCapture(0); PictureBox pictureBox = new PictureBox(); this.Controls.Add(pictureBox); while (true) { Mat frame = new Mat(); videoCapture.Read(frame); Bitmap bitmap = new Bitmap(frame.Bitmap); pictureBox.Image = bitmap; } videoCapture.Dispose(); ``` 在上面的代码中,我们使用`VideoCapture`类打开默认的摄像头,并创建一个`PictureBox`控件,用于显示摄像头的视频流。在每个循环迭代中,我们使用`Read`方法获取视频帧,并将其转换为`Bitmap`对象。由于`Bitmap`对象是.NET的图像对象,因此在将`Mat`对象转换为`Bitmap`对象时,会涉及到图像数据的复制和格式转换,可能会影响性能。最后,我们将`Bitmap`对象赋值给`PictureBox`控件的`Image`属性。 需要注意的是,在Windows窗体应用程序中,更新UI控件的操作必须在主线程中进行,否则会抛出异常。如果需要在其他线程中更新UI控件,可以使用`Invoke`方法或`BeginInvoke`方法来实现。 希望我的回答能够帮到您。如果您还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值