[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat

简介: [笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat

一、源码分析和空间创建释放

1.1 内联特性

1.2 特性

inline关键字是一定要和函数体定义放在一起得,和声明结合是没有作用的。

1.2.1 调用开销的区别

实现太过简单,以至于他的消耗甚至是小于标准函数调用的消耗,其调用指令相对简单,如果此时我们又需要大量的调用函数,那伴随着的就是大量的指令开销;针对这种浪费情况,“寸土寸金”思想严重的开发人员就设计出了inline函数,又称内联函数。

内联函数最重要的作用就是针对函数调用开销大于函数指令开销的函数体而推出的!实现在编译阶段,将调用开销忽略,直接在函数处进行代码展开,且inline函数也就不会再生成函数符号了!

1.2.2 代码体的差异

(1)在debug版本上,inline是无作用的,只有在release版本下才可以!

(2)并非所有的inline函数都会被编译器处理成内联函数 例如递归可以;代码体太过庞大不易展开,要么是代码体是个贪得无厌的无底洞,不能展开;

1.3 Mat创建

1.3.1 构造方法创建

inline
Mat::Mat(int _rows, int _cols, int _type)

例如

Mat mat(3000,4000,CV_8UC3);

1.3.2 Mat.Create()

inline
void Mat::create(int _rows, int _cols, int _type)

例如

Mat mat;
mat.create(3000,4000,CV_8UC1);

1.4 Mat释放

1.4.1 release()或者析构

引用计数为1时才会真正释放

二、遍历和修改连续Mat图像空间

2.1 遍历和修改连续的OpenCV Mat图像空间

int main(int argc, char* argv) {
  Mat image(3000, 4000, CV_8UC3);
  int es = image.elemSize();
  int size = image.rows * image.cols * es;
  for (int i = 0; i < size; i += es) {
    image.data[i] = 255;//B
    image.data[i + 1] = 0;//G
    image.data[i + 2] = 0;//R
  }
  namedWindow("img");
  imshow("img", image);
  waitKey(0);
  return 0;
}

2.1.1 RGB存放方式(连续)

注:可能因为内存对齐等原因,第一行和第二行不是连续存储的,即第一行末不是第二行开始,而是可能空一些字节用于内存对齐。

2.2 判断是否连续isContinues()

2.2.1 判断存储空间是否连续
2.2.2 通过steps记录

2.3 使用opencv接口实现运行记时函数用来分析执行时间

int PrintMs(const char *text = "") 
{
  static long long last = 0;
  long long cur  = getTickCount();
  if (last == 0) {
    last = cur;
  }
  long long ms = ((double)(cur - last) / getTickFrequency()) *1000;
  if (*text != 0) {
    printf("%s = %d ms\n", text,ms);
  }
  return 0;
}

优化禁用耗时39ms

优化使速度最大化22ms

注:debug版本开启使速度最大化需要设置:

1.项目属性 c/c+±>优化->使速度最大化

2.c/c+±>常规->调试信息-》程序数据库(/Zi)

3.c/c++ 代码生成->基本运行时检查->默认

2.4 遍历不连续的OpenCV Mat空间

for (int row = 0; row < image.rows; row++) {
    for (int col = 0; col < image.cols; col++) {
      (&image.data[row*image.step])[col*es] = 0;//B
      (&image.data[row*image.step])[col*es + 1] = 0;//G
      (&image.data[row*image.step])[col*es + 2] = 0;//R
    }
  }

2.5 ptr模板函数 遍历Mat并测试其性能

ptr访问 相比遍历访问 速度更接近于直接地址访问

for (int row = 0; row < image.rows; row++) {
    for (int col = 0; col < image.cols; col++) {
      Vec3b* c = image.ptr<Vec3b>(row, col);      
      c->val[0] = 0; //B
      c->val[1] = 255; //G
      c->val[2] = 0; //R
    }
  }

2.6 at函数 遍历Mat并捕获异常

try{
      //此处rows*2 特意测试异常
    for (int row = 0; row < image.rows *2; row++) {
      for (int col = 0; col < image.cols; col++) {
        Vec3b &m = image.at<Vec3b>(row, col);
        m.val[0] = 0; //B
        m.val[1] = 255; //G
        m.val[2] = 0; //R
      }
    }
  }
  catch (cv::Exception &ex) {
    std::cout << ex.what() << std::endl;
  }

注:Release版本不会抛出异常 只有Debug 会抛出异常

原因:解决try-catch 在RELEASE版无法捕捉错误

2.7 迭代器 遍历Mat并总结遍历方法

auto it = image.begin<Vec3b>();
  auto it_end = image.end<Vec3b>();
  for (; it != it_end; it++)
  {
    (*it).val[0] = 0;//B
    (*it).val[1] = 0;//G
    (*it).val[2] = 255;//R
  }

2.7.1 特点

1>可以不用管mat的行列,大小,类型

2.8 总结遍历方法

1>通过地址直接访问 data

2>通过Ptr

3>通过at

4>通过迭代器

2.9 QT自定义opengl的Widget绘制Mat

具体不展开 后期贴上源码地

相关文章
|
2月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
186 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
2月前
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
4832 3
|
2月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
78 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
1月前
|
编解码 监控 网络协议
如何使用FFmpeg实现RTSP推送H.264和H.265(HEVC)编码视频
本文详细介绍了如何使用FFmpeg实现RTSP推送H.264和H.265(HEVC)编码视频。内容涵盖环境搭建、编码配置、服务器端与客户端实现等方面,适合视频监控系统和直播平台等应用场景。通过具体命令和示例代码,帮助读者快速上手并实现目标。
185 6
|
2月前
|
Ubuntu 应用服务中间件 nginx
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
本文是关于Ubuntu系统中使用ffmpeg 3.2.16源码编译OpenCV 3.4.0的安装笔记,包括安装ffmpeg、编译OpenCV、卸载OpenCV以及常见报错处理。
201 2
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
|
2月前
|
Java 数据安全/隐私保护
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
150 1
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
110 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
计算机视觉 Python
FFMPEG学习笔记(一): 提取视频的纯音频及无声视频
本文介绍了如何使用FFmpeg工具从视频中提取纯音频和无声视频。提供了具体的命令行操作,例如使用`ffmpeg -i input.mp4 -vn -c:a libmp3lame output.mp3`来提取音频,以及`ffmpeg -i input.mp4 -c:v copy -an output.mp4`来提取无声视频。此外,还包含了一个Python脚本,用于批量处理视频文件,自动提取音频和生成无声视频。
84 1
|
2月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
67 1
|
2月前
|
网络协议 应用服务中间件 nginx
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
这篇文章讨论了在使用nginx-rtmp-module进行RTMP推流时遇到的“Server error: Already publishing”错误,分析了错误原因,并提供了详细的解决办法,包括修改nginx配置文件和终止异常的TCP连接。
205 0
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing

推荐镜像

更多
下一篇
DataWorks