写点什么

基于 OpenCV+QT 开发超实用的视频编辑器

用户头像
轻口味
关注
发布于: 刚刚
基于OpenCV+QT开发超实用的视频编辑器

1. 背景

在生活工作当中,很多时候我们都有裁剪、水印、旋转等视频编辑的需求。作为一个程序员,这些需求我们常常用 ffmpeg 命令工具搞定。但是 ffmpeg 命令工具可见性和可操作性差。


现在随着深度学习和人工智能热门,大量的技术涌现,但 opencv 作为老牌的图像视频库,一直是在大量的生产环境(包括嵌入式设备)中应用,不管你用什么深度学习的平台,opencv 都是作为图像图像领域及佳的选择,可以很方便的与第三方深度学习框架结合 ,提供基础算法支持。


而用过或者学习过 QT 的同学们都知道这是 c++程序员必须学习的技能,包括现在热门的 Python 也是在大量的应用 QT 来做界面,QT 的设计及其精美,他的信号槽机制很好的将界面与业务隔离开来,并且界面可以使用类似 CSS 的设置做得很炫,不会像 MFC 一样自动生成的代码和你手写的代码融合在一起,而且 QT 还有一项跨平台能力(包括 Windows、Linux、Mac、iphone,Android 等平台)。


今天我们基于 OpenCV+QT 开发一款带 UI 界面的视频编辑工具。在满足我们功能的基础上,充分了解和学期 opencv 及 QT 技术。

2. 功能介绍

编辑工具的功能主要包含:


  1. 视频画面添加水印;

  2. 视频画面亮度调整;

  3. 视频画面对比度调整;

  4. 视频画面旋转;

  5. 视频画面镜像;

  6. 视频尺寸调整;

  7. 视频图像模糊;

  8. 两路视频融合。


编辑工具操作界面如下图所示:



3. OpenCV 实战

3.1 OpenCV 环境搭建

今天我们用的是 3.4 版本,基于 Mac 环境搭建。下载源码后执行如下命令编译:


git clone https://github.com/opencv/opencv.gitcd opencv mkdir buildcd buildcmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local/opencv3 -D BUILD_opencv_world=ON -D WITH_GSTREAMER=OFF -D OPENCV_ENABLE_NONFREE=ON ..make -j8sudo make install
复制代码


如果编译顺利的话,最终 opencv 相关 lib 库,头文件 include 均会安装到/usr/local/opencv3

3.2 OpenCV 核心类型 Mat 介绍

Mat 类是 Opencv 中储存图像的一种数据结构。Mat 类可以看做是存放矩阵的容器,他包含了两部分,分别是用来存放图片信息的信息头,和一个指向图片储存矩阵的指针。信息头往往占用空间比较小,而且各个图片之间的信息头是完全独立的。而图片储存矩阵往往占用较大的空间,并且可以多个图片的矩阵指针指向同一个内存空间。下面主要减少利用 Mat 创建矩阵。

3.2.1 利用 Mat 类的构造函数创建矩阵

Mat 类有很多构造函数可以用来创建矩阵结构,并且给与赋值,这里距离介绍一种,其函数定义为


 Mat(int rows, int cols, int type, const Scalar& s);
复制代码


这个构造函数具有四个参数,其特点是能够定义矩阵的结构并且能够赋予初值


  • 第一个参数表示矩阵的行数

  • 第二个参数表示矩阵的列数

  • 第三个参数表示矩阵储存数据的类型,具有格式 CV_[位数] [有无符号] [数据类型] [通道数],如CV_8UC3 表示存储数据为 8 位无符号 char 类型,并且具有三个通道

  • 第四个参数是一种向量类型的变量,能够给予矩阵赋予初值,这个向量最多有四个维度。

3.2.2 利用成员函数 create 创建矩阵

使用这种方法创建的矩阵只是一种开辟内存空间,而不能赋予初值


Mat m;m.create(3, 3, CV_8UC3);
复制代码

3.3 OpenCV 图像处理实战

上面我们功能介绍里面提到了旋转、裁剪都功能均可以利用 OpenCV 提供的现成函数实现。用到头文件:


