zoukankan      html  css  js  c++  java
  • 模糊测试之AVI文件分析

    本次试验主要是针对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文件的各子块构造。

    图片1.png

    AVIBMP的关系

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

    图片18.png

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

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

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

    目录 “Easy_BMP2AVI”   

    在此目录下运行如下:

    图片2.png

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

    图片3.png

     

    最终可以打开结果看一下

    图片4.png

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

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

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

    图片5.png

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

    图片6.png

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

    图片7.png

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

    图片8.png

    选择图片9.png分别添加OnBnClickedButton1()•••OnBnClickedButton5()

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

    图片11.png

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

    图片12.png

    同理可得完成下一部分:

    图片13.png

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

    图片14.png

    变量名分别为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()”的上面和

    图片15.png

    下面添加

    ON_MESSAGE(UM_PROGRESS,Onrogress)

    13. 图片16.png下面添加:

     

     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 ”);

    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运行 得:

    图片17.png

    五.实验心得与总结

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

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

  • 相关阅读:
    Entity Framework 实体框架的形成之旅--界面操作的几个典型的处理(8)
    C#开发微信门户及应用(28)--微信“摇一摇·周边”功能的使用和接口的实现
    Winform开发框架中实现同时兼容多种数据库类型处理
    Entity Framework 实体框架的形成之旅--数据传输模型DTO和实体模型Entity的分离与联合
    C#开发微信门户及应用(27)-公众号模板消息管理
    知识图谱 知识计算--- 本体推理 规则推理 路径计算 社区计算 相似图计算 链接预测 不一致检测
    动态规划算法模板和demo
    dga model train and test code
    基于图的异常检测(三):GraphRAD
    InterpretML 微软可解释性机器学习包
  • 原文地址:https://www.cnblogs.com/ichunqiu/p/7366251.html
Copyright © 2011-2022 走看看