cvcap.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,486 行 · 第 1/4 页

SVN-BASE
1,486
字号
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "_highgui.h"

#ifdef WIN32

#include <vfw.h>
#if _MSC_VER >= 1200
#pragma warning( disable: 4711 )
#endif

#else

extern "C" {
#include "ffmpeg/avcodec.h"
}

#endif

/************************* Reading AVIs & Camera data **************************/

/***************************** Common definitions ******************************/

#define CV_CAPTURE_BASE_API_COUNT 6

typedef void (CV_CDECL* CvCaptureCloseFunc)( CvCapture* capture );
typedef int (CV_CDECL* CvCaptureGrabFrameFunc)( CvCapture* capture );
typedef IplImage* (CV_CDECL* CvCaptureRetrieveFrameFunc)( CvCapture* capture );
typedef double (CV_CDECL* CvCaptureGetPropertyFunc)( CvCapture* capture, int id );
typedef int (CV_CDECL* CvCaptureSetPropertyFunc)( CvCapture* capture,
                                                  int id, double value );
typedef const char* (CV_CDECL* CvCaptureGetDescriptionFunc)( CvCapture* capture );

typedef struct CvCaptureVTable
{
    int     count;
    CvCaptureCloseFunc close;
    CvCaptureGrabFrameFunc grab_frame;
    CvCaptureRetrieveFrameFunc retrieve_frame;
    CvCaptureGetPropertyFunc get_property;
    CvCaptureSetPropertyFunc set_property;
    CvCaptureGetDescriptionFunc get_description;
}
CvCaptureVTable;

typedef struct CvCapture
{
    CvCaptureVTable* vtable;
}
CvCapture;


HIGHGUI_IMPL void cvReleaseCapture( CvCapture** pcapture )
{
    if( pcapture && *pcapture )
    {
        CvCapture* capture = *pcapture;
        if( capture && capture->vtable &&
            capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
            capture->vtable->close )
            capture->vtable->close( capture );
        cvFree( (void**)pcapture );
    }
}


HIGHGUI_IMPL IplImage* cvQueryFrame( CvCapture* capture )
{
    if( capture && capture->vtable &&
        capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
        capture->vtable->grab_frame && capture->vtable->retrieve_frame &&
        capture->vtable->grab_frame( capture ))
        return capture->vtable->retrieve_frame( capture );
    return 0;
}

HIGHGUI_IMPL int cvGrabFrame( CvCapture* capture )
{
    if( capture && capture->vtable &&
        capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
        capture->vtable->grab_frame )
        return capture->vtable->grab_frame( capture );
    return 0;
} 

HIGHGUI_IMPL IplImage* cvRetrieveFrame( CvCapture* capture )
{
    if( capture && capture->vtable &&
        capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
        capture->vtable->retrieve_frame )
        return capture->vtable->retrieve_frame( capture );
    return 0;
}                                       

HIGHGUI_IMPL double cvGetCaptureProperty( CvCapture* capture, int id )
{
    if( capture && capture->vtable &&
        capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
        capture->vtable->get_property )
        return capture->vtable->get_property( capture, id );
    return 0;
}


HIGHGUI_IMPL int cvSetCaptureProperty( CvCapture* capture, int id, double value )
{
    if( capture && capture->vtable &&
        capture->vtable->count >= CV_CAPTURE_BASE_API_COUNT &&
        capture->vtable->set_property )
        return capture->vtable->set_property( capture, id, value );
    return 0;
}


/********************* Capturing video from AVI via VFW ************************/

#ifdef WIN32

static BITMAPINFOHEADER
icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB )
{
    BITMAPINFOHEADER bmih;
    memset( &bmih, 0, sizeof(bmih));
    bmih.biSize = sizeof(bmih);
    bmih.biWidth = width;
    bmih.biHeight = height;
    bmih.biBitCount = (WORD)bpp;
    bmih.biCompression = compression;
    bmih.biPlanes = 1;

    return bmih;
}

static void icvInitCapture_VFW()
{
    static int isInitialized = 0;
    if( !isInitialized )
    {
        AVIFileInit();
        isInitialized = 1;
    }
}


typedef struct CvCaptureAVI_VFW
{
    CvCaptureVTable* vtable;
    PAVIFILE avifile;
    PAVISTREAM avistream;
    PGETFRAME getframe;
    AVISTREAMINFO aviinfo;
    BITMAPINFOHEADER* bmih;
    CvSlice film_range;
    double fps;
    int pos;
    IplImage frame;
}
CvCaptureAVI_VFW;


static void icvCloseAVI_VFW( CvCaptureAVI_VFW* capture )
{
    if( capture->getframe )
    {
        AVIStreamGetFrameClose( capture->getframe );
        capture->getframe = 0;
    }
    if( capture->avistream )
    {
        AVIStreamRelease( capture->avistream );
        capture->avistream = 0;
    }
    if( capture->avifile )
    {
        AVIFileRelease( capture->avifile );
        capture->avifile = 0;
    }
    capture->bmih = 0;
    capture->pos = 0;
    capture->film_range.startIndex = capture->film_range.endIndex = 0;
    memset( &capture->frame, 0, sizeof(capture->frame));
}