#include <opencv2/imgcodecs.hpp>#include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp>#include <iostream>
using namespace cv;cv::Mat src1, src2;cv::Mat dest; //src1.copyTo(dest);
复制代码

3.3.1 旋转

//旋转90度rotate(dest, dest, ROTATE_90_COUNTERCLOCKWISE);//旋转180度rotate(dest, dest, ROTATE_180);
复制代码

3.3.2 翻转

//左右上下翻转flip(dest, dest, -1);//上下翻转flip(dest, dest, 1);//左右翻转flip(dest, dest, 0);
复制代码

3.3.3 修改大小

cv::resize(dest, dest, Size(width, height));
复制代码

3.3.4 裁剪

dest = dest(Rect(x, y, w, h));
复制代码

3.3.5 灰度

cvtColor(dest,dest, COLOR_BGR2GRAY);
复制代码

3.3.6 混合

addWeighted(src2, a, dest, 1-a,0,dest);
复制代码

3.4 OpenCV 视频 IO 接口

上面介绍的均为基于图片的操作,我们要操作的是视频,其实视频都是有一帧一帧的图像组成,图像知道怎么处理了就可以开始处理视频了。OpenCV 为我们提供了视频的 IO 接口:

3.4.1 打开视频源

VideoCapture cap1;bool ret = cap1.open(file);//获取帧率fps = cap1.get(CAP_PROP_FPS);//获取视频宽度width = cap1.get(CAP_PROP_FRAME_WIDTH);//获取视频高度height = cap1.get(CAP_PROP_FRAME_HEIGHT);
复制代码

3.4.1 读取视频帧

Mat mat1;cap1.read(mat1);
复制代码

4. QT 实战

4.1 环境搭建

基于官方教程https://doc.qt.io/qt-5/macos.html安装 QTCreator 即可。


新建视频编辑工程,在 pro 配置文件中增加 opencv 库路径:


DEFINES += QT_MULTIMEDIA_LIB QT_WIDGETS_LIB
LIBS += -L"/usr/local/opencv3/lib" \ -lopencv_core \ -lopencv_highgui \ -lopencv_imgproc \ -lopencv_ml \ -lopencv_objdetect \ -lopencv_video \ -lopencv_dnn \ -lopencv_imgcodecs \ -lopencv_shape \ -lopencv_videoio \
复制代码

4.2 绘制视频

视频绘制我们基于 QT 提供的 QOpenGLWidget,通过 QOpenGLWidget 提供的机制将 Mat 中的图像内容渲染到屏幕:


QImage img;void CustomQOpenGLWidget::SetImage(cv::Mat mat){    QImage::Format fmt = QImage::Format_RGB888;    int pixSize = 3;    if(mat.type() == CV_8UC1){        fmt = QImage::Format_Grayscale8;        pixSize = 1;    }    if(img.isNull() || img.format() != fmt){        delete img.bits();        uchar *buf = new uchar[width()*height() * pixSize];        img = QImage(buf, width(), height(), fmt);    }    Mat des;    cv::resize(mat, des, Size(img.size().width(), img.size().height()));    if(pixSize > 1){        cv::cvtColor(des, des, COLOR_BGR2RGB);    }    memcpy(img.bits(), des.data, des.rows*des.rows*des.elemSize());    update();}void CustomQOpenGLWidget::paintEvent(QPaintEvent *e){     QPainter p;     p.begin(this);     p.drawImage(QPoint(0, 0),img);     p.end(); }
复制代码

5. 总结

至此我们已经基于 OpenCV+QT 实现了一个简单实用的视频编辑工具。当然我们也可以基于 ffmpeg 的视频 IO + OpenGL 实现;也可以基于 OpenGl + OpenCV 实现 Android、iOS 平台的编辑工具。方法有很多,我们选择用最少的代码进行最快的实现。


当然里面也会涉及很多细节,包括视频的同步,线程的同步,以及音频合成以及音视频同步。后面的文章我们在介绍这方面的内容。





发布于: 刚刚阅读数: 2
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017.10.17 加入

Android音视频、AI相关领域从业者

评论

发布
暂无评论
基于OpenCV+QT开发超实用的视频编辑器