WHCSRL 技术网

Ubuntu 18下OpenCV3.4的安装与使用示例

Ubuntu 18下OpenCV3.4的安装与使用示例

安装环境:

VirtualBox虚拟机Ubuntu 18.04系统
OpenCV版本:3.4.14
本机环境:Windows 10

一、认识 OpenCV

开源计算机视觉(OpenCV)是一个主要针对实时计算机视觉的编程函数库。
OpenCV的应用领域包括:

  • 2D和3D功能工具包
  • 运动估计
  • 面部识别系统
  • 手势识别
  • 人机交互
  • 移动机器人
  • 动作理解
  • 物体识别
  • 分割和识别
  • 实体影像立体视觉:来自两个摄像机的深度感知
  • 运动中的结构(SFM)
  • 运动跟踪
  • 增强现实

为了支持上述一些领域,OpenCV包括一个统计机器学习库,其中包含:

  • 提升(Boosting)
  • 决策树学习
  • 梯度提升树
  • 期望最大化算法
  • k最近邻算法
  • 朴素贝叶斯分类器
  • 人工神经网络
  • 随机森林
  • 支持向量机(SVM)
  • 深层神经网络(DNN)

二、安装 OpenCV

1. 下载 OpenCV 3.4.11 数据包

OpenCV下载地址:

官网:https://opencv.org/

Github:https://github.com/opencv/opencv/releases

国内:https://www.bzblog.online/wordpress/index.php/2020/03/09/opencvdownload/

推荐选择国内下载地址,有条件的可以选择国外原装进口。

本篇文章采用国内镜像源下载,在虚拟机中打开游览器(这里用的火狐),输入网址,选择opencv3.4最新版本进行下载:

请添加图片描述
选择.zip
请添加图片描述


Ubuntu中游览器的默认下载位置是名为“下载”的文件夹,如果不能通过cd进入可以选择右键文件夹选择终端打开来解决

请添加图片描述

2. 解压安装

安装之前,为了避免麻烦,首先我们输入sudo su进入root模式。

桌面版的虚拟机可以直接通过鼠标操作:右键压缩包👉提取到此处,或者在终端输入以下指令:

unzip opencv-3.4.14.zip
  • 1

检查是否安装了cmake,因为我们需要使用cmake来安装opencv,所以可以在终端输入cmake来检查。如果提示没有找到,则需要安装cmake。

请添加图片描述


安装cmake:

apt-get install cmake
  • 1

请添加图片描述


如果提醒需要apt-get update,那就在终端输入下面的命令更新

sudo apt-get update
  • 1

安装完cmake之后需要安装依赖包,在终端输入以下命令来安装依赖包

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

结果出现了以下问题:无法定位软件包 xxxx

在这里插入图片描述


百度参考了 无法定位软件包libjasper-dev的解决办法 后在终端输入以下命令:

sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt upgrade
sudo apt install libjasper1 libjasper-dev
  • 1
  • 2
  • 3
  • 4

若有提示输入[Y/n]一律Y过去。

在这里插入图片描述


安装完cmake之后执行命令,创建编译文件夹,进入build文件夹

mkdir build
cd build
  • 1
  • 2

使用cmake编译参数

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
  • 1

使用make创建编译:仍然在build文件夹下进行,在终端输入

sudo make -j4
  • 1

在这里插入图片描述

不加 -j4 智障系统会使用单线程编译,很浪费时间!而博主这里尽管通过 -j4使用四线程编译也等了二十多分钟

编译好后执行如下命令安装OpenCV

sudo make install
  • 1

在这里插入图片描述

3. 配置环境

安装好opencv后,接下来就需要配置一些OpenCV的编译环境。首先将OpenCV的库添加到路径,调用OpenCV时使用库函数时系统可以找到库函数的位置,在终端输入下面的命令

sudo gedit /etc/ld.so.conf.d/opencv.conf
  • 1

或者选择其他的文本编辑软件如nano、vi/vim等打开,编辑系统文件需要添加sudo选项。执行此命令后打开的文件

可能是空白文件,在文件中添加以下内容

/usr/local/lib
  • 1

在这里插入图片描述
点击右上角保存,然后关闭文件。

退出之后会发现有警告信息,不要担心,这是正常情况
在这里插入图片描述

更新系统共享链接库

sudo ldconfig
  • 1

配置bash,修改bash.bashrc文件

sudo gedit /etc/bash.bashrc  
  • 1

打开文件后,在最末尾添加下面的文字

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
export PKG_CONFIG_PATH  
  • 1
  • 2

点击保存后关闭文本编辑器

在这里插入图片描述

然后执行下面的命令使配置生效和更新

source /etc/bash.bashrc
sudo updatedb
  • 1
  • 2

所有配置已经完成。之后可以顺便查看一下OpenCV的版本信息

pkg-config --modversion opencv
  • 1

在这里插入图片描述
版本无误,开始后面的步骤。

三、编译图片

1. 创建文件

首先创建test.cpp并编辑它

gedit test.cpp
  • 1

输入以下代码

#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("temp.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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述

上面的代码里面我们用到了mat数据类型,在OpenCV的官网上面可以查询到相关资料

官网Mat解释:https://docs.opencv.org/3.4.14/d3/d63/classcv_1_1Mat.html

图图

2. 编译

