opencv+ffmpeg环境(ubuntu)搭建全面详解

news/2024/3/29 14:46:31/文章来源:https://blog.csdn.net/Damon_Sandy/article/details/131995799

一.先讲讲opencv和ffmpeg之间的关系

1.1它们之间的联系

我们知道opencv主要是用来做图像处理的,但也包含视频解码的功能,而在视频解码部分的功能opencv是使用了ffmpeg。所以它们都是可以处理图像和视频的编解码,我个人感觉两个的侧重点不一样。

1.2它们之间的区别

这就要提上面我所说的它们的侧重点是不一样。

OpenCV专注处理图像,以及图像相关的处理应用,不严谨地可以认为是PhotoShop。Opencv主要做一些识别 跟踪机器视觉应用。

FFmpeg专注处理视频、音频的编解码、转换等,不严谨地可以认为是格式工厂和PotPlayer的结合体。主要应用是编解码,各种格式转换。

二.opencv和ffmpeg版本匹配

在搭建环境之前,我着重强调下两者版本匹配的问题,因为在我本人搭建环境的时候由于版本不匹配问题踩了太多的坑,怕了。所以一开始把这些干扰因素处理好,后面可以省很多事。

2.1如果版本不匹配可能会出哪些问题呢?

会在编译opencv的时候出现各种识别不到某些定义的错误,导致编译不过。

具体有:

2.1.1问题一

error: ‘CODEC_ID_H264’ was not declared in this scope

{ CODEC_ID_H264, MKTAG('H', '2', '6', '4') }

网友给的就解决方法是,编译的时候不开启ffmpeg的编译:

-D WITH_FFMPEG=OFF 

我试过,可以编译通过,但同时也如同自断一臂,给使用ffmpeg功能(视频处理类)带来巨大麻烦,或者干脆是用不了。因此我认为,最好的办法还是,版本匹配,完美编译,完美使用,这才用的安心,根本之道。

2.1.2问题二

error: 'CODEC_FLAG_GLOBAL_HEADER' was not declared in this scope

这种解决办法是,补充添加未定义的宏,这个如果你了解不深刻里面的原理机制,一般人想不到,也只有是大佬才能理解并找到的方法。

总之基本上出问题的都是ffmpeg和opencv版本匹配问题,为啥我们不一开始就做好呢,是吧。

2.2如何知道ffmpeg和opencv的匹配的版本

为了解决这个问题,本人也是走了一大圈,才整清楚,可能最终说起来也就几句话的事,但过程是非常曲折的,不过正是经历了这种过程,才更加深刻吧,也同时也锻炼了下自己的耐心,加强了一点专研的精神,也不错哈!下面进入主题!

根据网友提供的方法进入opencv源码目录

按理说这里面应该会有一个叫ffmpeg_version.cmake的文件,里面会列出opencv相对应的ffmpeg版本号,类似下图:

那些带数字的就是某个版本的ffmpeg下,各个组件对应的版本,我们到ffmpeg官网去FFmpeg下载对应的版本源码即可。

上图只是为了说明问题,并没有去专门匹配版本号哈。

现在问题是,我的文件下没有ffmpeg_version.cmake啊,当时也是一脸懵。没办法,我就打开ffmpeg.cmake看看,是否能发现什么线索。

看到里面的内容,有几条线索,图片上已经标注出来了,这里总结下:

1.可以看到opencv需要的ffmpeg版本号对应的tag标签,以及commit id号;

2.ffmpeg.cmake其实是从上述网址***raw.git***上下载下来的;

为什么我的电脑上没有下载下来,一波查询,发现是访问不了该网址,网友也支招,在host文件加入ip什么的。我的办法是用github.com替代,其实是一样的。

进入另外的链接:

GitHub - opencv/opencv_3rdparty: OpenCV - 3rdparty

点击进去

你会发现opencv的commit id也匹配上了。

这样就找到了。关于版本匹配就讲这么多,当了解了整个过程是不是简单许多了,但如果不是自己一步一步摸索出来的,你是体会不到那种,遇到问题的焦躁以及解决完问题豁然开朗的感觉。

接下来就是分别下载ffmpeg和opencv的源码了,ffmpeg官网链接上面提供了,Releases - OpenCV是opencv的源码下载链接,自己选好版本,切记它们之间的版本匹配,要不我上面唠叨那么多是为了啥,然后编译安装,咱们继续往下走。

三.ffmpeg的安装流程

安装流程

这里建议先安装ffpmeg再安装opencv,因为安装opencv会用到ffmpeg。

先解压ffmpeg源码,然后进入到源码目录,输入如下指令:

