前言

OpenCV(开源的计算机视觉库)是基于BSD协议,因此它可免费用于学术和商业用途。其提供C++,C,Python和Java接口,支持Windows,Linux,Mac OS,iOS和Android。OpenCV致力于高效运算和即时应用开发。因其是用优化的C/C++编写的,故其可以充分利用多核处理优势。并且还启用了OpenSL,它可以利用底层异构计算平台的硬件加速。广泛运用在世界各地,OpenCV拥有超过4.7万人的用户社区和超过1400万的下载次数。从互动艺术、矿山检查、网络地图到先进的机器人技术都有OpenCV的身影。


一、Opencv的功能

  • 人机互动

  • 物体识别

  • 图像分割

  • 人脸识别

  • 动作识别

  • 运动跟踪

  • 运动分析

  • 机器视觉

  • 结构分析

  • 汽车安全驾驶

二、安装Opencv

1.下载 OpenCV 3.4.11 数据包

国外官网下载地址:https://github.com/opencv/opencv/releases,不推荐在国外网址上下载,巨慢!!!!

国内快速下载地址:https://www.bzblog.online/wordpress/index.php/2020/03/09/opencvdownload/

2.解压安装包

创建一个名为Opencv的文件夹

 mkdir opencv

将压缩包解压到opencv文件夹(指定一个文件夹)

unzip opencv-3.4.11.zip -d opencv

3.安装cmake和依赖库

  • 进入opencv
cd opencv-3.4.11
 sudo apt-get install cmake  

注意:如果提醒需要apt-get update,那就先sudo su进入root权限,再sudo apt-get update

  • 配置依赖库
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev  

执行后出现问题请添加图片描述
查阅相关资料后,解决问题

OpenCV安装libjasper-dev依赖包错误

解决方法:

sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt install libjasper1 libjasper-dev

再次输入

sudo apt install libjasper1 libjasper-dev

出现以下界面,问题解决

在这里插入图片描述

再次输入

sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev  

耐心等待几分钟


三、配置编译环境

1.创建编译文件夹

  • 创建build文件夹
   mkdir build
  • 进入build文件夹
   cd build
  • 使用cmake编译参数
 cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
  • 生成编译文件
    请添加图片描述

2.使用make创建编译

:单线程编译:sudo make ,这会等待比较长的时间,如果你想更快编译完,可以使用命令:sudo make -j4 ,而 -j4 表示使用 4 个线程进行编译。

	sudo make -j4

在这里插入图片描述
等等,经过漫长的等待后,怎么又出错了?
请添加图片描述
一开始一脸懵逼,仅使用这些关键词查找出问题的原因,看到一些答案说往上翻,可以看到红字,果不其然,我所出现的错误信息如下:
请添加图片描述

c++:internal compiler error:已杀死(program cc1plus)

再次查阅资料后,发现是我内存配置不够(原来是2G),有两种方法可供参考,一是设置虚拟机内存大小(我设置为3G),二是临时使用交换分区。

如果你也遇到这个问题,可参考

C++ 错误解决 —— internal compiler error

  • 设置好内存大小后,重新输入命令
sudo make -j4
  • 等待编译成功

请添加图片描述

  • 执行命令
sudo make install

3.配置编译环境

  • 修改 opencv.conf 文件
sudo gedit /etc/ld.so.conf.d/opencv.conf

打开后的文件是空的,添加 opencv 库的安装路径:/usr/local/lib ,保存退出

在这里插入图片描述

  • 执行如下命令使得刚才的配置路径生效
 sudo ldconfig  
  • 修改 bash.bashrc 文件
 sudo gedit /etc/bash.bashrc  
  • 在bash.bashrc 文件最末尾添加
 PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
export PKG_CONFIG_PATH  

在这里插入图片描述

  • 保存退出,执行如下命令使得配置生效
 source /etc/bash.bashrc  
  • 更新一下
 sudo updatedb  

至此所有的配置都已经完成。

不放心的话可以查看一下opencv版本信息

pkg-config --modversion opencv

在这里插入图片描述
终于安装成功了!!!

四、Opencv使用例程

1.图片处理

  • 在opencv-3.4.1下新建文件夹mytest
   mkdir mytest
  • 创建test.cpp 文件
gedit test.cpp

将下面的代码复制粘贴进去

test.cpp代码

#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
	CvPoint center;
    double scale = -3; 

	IplImage* image = cvLoadImage("lena.jpg");
	argc == 2? cvLoadImage(argv[1]) : 0;
	
	cvShowImage("Image", image);
	
	
	if (!image) return -1; 	center = cvPoint(image->width / 2, image->height / 2);
	for (int i = 0;i<image->height;i++)
		for (int j = 0;j<image->width;j++) {
			double dx = (double)(j - center.x) / center.x;
			double dy = (double)(i - center.y) / center.y;
			double weight = exp((dx*dx + dy*dy)*scale);
			uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
			ptr[0] = cvRound(ptr[0] * weight);
			ptr[1] = cvRound(ptr[1] * weight);
			ptr[2] = cvRound(ptr[2] * weight);
		}

	Mat src;Mat dst;
	src = cvarrToMat(image);
	cv::imwrite("test.png", src);

    cvNamedWindow("test",1);  	imshow("test", src);
	 cvWaitKey();
	 return 0;
}
  • 保存退出,编译
gcc test.cpp -o test `pkg-config --cflags --libs opencv`

