本次试验主要是针对AVI的处理,了解AVI的基本概念,并且掌握AVI文件常用的程序读写方法。知道AVI视频文件的帧的读取方法,以及了解BMP和AVI的基本关系。

本文作者:i春秋签约作家——天天

一 AVI的基本概念

1. 什么是AVI

AVI是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,现在已被Windows 95/98、OS/2等多数操作系统直接支持。

2. AVI格式的优缺点

图像质量好、可跨平台使用、体积庞大、压缩标准不统一。

3. AVI的文件结构

AVI是符合RIFF文件规范的数字音频与视频文件格式,在介绍AVI文件前,我们要先来看看RIFF文件结构。AVI文件采用的是RIFF文件结构方式,RIFF(Resource Interchange File Format,资源互换文件格式)是微软公司定义的一种用于管理windows环境中多媒体数据的文件格式,波形音频wave,MIDI和数字视频AVI 都采用这种格式存储。构造RIFF文件的基本单元叫做数据块(Chunk),每个数据块包含3个部分:4字节的数据块标记(或者叫做数据块的ID)、数据块的大小、数据。整个RIFF文件可以看成一个数据块,其数据块ID为RIFF,称为RIFF块。

一个RIFF文件中只允许存在一个RIFF块。RIFF块中包含一系列的子块,其中有一种字块的ID为”LIST”,称为LIST,LIST块中可以再包含一系列的子块,但除了LIST块外的其他所有的子块都不能再包含子块。RIFF和LIST块分别比普通的数据块多一个被称为形式类型(Form Type)和列表类型(List Type)的数据域,其组成为: 4字节的数据块标记(Chunk ID)、数据块的大小、4字节的形式类型或者列表类型、数据。

下面我们看看AVI文件的结构。AVI文件是目前使用的最复杂的RIFF文件,它能同时存储同步表现的音频视频数据。AVI的RIFF块的形式类型是AVI,它包含3个子块,如下所述:

(1)信息块,一个ID为”hdrl”的LIST块,定义AVI文件的数据格式。

(2)数据块,一个ID为 “movi”的LIST块,包含AVI的音视频序列数据。

(3)索引块,ID为 “idxl”的子块,定义 “movi”LIST块的索引数据,是可选块。

AVI文件的结构如下图所示,下面将具体介绍AVI文件的各子块构造。

AVIBMP的关系

一个AVI文件是由多个BMP文件构成。如下图:

AVI视频序列中的“帧”即为位图。

AVI视频序列中的“帧”的数量和位图数量是对应的。

三.分析analysis目录里AVI操作函数的写法

目录 “Easy_BMP2AVI”   

在此目录下运行如下:

上图的一些命令是用来合成avi的,在一下函数的调用:
cvLoadImage:从文件中读取图像 。
cvCreateVideoWriter:创建视频文件写入器 。
cvWriteFrame:写入一帧到一个视频文件中。
cvGetCaptureProperty:获得视频获取结构的属性,如视频序列的帧数等。
cvCaptureFromFile 为从文件中读取而打开文件
cvQueryFrame从摄像头或者文件中抓取并返回一帧
可以很方便的把BMP合成AVI。一下是合成的过程:

最终可以打开结果看一下:

.OpenCV 及MFC实现AVI的合成和分解

1. 创建一个MFC对话框应用程序(Dialog-based Application),在名称栏输入创建项目的名称,点击“确定”。

2. 在出现的“MFC应用程序向导”对话框内,选择“基于对话框”,并取消“使用Unicode库(N)”其他选项不做修改,单击“下一步”如下图:

3. 一直点击“下一步”到“生成的类”对话框,选择基类为“CDialog”单击完成即可创建一个MFC对话框。如下图:

4. 删除“TODO:在此放置对话框控件。”、“确定”和“取消”控件。然后点击“工具”中的“Button”添加以下五个控件并改名。结果如下下图:

5. 接着点击属性栏中的“控制事件“按钮 ,弹出如下对话框:

选择分别添加OnBnClickedButton1()•••OnBnClickedButton5()