这里说下,输入指令前先对支持库的安装

sudo apt-get install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev

再是参数配置指令输入

./configure --disable-x86asm --enable-shared --prefix=/usr/local/ffmpeg

参数含义是把ffmpeg安装到/usr/local/ffmpeg目录下,完了之后再输入

make
中间编译的时间会有点长,依电脑的性能而定
sudo make install

所有走完之后,会在/usr/local目录下看到ffmpeg文件夹,如下:

ffmpeg的工具和动态库都在里面了,为了编译时能找到ffmpeg的动态库,还要做如下处理:

创建文件ffmpeg.conf
sudo vi /etc/ld.so.conf.d/ffmpeg.conf
输入如下内容(ffmpeg动态库的路径)
/usr/local/ffmpeg/lib
最后使能生效
sudo ldconfig

看到下面内容说明安装成功

可以测试使用ffplayg工具播放一段视频

/usr/local/ffmpeg/bin/ffplay   **/**/***.mp4 (视频文件目录)

当然我们可以将ffmpeg的bin添加到全局变量,这样可以随时调用,不用加上绝对地址,编辑 profile 文件(sudo vi /etc/profile)在文件末尾添加:

export FFMPEG_HOME=/usr/local/ffmpeg 
export PATH=$FFMPEG_HOME/bin:$PATH

ffmpeg的安装到此结束,接下来是opencv的安装,继续往下走!

四.opencv的安装流程

安装流程

同样,将opencv的压缩包解压,进入源码目录,创建一个pc_build(如果以后要使用交叉编译,就换一个arm_build,扯远了)文件夹:

这里我是使用cmake图形化编译的,先安装一个cmake工具:

sudo apt-get install cmake cmake-qt-gui cmake-curses-gui

然后在pc_build目录下执行

cmake-gui

出现界面

这里仅演示ubuntu环境,不说交叉编译的

点击finish,然后再点击configure,配置一些参数,如下图

出现下图框出的版本信息,说明识别到了ffmpeg,如果没识别到怎么办呢?留个悬念后面讲。

最后点击generate。

小提示:

cmake过程中如果遇到卡住的情况,缺少文件需要下载,却一直下载不下来的情况

如:opencv源码安装文件下载问题:ippicv_2017u3_lnx, face_landmark_model.dat, tiny-dnn

配置:打开${opencv_folder}/3rdparty/ippicv/ippicv.cmake,
第47行  "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/",
改成:"file://${path}",比如我的就是"file:///home/downloads/"

下载地址:https://github.com/opencv/opencv_3rdparty/tree/ippicv/

按照自己缺少的版本下载,下载慢的话可以把链接拷贝到迅雷里面下载。

开始编译

回到命令界面,先不要急着输入 make。首先在源码目录 3rdparty/protobuf/src/google/protobuf/stubs/common.cc 这个文件下第 33 行添加#define HAVE_PTHREAD 宏定义才可以编译的过。具体原因是 HAVE_PTHREAD 宏定义了 pthread 库。

cd ..
// 返回 opencv 源码顶层目录
vi 3rdparty/protobuf/src/google/protobuf/stubs/common.cc

再进入pc_build目录输入指令

make -j 16
漫长的等待编译编译完之后,安装
sudo make install

所有成功之后会在/usr/local目录下生成相应的文件

里面包含头文件和动态库

同样为了找到opencv的动态库做如下处理

创建文件opencv.conf
sudo vi /etc/ld.so.conf.d/opencv.conf
输入如下内容(ffmpeg动态库的路径)
/usr/local/lib
最后使能生效
sudo ldconfig

到此opencv编译安装完成!

前面挖的坑

前面提到一个坑,是在cmake的时候没有出现ffmpeg的版本怎么办,我的做法是先编译,不管,编译通过之后,将ffmpeg的pkgconfig里面的所有pc文件复到/usr/local/lib/pkgconfig里面,这文件里面是opencv的pc文件。