static int icvOpenAVI_VFW( CvCaptureAVI_VFW* capture, const char* filename )
{
    HRESULT hr;

    icvInitCapture_VFW();

    if( !capture )
        return 0;

    hr = AVIFileOpen( &capture->avifile, filename, OF_READ, NULL );
    if( SUCCEEDED(hr))
    {
        hr = AVIFileGetStream( capture->avifile, &capture->avistream, streamtypeVIDEO, 0 );
        if( SUCCEEDED(hr))
        {
            hr = AVIStreamInfo( capture->avistream, &capture->aviinfo,
                                    sizeof(capture->aviinfo));
            if( SUCCEEDED(hr))
            {
                BITMAPINFOHEADER bmih = icvBitmapHeader(
                    capture->aviinfo.rcFrame.right -
                    capture->aviinfo.rcFrame.left,
                    capture->aviinfo.rcFrame.bottom -
                    capture->aviinfo.rcFrame.top,
                    24 );
                capture->film_range.startIndex = (int)capture->aviinfo.dwStart;
                capture->film_range.endIndex = capture->film_range.startIndex +
                                                (int)capture->aviinfo.dwLength;
                capture->fps = ((double)capture->aviinfo.dwRate)/capture->aviinfo.dwScale;
                capture->pos = capture->film_range.startIndex;
                capture->getframe = AVIStreamGetFrameOpen( capture->avistream, &bmih );
                if( capture->getframe != 0 )
                    return 1;
            }
        }
    }

    icvCloseAVI_VFW( capture );
    return 0;
}


static int icvGrabFrameAVI_VFW( CvCaptureAVI_VFW* capture )
{
    if( capture->avistream )
    {
        capture->bmih = (BITMAPINFOHEADER*)
            AVIStreamGetFrame( capture->getframe, capture->pos++ );
    }

    return capture->bmih != 0;
}


static const IplImage* icvRetrieveFrameAVI_VFW( CvCaptureAVI_VFW* capture )
{
    if( capture->avistream && capture->bmih )
    {
        cvInitImageHeader( &capture->frame,
                           cvSize( capture->bmih->biWidth,
                                   capture->bmih->biHeight ),
                           IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
        capture->frame.imageData = capture->frame.imageDataOrigin =
            (char*)(capture->bmih + 1);
        return &capture->frame;
    }

    return 0;
}


static double icvGetPropertyAVI_VFW( CvCaptureAVI_VFW* capture, int property_id )
{
    switch( property_id )
    {
    case CV_CAP_PROP_POS_MSEC:
        return cvRound(capture->pos*1000./capture->fps);
        break;
    case CV_CAP_PROP_POS_FRAMES:
        return capture->pos;
    case CV_CAP_PROP_POS_AVI_RATIO:
        return (capture->pos - capture->film_range.startIndex)/
               (capture->film_range.endIndex - capture->film_range.startIndex + 1e-10);
    case CV_CAP_PROP_FRAME_WIDTH:
        return capture->frame.width;
    case CV_CAP_PROP_FRAME_HEIGHT:
        return capture->frame.height;
    case CV_CAP_PROP_FPS:
        return capture->fps;
    case CV_CAP_PROP_FOURCC:
        return capture->aviinfo.fccHandler;
    case CV_CAP_PROP_FRAME_COUNT:
        return capture->film_range.endIndex - capture->film_range.startIndex;
    }
    return 0;
}


static int icvSetPropertyAVI_VFW( CvCaptureAVI_VFW* capture,
                                  int property_id, double value )
{
    switch( property_id )
    {
    case CV_CAP_PROP_POS_MSEC:
    case CV_CAP_PROP_POS_FRAMES:
    case CV_CAP_PROP_POS_AVI_RATIO:
        {
            int pos;
            switch( property_id )
            {
            case CV_CAP_PROP_POS_MSEC:
                pos = cvRound(value*capture->fps*0.001);
                break;
            case CV_CAP_PROP_POS_AVI_RATIO:
                pos = cvRound(value*(capture->film_range.endIndex - 
                                     capture->film_range.startIndex) +
                              capture->film_range.startIndex);
                break;
            default:
                pos = cvRound(value);
            }
            if( pos < capture->film_range.startIndex )
                pos = capture->film_range.startIndex;
            if( pos > capture->film_range.endIndex )
                pos = capture->film_range.endIndex;
            capture->pos = pos;
        }
        break;
    default:
        return 0;
    }

    return 1;
}

static CvCaptureVTable captureAVI_VFW_vtable = 
{
    6,
    (CvCaptureCloseFunc)icvCloseAVI_VFW,
    (CvCaptureGrabFrameFunc)icvGrabFrameAVI_VFW,
    (CvCaptureRetrieveFrameFunc)icvRetrieveFrameAVI_VFW,
    (CvCaptureGetPropertyFunc)icvGetPropertyAVI_VFW,
    (CvCaptureSetPropertyFunc)icvSetPropertyAVI_VFW,
    (CvCaptureGetDescriptionFunc)0
};


HIGHGUI_IMPL CvCapture* cvCaptureFromAVI( const char* filename )
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?