6. 在工具箱中点击在图中添加后如下图:

7. 在工具箱中点击“Group Box” ,从左上角往右下角拖拉到 “开始分解”止,同时修改其属性栏里的 的“静态”为“AVI的合成”,完成后如图:

同理可得完成下一部分:

8. 依次右击“示例编辑框”按钮分别添加变量,如图:

变量名分别为m_1, m_2,  m_3,  m_4。

9. 在“解决方案资源管理器下”打开“BY_MFC_YJCDlg.h”,在“#pragma one”下面添加:

#include “cv.h”

#include “highgui.h”

#include “cxcore.h”

#include <stdio.h>

#include “shlwapi.h”

#include <direct.h>

#include <io.h>

#include <vector>

using namespace std;

#define UM_PROGRESS WM_USER+1

10. 在最后的“}”内添加:

afx_msg LRESULT Onrogress(WPARAM, LPARAM);

public:

char* choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath);

public:

int bmptoavi();

public:

afx_msg void OnBnClickedButton10();

void GetFile(CString sPath, vector<CString> *filePaths);

CString getFileExt(CString filePath);

BOOL __cdecl isSameType (char *Ext,const char *format, …);

11. 打开源文件“BY_MFC_YJCDlg.cpp”,在“#ifdef_DEBUG”上添加:

#include <stdlib.h>

在 “#endif”下添加:

CString bmp_path1;

CString bmp_path;//bmp路径(hecheng)

CString AviFileName;//AVIL路径

CString AVI_path;

int i = 1;

//int bmptoavi(LPVOID lpParameter);//shengming

CEdit dlg;

12. 在“END_MESSAGE-MAP()”的上面和

下面添加:

ON_MESSAGE(UM_PROGRESS,Onrogress)

13. 在下面添加:

char* COPENCV_AVI_BMPDlg::choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath)//获得文件夹

{

BROWSEINFO bi;

LPCITEMIDLIST pItemIDList;

bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();

bi.pidlRoot = NULL;

bi.pszDisplayName = szPath;

bi.lpszTitle = szTitle;

bi.ulFlags = BIF_RETURNONLYFSDIRS;

bi.lpfn = NULL;

bi.iImage = 0;

pItemIDList = SHBrowseForFolder(&bi);

if(NULL == SHGetPathFromIDList(pItemIDList, szPath) )

{

AfxMessageBox(“路径为获取“);

}

return (char*)szPath;

}

14. 在OnBnClickedButton2()下添加:

if (0 == m_1.GetWindowTextLength())

{

AfxMessageBox(“please CHOISE bmp_filename!”);

exit(1);

}

if (0 == m_1.GetWindowTextLength())

{

AfxMessageBox(“please INPUT bmp_filename!”);

exit(1);

}

//AfxBeginThread((AFX_THREADPROC)bmptoavi, (void*)this);

PostMessage(UM_PROGRESS);

bmptoavi();

}

int COPENCV_AVI_BMPDlg::bmptoavi()

{

CString FileName;

CvVideoWriter *writer;

IplImage *frame;

vector<CString> imgFilePaths;

GetDlgItemText(IDC_EDIT1,bmp_path);//BMP的文件路径

GetFile(bmp_path, &imgFilePaths);

for (int i=0 ;i< imgFilePaths.size();++i)

{

frame = cvLoadImage(imgFilePaths.at(i).GetBuffer());

if(i == 0)

{

int AviForamt = -1;//设置压缩格式

int FPS = 25;

int AviColor = 1;

writer=cvCreateVideoWriter(AviFileName,-1,FPS,cvGetSize(frame),AviColor);

}

cvWriteFrame(writer,frame);

cvWaitKey(1);

cvReleaseImage(&frame);

}

cvReleaseVideoWriter(&writer);

return 0;

}

/*

* 功能:获取文件夹下的所有图片文件

*/

void COPENCV_AVI_BMPDlg::GetFile(CString sPath, vector<CString> *filePaths)