sudo cp /usr/local/ffmpeg/lib/pkgconfig/*.pc   /usr/local/lib/pkgconfig

然后按上面的操作在重新编译一次opencv,是不是有点崩溃,没办法。

当然我也想了一些操作,有网友说安装完ffmpeg后做如下操作,再去编译opencv

sudo vi /etc/profile
添加
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig
让环境变量生效
source /etc/profile

我这么处理了,貌似没用,也不知道怎么回事,有知道的网友,还请麻烦留言告知下。

到这里ffmpeg和opencv都安装好了,是不是按捺不住内心的激动,跃跃欲试。接下来走几个小栗子,磨磨刀,哈哈哈。

五.实践操作

是骡子是马拉出来溜溜,前面做了这么多就是为了学习和实践操作,接下来就写几个小程序跑一跑功能。

5.1显示一张图片

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>using namespace std;
using namespace cv;int main(int argc,char** argv)
{Mat image = imread("11.png", 1 );//加载cv::namedWindow("picture",CV_WINDOW_AUTOSIZE);cv::imshow("picture", image);//显示图片waitKey(5000);//等待return 0;
}

5.2播放一段视频

#include<opencv2/opencv.hpp>
using namespace cv;int main()
{//从摄像头读取视频VideoCapture capture("video.mp4");//循环显示每一帧while (1){Mat frame;//定义一个Mat变量,用于存储每一帧的图像capture >> frame;//读取当前帧imshow("读取视频帧", frame);//显示当前帧waitKey(30);//延时30ms}system("pause");return 0;
}

5.3使用笔记本内置的摄像头,拍摄一段视频并保存

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>using namespace std;
using namespace cv;int main(int argc,char** argv)
{
//打开电脑摄像头VideoCapture capture(0);if(!capture.isOpened()){cout<<"error"<<endl;waitKey(0);return 0;}//获得分辨率int w = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH));int h = static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT));cout<<"w="<<w<<endl;cout<<"h="<<h<<endl;Size videoSize(w,h);VideoWriter writer;writer.open("video.mp4",CV_FOURCC('M','J','P','G'),25,videoSize);if(!writer.isOpened()){cout<<"fail"<<endl;return -1;}Mat frame;int key;char startorstop=1;char flag=0;while(1){capture >> frame;if(key == 32){//按下空格开始录制、暂停录制   可以来回切换startorstop = 1-startorstop;if(startorstop == 0){flag = 1;}}if(key == 27){//按下ESC退出整个程序,保存视频文件到磁盘cout << "exit" << endl;break;}if(startorstop == 0 && flag == 1){writer << frame;cout << "recording" << endl;}else if(startorstop == 1){flag = 0;cout << "end recording" << endl;}imshow("picture",frame);key=waitKey(100);cout<<"key="<<key<<endl;}capture.release();writer.release();destroyAllWindows();return 0;
}

编译脚本

g++ test.cpp -o test -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs

好了,到这里就告一段落了,一路走下来感觉要踩的坑我绝大部分都踩了一遍,不容易啊!所以后面的路,尽情发挥你的创造力吧!

如存在有误之处,还请广大网友指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_337118.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot项目部署(前后端分离、Linux部署项目)

一、架构 部署环境说明&#xff1a; 192.168.122.100(服务器A)&#xff1a; Nginx&#xff1a;部署前端项目、配置反向代理 Mysql&#xff1a;主从复制结构中的主库 192.168.122.131 (服务器B)&#xff1a; jdk: 运行Java项目 git:版本控制工具 (从gitee中拉取源码) maven:…

数据结构:快速的Redis有哪些慢操作?

redis 为什么要这莫快&#xff1f;一个就是他是基于内存的&#xff0c;另外一个就是他是他的数据结构 说到这儿&#xff0c;你肯定会说&#xff1a;“这个我知道&#xff0c;不就是 String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、 Hash&#xff08…

【SpringCloud Alibaba】(五)服务雪崩与容错方案

在前面的文章中&#xff0c;我们实现了用户微服务、商品微服务和订单微服务之间的远程调用&#xff0c;并且实现了服务调用的负载均衡。 但是&#xff0c;现在系统中存在着一个很明显的问题&#xff1a;那就是如果系统的并发量上来后&#xff0c;系统并没有容错的能力&#xf…

Java | 继承、多态、抽象类与接口

目录 一、类的继承 二、Object类 2.1 getClass()方法 2.2 toString()方法 2.3 equals()方法 三 、对象类型的转换 3.1 向上转换 3.2 向下转型 四、使用instanceof关键字判断对象类型 五、方法的重载 六、final关键字 6.1 final变量 6.2 final方法 6.3 final类 七…

LeetCode 1857. Largest Color Value in a Directed Graph【拓扑排序,动态规划】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

【UE5】快速认识入门

目录 &#x1f31f;1. 快速安装&#x1f31f;2. 简单快捷键操作&#x1f31f;3. 切换默认的打开场景&#x1f31f;4. 虚幻引擎术语 &#x1f31f;1. 快速安装 进入Unreal Engine 5官网进行下载即可&#xff1a;UE5 &#x1f4dd;官方帮助文档 打开后在启动器里创建5.2.1引擎…

冯诺依曼体系的认识、来源、原理、组成、功能和特点

目录 一.认识冯诺依曼 二.冯诺依曼体系结构的来源 三.冯诺依曼体系结构计算机 3.1工作原理 3.2组成部件 3.3功能和特点 &#x1f381;个人主页&#xff1a;tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主 &#x1f3a5; 本文由 tq02 原创&#xff0c;首发于 CSDN&…

C++笔记之vector的resize()和clear()用法

C笔记之vector的resize()和clear()用法 code review! 文章目录 C笔记之vector的resize()和clear()用法1.resize()2.clear() 1.resize() 运行 2.clear() 运行

Jsp+Ssh+Mysql实现的简单的企业物资信息管理系统项目源码附带视频指导运行教程

由jspssh&#xff08;springstruts2mysql&#xff09;实现的企业物资信息管理系统&#xff0c;系统功能比较简单&#xff0c;实现了基本的管理员、操作员等用户管理、物品分类管理、物品管理、入库管理、出库管理、库存预警、客户管理、供应商管理等基本功能需要的可以联系我分…

怎么在线制作证件?教你一键生成证件照

无论是申请身份证、护照、驾照还是学生证&#xff0c;都需要一张清晰、规范的证件照。但是&#xff0c;为了拍摄一张完美的证件照&#xff0c;需要付出不少时间和精力。而现在&#xff0c;我们可以使用压缩图网站提供的证件照制作工具&#xff0c;轻松制作出一张清晰、规范的证…

《重构的时机和方法》——让你的代码更健壮、更易维护

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

FFmpeg aresample_swr_opts的解析

ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…

【学会动态规划】打家劫舍 II(12)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

P3818 小A和uim之大逃离 II

题目 思路 一眼bfs 好像需要记录的东西有点多啊&#xff0c;那就交给数组吧 s t i j 0 / 1 st_{ij0/1} stij0/1​表示用/没用特殊步走到(i,j)的步数&#xff0c;然后套bfs模板即可 代码 #include<bits/stdc.h> using namespace std; const int N1005; int n,m,d,r,st…

使用Kmeans算法完成聚类任务

聚类任务 聚类任务是一种无监督学习任务&#xff0c;其目的是将一组数据点划分成若干个类别或簇&#xff0c;使得同一个簇内的数据点之间的相似度尽可能高&#xff0c;而不同簇之间的相似度尽可能低。聚类算法可以帮助我们发现数据中的内在结构和模式&#xff0c;发现异常点和离…

Pycharm debug程序,跳转至指定循环条件/循环次数

在断点出右键&#xff0c;然后设置条件 示例 for i in range(1,100):a i 1b i 2print(a, b, i) 注意&#xff1a; 1、你应该debug断点在循环后的位置而不是循环上的位置&#xff0c;然后你就可以设置你的条件进入到指定的循环上了 2、设置条件&#xff0c;要使用等于符号…

系统集成|第七章(笔记)

目录 第七章 范围管理7.1 项目范围管理概念7.2 主要过程7.2.1 规划范围管理7.2.2 收集需求7.2.3 定义范围7.2.4 创建工作分解结构 - WBS7.2.5 范围确认7.2.6 范围控制 上篇&#xff1a;第六章、整体管理 第七章 范围管理 7.1 项目范围管理概念 概述&#xff1a;项目范围管理就…

【深度学习Week3】ResNet+ResNeXt

ResNetResNeXt 一、ResNetⅠ.视频学习Ⅱ.论文阅读 二、ResNeXtⅠ.视频学习Ⅱ.论文阅读 三、猫狗大战Lenet网络Resnet网络 四、思考题 一、ResNet Ⅰ.视频学习 ResNet在2015年由微软实验室提出&#xff0c;该网络的亮点&#xff1a; 1.超深的网络结构&#xff08;突破1000层&…

C#之泛型

目录 一、概述 二、C#中的泛型 继续栈的示例 三、泛型类 &#xff08;一&#xff09;声明泛型类 &#xff08;二&#xff09;创建构造类型 &#xff08;三&#xff09;创建变量和实例 &#xff08;四&#xff09;比较泛型和非泛型栈 四、类型参数的约束 &#xff08;一…

golangd\pycharm-ai免费代码助手安装使用gpt4-免费使用--[推荐]

golangd-ai免费代码助手安装使用,pycharm可以使用&#xff0c;估计只要是xx的ide都是可以使用这个插件 目前GPT4以及gpt的大规模使用&#xff0c;如何快速掌握以及在ide中快速使用的办法&#xff0c;今天安装一款golangd编辑器的插件已经使用 一、安装以及使用 1.在golangd中…