1.原理图


2.处理函数,

class YuvOperationtwo {public:void averageFrame(int totalPix,unsigned char* before_data, unsigned char* write_data, unsigned char* after_data);};
void YuvOperationtwo::averageFrame(int totalPix,unsigned char* before_frame, unsigned char* write_frame, unsigned char* after_frame) {//前一帧,写入帧,后一帧的活动指针unsigned char* activity_before_frame = before_frame;unsigned char* w_write_frame = write_frame;unsigned char* activity_after_frame = after_frame;for (int j = 1; j <= totalPix; j++) {//除2是因为d1与d2相同*w_write_frame = *activity_before_frame / 2 + *activity_after_frame / 2;w_write_frame++;activity_before_frame++;activity_after_frame++;}
}

调用

const char* inPath = "D:\\YUM\\experiment three\\RaceHorses_416x240_30.yuv";const char* outOddPath = "D:\\YUM\\experiment three\\RaceHorses_416x240_30_odd.yuv";FILE* fin = fopen(inPath, "rb+");if (!fin) {cout << "Open file failed!" << endl;return -1;}FILE* fout = fopen(outOddPath, "a");if (!fout) {cout << "Open file failed!" << endl;return -1;}int width = 416;int height = 240; int totalPix = int(width * height * 1.5);//每帧像素个数为416×240,420视频序列yuv每个像素占用1.5byte的像素空间。int nFrame, size;fseek(fin, 0, SEEK_END);   //将文件指针移到文件末尾,偏移0个字节;fseek(fp,50L,0);或fseek(fp,50L,SEEK_SET);解释:其作用是将位置指针移到离文件头50个字节处size = ftell(fin);     //得到文件尾相对于文件首的位移,即文件的总字节数rewind(fin);       //重置文件指针指向文件头部nFrame = size / totalPix; //得到视频文件的总帧数cout << "视频总帧数:" << nFrame << endl;//这里只能用unsigned char 不能用char。unsigned char* before_frame = new unsigned char[totalPix]();      //前一帧unsigned char* write_frame = new unsigned char[totalPix]();       //预测帧unsigned char* after_frame = new unsigned char[totalPix]();       //后一帧//nFrame可理解为生成的帧数,10--》生成10帧for (int frame = 0; frame < nFrame; frame++) {//读取1-2-3。。。帧fread(before_frame, 1, totalPix, fin);     //读取2-3-4。。。帧fread(after_frame, 1, totalPix, fin);//第二次读取时候文件指针移动到第2帧处,需要向后移动一帧大小的位数fseek(fin, -totalPix, SEEK_CUR); YuvOperationtwo y;y.averageFrame(totalPix, before_frame, write_frame, after_frame);fwrite(write_frame, 1, totalPix, fout);}fclose(fin);fclose(fout);system("pause");return 0;

踩坑1

unsigned char 和 char的区别:

虽然都是占用1个字节,8位,且都能表示256个数字,但是char表示的范围为-128~127,而unsigned char表示的范围为0-255。在读取yuv二进制文件时候出现单个位数大于127的情况,就会导致出问题。如
unsigned char uc=255; char c=255; printf("%d %d",uc,c); 结果为: 255 -1
因为char类型表示有符号数,而二进制中最高位表示正负,255二进制表示为11111111在计算机内进行存储,为补码形式,转化为原码即为-1。

踩坑2

在进行测试不使用函数的情况下,活动指针必须要放在循环体里边,不能放在循环体外部。

踩坑3

在仅处理1,2帧得到1和2之间的插入帧时候也要使用中间指针,不能使用原定义的数组,这里不是多清楚原因,从java到c++底子太弱了。

分开处理YUV的写法

1.函数