{

if (sPath.IsEmpty())

{

return;

}

CFileFind   ff;

CString szDir = sPath;

CString Ext;

if(szDir.Right(1) != “\\”)

szDir += “\\”;

szDir += “*.*”;

BOOL res = ff.FindFile(szDir);

while( res )

{

res = ff.FindNextFile();

CString sFileName;

if (ff.IsDirectory() && !ff.IsDots())//文件夹

{

CString sFilePath = ff.GetFilePath();

sFileName = ff.GetFileTitle();

GetFile(sFilePath, filePaths);

}

else if (!ff.IsDirectory() && !ff.IsDots())//文件

{

CString   strFilePath = ff.GetFilePath();

Ext = getFileExt(ff.GetFilePath());

if (isSameType(Ext.GetBuffer(),“ss”,“bmp”,“jpg”))

{

filePaths->push_back(strFilePath);

}

}

}

ff.Close();

}

CString COPENCV_AVI_BMPDlg::getFileExt(CString filePath)

{

filePath.ReleaseBuffer();

int pos = filePath.ReverseFind(‘.’);

if (pos >= 0)

{

return filePath.Right(filePath.GetLength() – pos -1);

}

}

BOOL __cdecl COPENCV_AVI_BMPDlg::isSameType (char *Ext,const char *format, …)

{

va_list ap;

int buffing;

int retval;

char ch;

char *ext;

va_start(ap, format);

_ASSERTE(format != NULL);

ext = strlwr(Ext);

while(ch = *(format++))

{

switch(ch)

{

case ‘s’:

{

char *p = va_arg(ap, char *);

if (0 == strcmp(Ext,p))

{

return 1;

}

break;

}

default:

{

printf(“input parameter is error \n”);

return -1;

}

break;

}

}

return(0);

15. 在OnBnClickedButton1()下添加:

char path[MAX_PATH];

choisebmppath(m_hWnd,“bmp文件夹“,path);

bmp_path = path;

SetDlgItemText(IDC_EDIT1,bmp_path);

AviFileName = “E:\\avi.avi”;

SetDlgItemText(IDC_EDIT2,“E:\\avi.avi”);

16. 在OnBnClickedButton3()下添加:

CFileDialog dlg(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,NULL,0);

if(!dlg.DoModal())

{

AfxMessageBox(“创建失败“);

exit(1);

}

AVI_path = dlg.GetPathName();

SetDlgItemText(IDC_EDIT3,AVI_path);

}

LRESULT  COPENCV_AVI_BMPDlg::Onrogress(WPARAM, LPARAM)

{

pgctrl.OffsetPos(2);

pgctrl.SetStep(1);//设置步长

pgctrl.SetRange32(1,1000);

pgctrl.SetPos(i);

pgctrl.SetBkColor(RGB(255, 0, 0));

pgctrl.StepIt();//让进度条动起来

return 1;

17. 在OnBnClickedButton4()下添加:

if (m_3.GetWindowTextLength() == 0)

{

AfxMessageBox(“AVI文件出错“);

exit(1);

}

CvCapture *capture;

IplImage *frame;

capture = cvCaptureFromAVI(AVI_path);

CString FileName;

CString strtemp;

CString newFileName;

int i=1;

UpdateData(FALSE);

for (i = 1;i<101;i++)

{

FileName.Format(“Frame-%03d.bmp”, i);

if (i==1)

{

GetDlgItemText(IDC_EDIT4,strtemp);

}

newFileName = strtemp + FileName;

frame = cvQueryFrame(capture);

if (!cvSaveImage( newFileName,frame))

{

AfxMessageBox(“提取失败“);

}

cvWaitKey(1);

}

}

18. 然后修改相应位置的所有“COPENCV-AVI-BMPDlg”为“C(工程名)Dlg”。并且在“项目属性”的“附加依赖项”添加 “cv.lib highgui.lib cvaux.lib cxcore.lib”运行 得:

五.实验心得与总结

本次试验主要是针对AVI的处理,了解AVI的基本概念,并且掌握AVI文件常用的程序读写方法。
   知道AVI视频文件的帧的读取方法,以及了解BMP和AVI的基本关系。

