[笔记]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

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

相关文章
|
10天前
|
计算机视觉 数据格式
使用opencv在Qt控件上播放mp4文件
使用opencv在Qt控件上播放mp4文件
23 2
|
22天前
|
存储 编解码 算法
深度探索:使用FFmpeg实现视频Logo的添加与移除(二)
深度探索:使用FFmpeg实现视频Logo的添加与移除
35 0
|
29天前
|
编解码 监控 计算机视觉
QT5.14.2 视频分帧:QT与FFmpeg的高效结合
QT5.14.2 视频分帧:QT与FFmpeg的高效结合
|
18天前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(三)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
24 0
|
18天前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(二)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
31 0
|
22天前
|
存储 编解码 调度
剖析ffmpeg视频解码播放:时间戳的处理
剖析ffmpeg视频解码播放:时间戳的处理
39 0
|
23天前
|
存储 编解码 vr&ar
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
65 0
|
22天前
|
编解码 算法 vr&ar
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(二)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
21 1
|
22天前
|
存储 编解码 算法
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(一)
深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换
44 1
|
18天前
|
存储 算法 编译器
【ffmpeg 到Qt的图片格式转换】精彩的像素:深入解析 AVFrame 到 QImage 的转换
【ffmpeg 到Qt的图片格式转换】精彩的像素:深入解析 AVFrame 到 QImage 的转换
41 0

推荐镜像

更多