class YuvOperationtwo {public:void averageFrameYuv(int width, int hegith,unsigned char* before_y_read_data, unsigned char* before_u_read_data, unsigned char* before_v_read_data, unsigned char* y_write_data, unsigned char* u_write_data, unsigned char* v_write_data, unsigned char* after_y_read_data, unsigned char* after_u_read_data, unsigned char* after_v_read_data);
};void YuvOperationtwo::averageFrameYuv(int width,int hegith,unsigned char* before_y_read_data, unsigned char* before_u_read_data, unsigned char* before_v_read_data, unsigned  char* y_write_data, unsigned  char*u_write_data, unsigned  char* v_write_data, unsigned char* after_y_read_data, unsigned char* after_u_read_data, unsigned  char* after_v_read_data) {//前一帧的yuv--游标指针unsigned char* read_before_y = before_y_read_data;unsigned char* read_before_u = before_u_read_data;unsigned char* read_before_v = before_v_read_data;//后一帧的yuv--游标指针unsigned char* read_after_y = after_y_read_data;unsigned char* read_after_u = after_u_read_data;unsigned char* read_after_v = after_v_read_data;//要写入的yuvunsigned char* write_img_y = y_write_data;unsigned char* write_img_u = u_write_data;unsigned char* write_img_v = v_write_data;int yWidth = width;int yHeight = hegith;int uvWidth = width / 2;int uvHeight = hegith / 2;int i = 0, j = 0;//对Y分量进行前后平均预测for (i = 0; i < yHeight; i++) {for (j = 0; j < yWidth; j++) {*write_img_y = *read_before_y / 2 + *read_after_y / 2;write_img_y++;read_before_y++;read_after_y++;}}//对UV分量进行前后预测for (i = 0; i < uvHeight; i++) {for (j = 0; j < uvWidth; j++) {*write_img_u = *read_before_u / 2 + *read_after_u / 2;write_img_u++;read_before_u++;read_after_u++;*write_img_v = *read_before_v / 2 + *read_after_v / 2;write_img_v++;read_before_v++;read_after_v++;}}

主函数

const char* inPath = "D:\\YUM\\experiment three\\RaceHorses_416x240_30.yuv";const char* outOddPath = "D:\\YUM\\experiment three\\RaceHorses_416x240_30_odd.yuv";FILE* fin = fopen(inPath, "rb+");if (!fin) {cout << "Open file failed!" << endl;return -1;}FILE* fout = fopen(outOddPath, "a");if (!fout) {cout << "Open file failed!" << endl;return -1;}int width = 416;int height = 240;int totalSize = width * height;int nFrame = 0, fileTotalSize = 0;int totalPix = int(width * height * 1.5);//每帧像素个数为416×240,420视频序列yuv每个像素占用1.5byte的像素空间。unsigned char* before_frame_y = new unsigned  char[totalSize]();unsigned char* before_frame_u = new unsigned char[totalSize / 4]();unsigned char* before_frame_v = new unsigned char[totalSize / 4]();unsigned char* write_frame_y = new unsigned char[totalSize]();unsigned char* write_frame_u = new unsigned char[totalSize / 4]();unsigned char* write_frame_v = new unsigned char[totalSize / 4]();unsigned char* after_frame_y = new unsigned char[totalSize]();unsigned char* after_frame_u = new unsigned char[totalSize / 4]();unsigned char* after_frame_v = new unsigned char[totalSize / 4]();for (int frame = 0; frame < 10; frame++) {fread(before_frame_y, totalSize, 1, fin);fread(before_frame_u, totalSize/4, 1, fin);fread(before_frame_v, totalSize/4, 1, fin);fread(after_frame_y, totalSize, 1, fin);fread(after_frame_u, totalSize / 4, 1, fin);fread(after_frame_v, totalSize / 4, 1, fin);fseek(fin, -totalPix, SEEK_CUR);YuvOperationtwo y;y.averageFrameYuv(width, height, before_frame_y, before_frame_u, before_frame_v,write_frame_y, write_frame_u, write_frame_v, after_frame_y, after_frame_u, after_frame_v);fwrite(write_frame_y, totalSize, 1, fout);fwrite(write_frame_u, totalSize / 4, 1, fout);fwrite(write_frame_v, totalSize / 4, 1, fout);}fclose(fin);fclose(fout);system("pause");return 1;

C++处理YUV格式视频【帧平均法】相关推荐

  1. vs2010MFC D3D播放YUV格式视频详细制作全过程

    1.环境配置 1.1 Microsoft Visual Studio 2010安装 先下载Visual Studio 2010,然后双击setup.exe安装,安装时有一步选择vc++安装就可以了,其 ...

  2. vs2010MFC D3D播放YUV格式视频详细制作全过程

    目录(?)[+] 1.环境配置 1.1 Microsoft Visual Studio 2010安装 先下载Visual Studio 2010,然后双击setup.exe安装,安装时有一步选择vc+ ...

  3. FFmpeg4入门07:解码视频并保存为YUV格式文件

    上一篇我们解码并保存了其中的几帧确保解码过程和结果是对的.本篇我们将解码整个视频并保存为标准的YUV格式(YUV格式具体信息详见YUV格式介绍),我们就选YUV420P(I420)作为输出格式. 保存 ...

  4. 使用v4l2音、视频协议实现USB摄像头的图像、视频YUV格式采集功能(ubuntu16.04LTS)

    第一感觉是首先得了解v4l2协议,它的功能.以及与之对应的实现逻辑,还有与硬件.操作系统的交互等内容.再试着根据功能逻辑和软硬件交互关系,借助硬件设备,实现基础的功能,如查询设备信息.帧类型等.然后, ...

  5. 视频和视频帧:图像,从自然光到01串

    视频和视频帧:图像,从自然光到01串 视频和视频帧:图像,从自然光到01串 资料来源 视频和视频帧:图像,从自然光到01串 写在前面 从今年(2019年)年中接手AI摄像头开发项目,笔者第一次真的到了 ...

  6. 【Bug修复】yuv生成mp4格式文件帧数(时间)与原视频不一致

    问题描述 需要将一系列的视频从yuv格式的文件编码成每秒30帧的视频,但是在yuv生成mp4格式时,存在帧数不对齐的问题. 1.准备两个视频 Animation_1080P-209f.mkv,25fp ...

  7. 音视频处理基础知识扫盲:数字视频YUV像素表示法以及视频帧和编解码概念介绍

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...

  8. 关于视频的YUV格式介绍

    本文转载于图文详解YUV420数据格式 YUV格式有两大类:planar和packed. 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V. 对于 ...

  9. AVI格式视频转YUV

    网上找这一方面找的还蛮困难的,开始只能找到别人写的一长串的代码,但不想用这种方式,觉得麻烦.现在也不知道这个问题算解决没有,因为感觉播放不是很清楚,打算明天找找比较两个视频的异同的指标乃至代码,看转换 ...

最新文章

  1. Android安全问题 抢先接收广播 - 内因篇之广播接收器注册流程
  2. Java程序的运行原理及JVM的启动是多线程的吗?
  3. 在WAS中得到OracleConnection
  4. java编译器使用教程_Java编译器API简介
  5. SD 胡策 Round 1 T3 彩尾巴猹的二进制数
  6. 微信开源项目讲解使用公开课
  7. 类的定义 java 1613806383
  8. [工具]将xml文件转换为html显示
  9. 带有记忆的菲波那切数列
  10. matlab积分器的工作原理,Simulink积分器详解(图)
  11. springboot 返回二进制文件流
  12. win2008R2 AD域 网络驱动映射
  13. Springboot文件上传报错:failed to convert java.lang.String to org.springframework.util.unit.DataSize
  14. word中如何制作三线表
  15. Probability and Stochastic Models(1) —— 研一新课学习笔记
  16. Android Kotlin - 监听耳机的插入和拔出
  17. 资源分享:嵌入式stm32项目开发 心率检测仪的设计与实现
  18. ViSual Studio美化插件设置背景图片
  19. HADOOP组成部分
  20. 云终端服务器的单价是多少_电子阅览室云终端报价方案

热门文章

  1. python.filter函数
  2. Java项目:汽车出租租赁系统(java+jsp+SSM+maven+mysql)
  3. Pushmall共享电商营销推广平台2023年6月升级进度
  4. 使用阿里云进行备案踩过的坑
  5. 数据库系统工程师(第一章)
  6. python不使用GDAL实现批量nc转tif
  7. document.getElementById
  8. win10taskkill无法终止进程_Win10关闭全部无响应进程的操作技巧
  9. 小程序开发零门槛教程
  10. 聊聊我对测试开发岗的理解