由于试验目的需要对一些代码的理解,对C++有更深度的认识,建议各位同学多看一些有关C++的内容。以更深一步的理解Opencv的机制与功能,将Opencv透彻的系统学习,加深对其的理解。

模糊测试之AVI文件分析的更多相关文章

  1. windows XP系统内核文件分析(全)

    Windows XP个别 System32 文件 System32 文件夹下个别要移除的文件 我们就要删除另外600 个 system32 文件...我们要一次把它们全都解决掉. 以下是我所删除的 S ...

  2. 富文本存储型XSS的模糊测试之道

    富文本存储型XSS的模糊测试之道 凭借黑吧安全网漏洞报告平台的公开案例数据,我们足以管中窥豹,跨站脚本漏洞(Cross-site Script)仍是不少企业在业务安全风险排查和修复过程中需要对抗的“大 ...

  3. RPM 打包技术与典型 SPEC 文件分析

    一 .rpm 介绍 1. 概述 RPM全称是 Red Hat Package Manager(Red Hat包管理器).几乎所有的 Linux 发行版本都使用这种形式的软件包管理安装.更新和卸载软件. ...

  4. linux实践之ELF文件分析

    linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...

  5. 蓝屏 Dump文件分析方法

    WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这 ...

  6. avi文件打开出现花屏、打开不了问题

    以avi为后缀名文件,其编码格式并不是单一的,而是多种格式都可以以avi作为后缀. AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchang ...

  7. (转)AVI文件格式解析+AVI文件解析工具

    AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...

  8. KEIL MDK输出map文件分析

    一.文件分析流程 1.第一部分:Section Cross References 主要是各个源文件生成的模块之间相互引用的关系. stm32f10x.o(STACK) refers (Special) ...

  9. 转:电子取证中AVI文件的文件雕复

    电子取证中AVI文件的文件雕复 收藏本文 分享 1引言在电子取证工作中,恢复数字设备中被删除的数据是极为重要的工作之一,恢复数据又分依赖系统元信息的传统数据恢复技术和不依赖系统元信息的文件雕刻.文件雕 ...

随机推荐

  1. 20172325 2017-2018-2 《Java程序设计》第九周学习总结

    20172325 2017-2018-2 <Java程序设计>第九周学习总结 教材学习内容总结 异常 1.学习了异常的基本概念: 2.区分异常与错误: 一个异常是指一个定义非正常情况或错误 ...

  2. forbidden

  3. hg 添加用户

    .hg目录下hgrc文件 [ui] username = lyd

  4. linq 使用or构建动态查询

    You can certainly do it within a Where clause (extension method). If you need to build a complex que ...

  5. 2018.10.05 NOIP模拟 相遇(dfs序+lca)

    传送门 考虑到两条路径相交的条件: 设两条路径为a,ba,ba,b. 则要么aaa路径的lcalcalca在bbb上. 要么bbb路径的lcalcalca在aaa上. 因此我们维护两棵树. 分别支持路 ...

  6. 2018.09.08 AtCoder Beginner Contest 109简要题解

    比赛传送门 水题大赛? 全是水题啊!!! T1 ABC333 就是判断是不是两个数都是奇数就行了. 代码: #include<bits/stdc++.h> using namespace ...

  7. IntelliJ IDEA 2017版 spring-boot使用Spring Data JPA使用Repository<T, T>编程

    1.环境搭建pom.xml搭建 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=& ...

  8. Oracle之SQL语句性能优化(34条优化方法)

    (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处 ...

  9. ArcGIS Desktop python Add-in 测试一个插件

    a)制作一个插件文件 先找到工作目录,双击运行makeaddin.py脚本.这个脚本拷贝所有插件需要的文件和文件夹并在工作目录形成一个压缩文件.该压缩文件名为工作目录名称加上".esriad ...

  10. About DNS

    FQDN -- Fully Qualified Domain Name TTL -- Time To Live TLD -- Top Level Domain gTLD -- Generic Top ...