gcc编译器:gcc + 文件名 + -o + 输出文件流名称 +` 支持包

其中pkg-config是一个linux下的命令,用于获得某一个库/模块的所有编译相关的信息(包括头文件和库的所有信息)

—cflags 是用来指定程序在编译时所需要头文件所在的目录

—libs则是指定程序在链接时所需要的动态链接库的目录

请添加图片描述
无法添加符号,这是怎么回事呢?

在C语言的项目中,makefile使用的是gcc来编译和链接,因此怀疑是C与C++链接时的兼容问题,于是在Cpp项目中改用g++,成功!!

g++ test.cpp -o test `pkg-config --cflags --libs opencv`
  • 生成可执行文件test

注意:在这里图片的名字要放在与创建的cpp文件同一个文件中,便于系统查找;图片的命名方式应与代码中的命名一致,我这里命名为lena.jpg

IplImage* image = cvLoadImage("lena.jpg");
  • 执行命令
./test

效果如下

在这里插入图片描述

2.视频处理

1.虚拟机获取摄像头权限

  • 使用快捷键 Win + r ,输入 services.msc ,并回车

在这里插入图片描述

  • 确保 VMware USB Arbitration Service正在运行

在这里插入图片描述

  • 打开虚拟机-设置

在这里插入图片描述

  • 选择 “ USB控制器 ” ,将 “ USB兼容性 ” 设置为 “ USB 3.0 ”
    在这里插入图片描述

若选项中没有USB控制器,可在硬件选项中添加后执行上一步操作
在这里插入图片描述

  • 选择 虚拟机 - 可移动设备 – IMC Networks ov9734_azureeave_camera连接

注意:每个人的设备名称可能不一样

在这里插入图片描述

在这里插入图片描述

  • 虚拟机右下角摄像头图标若有个小绿点,则连接成功
    在这里插入图片描述

2.播放视频

  • 在mytest文件中创建一个 test1.cpp 文件
   gedit test1.cpp
  • 编写代码
    test1.cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
	//从man.mp4中读取视频
	VideoCapture capture("man.mp4");
	//从摄像头中读取视频
	//VideoCapture capture(0);
	//循环显示每一帧
	while(1){
		Mat frame;//定义一个Mat变量,用于存储每一帧的图像
		capture >> frame;//读取当前帧
		if(frame.empty())//播放完毕,退出
			break;
		imshow("读取视频帧",frame);//显示当前帧
		waitKey(25);//延时25ms
	}
	system("pause");
	return 0;
}

代码分析:
1)

C++: VideoCapture::VideoCapture();
C++: VideoCapture::VideoCapture(const string& filename);
C++: VideoCapture::VideoCapture(int device);

传入对应的参数,可以直接打开视频文件或者要调用的摄像头
参数: filename –> 打开的视频文件名
参数:device –> 打开的视频捕获设备id ,如果只有一个摄像头可以填0,表示打开默认的摄像头

VideoCapture capture("man.mp4")

表示从一个名为man的mp4类型文件中读取视频内容

2)

Mat本质上是由两个数据部分组成的类: (包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等) 的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。

简单来说,就是包含一张图片所有强度值的像素点矩阵。

OpenCV Mat类详解和用法

3)waitKey()这个函数是在一个给定的时间内(单位ms)等待用户按键触发;
如果用户没有按下键,返回值为-1,并关闭当前显示的窗口;
如果用户按下键,则返回对于按键的ASCII码值,并关闭当前显示的窗口;

waitKey()与waitKey(0),都代表无限等待,程序会无限制的等待用户的按键(适用于图像显示)

waitKey(25);//延时25ms

每25ms刷新一次,即1秒40帧

  • 准备一个小视频,命名为与代码中文件名相同的 man.mp4

在这里插入图片描述

  • 编译 test1.cpp 文件
 g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv`
  • 运行效果

在这里插入图片描述
在这里插入图片描述

  • 小结
    a.当删除waitKey()延时函数时,再次编译,不能正常运行(猜测:此时cpu执行速度很快,读取和显示一帧图像只需要几us,而显示器(一般是以ms刷新图片)不能以如此高的速率显示,两者可能会出现冲突,故函数中一个存在延时函数)
    b.当设置waitKey()或waitKey(0)时,不动态显示视频,只显示某一张图片,按任意键显示下一帧图片(需要手动按键)
    c.使用ESC键退出(而不是Ctrl+C 强制中断程序)
    只需在程序中稍微修改下即可
    在这里插入图片描述

3.录制视频

  • 创建test2.cpp 文件
gedit test2.cpp
  • 编写代码
    test2.cpp
 /*********************************************************************
打开电脑摄像头,空格控制视频录制,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;

int main()
{
	//打开电脑摄像头
	VideoCapture cap(0);
	if (!cap.isOpened())
	{
		cout << "error" << endl;
		waitKey(0);
		return 0;
	}

	//获得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();
	return 0;
}
  • 编译文件
 g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
  • 运行程序
./test2

在这里插入图片描述

至此,OpenCV的安装和使用就简单介绍到这了,更多其他的功能可参考

OpenCV教程:超详细的OpenCV入门教程,值得收藏!

总结

在ubuntu下安装Opencv ,我遇到了很多小问题,不过庆幸的是,很多问题都可以在网上找到答案,也参考了很多大佬的文章,安装步骤等,在这学习过程中,我遇到了我一些小问题,有一点心得体会,于是参考下面两篇文章写了自己的关于Opencv 安装与使用步骤,感谢!!!
此外,在安装过程中,遇到问题很正常,只要大家耐心点,基本上出现的问题都可以找到解决办法的。

来源:

Windows10&Ubantu16.04&树莓派3B+安装opencv教程
Ubuntu18.04下OpenCV3.4.11的安装及使用示例

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