OpenCV的矩阵是用Mat这个对象来存储的,并且提供了一些函数操作矩阵的属性。关于Mat数据类型的更多知识,请在OpenCV官网或者在CSDN上搜索。
接下来编译文件,执行下面的命令(注意:后面的符号`是英文输入状态下键盘左上角的~)

gcc test.cpp -o test `pkg-config --cflags --libs opencv`
  • 1

如果出现以下错误,则需要用C++编译器编译接口模块。
在这里插入图片描述

解决方法是打开相关的so下的build.sh(每个产生so目录下,都写了build.sh),把gcc改成g++。然后再重新编译。或者直接将输入的命令中的gcc改为g++

g++ test.cpp -o test `pkg-config --cflags --libs opencv`
  • 1

在这里插入图片描述

在同一文件夹下准备一张图片,命名为temp.jpg

在这里插入图片描述

执行编译好的可执行文件test,可以看到生成了test.png

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

四、编译视频

1. 环境配置:

如果使用虚拟机来进行本实验,那么需要让虚拟机获取摄像头的权限。因为本人使用的虚拟机是VirtualBox6,与其他的VM虚拟机获取权限的步骤有所出入。
以下步骤参考ROS与虚拟机-配置Vbox(Ubuntu)使用主机摄像头
配置Vbox(Ubuntu)使用主机摄像头

说明

  • 在虚拟机里难免要使用内置或外置的摄像头
  • 比如在做ROS By Example例子就要使用usbcam
  • 比如开发Opencv,使用摄像头捕抓图像
  • 要使用USB,就需要安装扩展Oracle_VM_VirtualBox_Extension_Pack

步骤

  1. 下载Oracle_VM_VirtualBox_Extension_Pack
    点击进入下载页面,选择对应版本,因为本人使用的6以上的版本所以这里选择6.1.0_RC1,然后下载下图所标注的任意一个拓展包。
    在这里插入图片描述
    在这里插入图片描述

  2. 安装到virtualbox, 在virtualbox管理器👉管理👉全局设定👉扩展,并在右上角的添加扩展,选择拓展包所在位置,确定。
    在这里插入图片描述

  3. 启用摄像头
    安装完成后,启动虚拟机。

在 设备 -> 摄像头 -> 启用摄像头设备(名字各有不同)
在这里插入图片描述
启用后,可以通过命令:

ls /dev/video*
  • 1

查看是否存在 camera 设备。
在这里插入图片描述

测试 camera
一般测试摄像头用到的命令是 cheese,以下是相关命令

sudo apt-get install -y //cheese安装 cheese
cheese                  //调用 cheese
cheese -d /dev/video1   //调用指定的摄像头
  • 1
  • 2
  • 3

但是在我的虚拟机测试却找不到设备,不知道原因,可能是戴尔的问题。
在这里插入图片描述
所以换一下其他方法

安装 xawtv
sudo apt-get install -y xawtv

调用 xawtv
xawtv

调用指定的摄像头
xawtv -d /dev/video1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
欸,还是不行,但这次至少没有找不到设备,经过一番搜索之后,有人给出的答案是部分笔记本电脑的摄像头无法被识别,那就是DELL的G3笔记本不够优秀了,这不能赖我。

2. 播放视频

创建一个test1.cpp文件,代码如下

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
	VideoCapture capture;
	//capture.open(0);   //打开摄像头  
	capture.open("temp.mp4");   //打开视频  
	if (!capture.isOpened())
	{
		cout << "video not open." << endl;
		return 1;
	}
	double rate = capture.get(CV_CAP_PROP_FPS);     	//获取当前视频帧率
	//当前视频帧
	Mat frame;
	//每一帧之间的延时
	int delay = 1000/ rate;      	//与视频的帧率相对应
	while (1)
	{
		if (!capture.read(frame))   //获取视频或摄像头的每一帧
		{
			cout << "no video frame" << endl;
			break;
		}
		imshow("video", frame);
		//引入延时
		//也可通过按键停止
				int k = waitKey(30);
		// 实现按键暂停和退出视频播放功能		
		if (k == 27)
			break;
		else if (k == 32)
		{
			while (waitKey(0) != 32)
				waitKey(0);
		}
	}
	//关闭视频,手动调用析构函数(非必须)
	capture.release();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

注意得在同目录下有一个叫temp.mp4的视频才行

打开效果如下,在键盘下按Esc推出,按下空格暂停/继续。

在这里插入图片描述

3. 录制视频

创建一个test2.cpp程序,代码如下

#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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

编译test2.cpp文件,在终端输入下面的命令

g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
./test2
  • 1
  • 2

运行效果如下图所示:
在这里插入图片描述

在按键上按下空格键暂停录制/开始录制,按下ESC键退出录制,录制好的视频会保存在同一目录下。
在这里插入图片描述
打开看看刚才录制的视频

在这里插入图片描述

录制成功,除了没有用到摄像头以外其他都还不错😟😟

五、总结

经过几个实验,发现OpenCV确实功能强大,(但还有些坑需要自己去填,比如这个摄像头😢)所以能在多个功能得到应用。而且OpenCV支持多种语言,还可以在Windows系统下进行视频开发

参考文章:
ROS与虚拟机-配置Vbox(Ubuntu)使用主机摄像头
ZONE画派:VirtualBox 调用摄像头
江南烟脓雨:Ubuntu 18.04下OpenCV的安装与简单应用
可乐有点好喝:Ubuntu18.04下OpenCV3.4.11的安装及使用示例

推荐阅读