zoukankan      html  css  js  c++  java
  • Direct Show采集图像实例

    // CaptureVideo.h: interface for the CCaptureVideo class.
    //
    //////////////////////////////////////////////////////////////////////

    #if !defined(AFX_CAPTUREVIDEO_H__973C8C7A_47A3_45B6_9B28_0A4A08003540__INCLUDED_)
    #define AFX_CAPTUREVIDEO_H__973C8C7A_47A3_45B6_9B28_0A4A08003540__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include 
    <atlbase.h>
    #include 
    <windows.h>
    #include 
    <dshow.h>
    #ifndef SAFE_RELEASE
    #define SAFE_RELEASE( x ) \
    if ( NULL != x ) \
    { \
        x
    ->Release( ); \
        x 
    = NULL; \
    }

    #endif
    class CSampleGrabberCB;

    class CCaptureVideo  : public CWnd
    {
        friend 
    class CSampleGrabberCB;
    public:
        
    void GrabOneFrame(BOOL bGrab);
        
    void ImageProcess(BOOL bImage);
        HRESULT Init(
    int iDeviceID,HWND hWnd);
        CCaptureVideo();
        
    virtual ~CCaptureVideo();

        BOOL bIsVideoOpen;
        
    void SwitchImageProcess(BOOL bprocess);
           
    void ImageProcessing(unsigned char*m_pDibBits,int m_height, int m_width);

    private:
        HWND m_hWnd;
        IGraphBuilder 
    *m_pGB;
        ICaptureGraphBuilder2
    * m_pCapture;
        IBaseFilter
    * m_pBF;
        IMediaControl
    * m_pMC;
        IVideoWindow
    * m_pVW;
        CComPtr 
    <ISampleGrabber> m_pGrabber;

    protected:
        
    void FreeMediaType(AM_MEDIA_TYPE& mt);
        
    bool BindFilter(int deviceId, IBaseFilter **pFilter);
        HRESULT InitCaptureGraphBuilder();
    }
    ;

    #endif // !defined(AFX_CAPTUREVIDEO_H__973C8C7A_47A3_45B6_9B28_0A4A08003540__INCLUDED_)

    // CaptureVideo.cpp: implementation of the CCaptureVideo class.
    //
    //////////////////////////////////////////////////////////////////////

    #include 
    "stdafx.h"
    #include 
    "CaptureVideo.h"
    #include 
    "ImageProcess.h"
    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
    /////////////////////////声明全局变量//////////////////////////////////////
    BOOL bIsSavePic = FALSE;
    BOOL bIsImageProcess 
    = FALSE;
    //////////////////////////////////////////////////////////////////////
    class CSampleGrabberCB:public ISampleGrabberCB 
    {
    public:
        
    long lWidth;
        
    long lHeight;
        CCaptureVideo dlg;

        STDMETHODIMP_(ULONG) AddRef() 
    return 2; }
        STDMETHODIMP_(ULONG) Release() 
    return 1; }
        STDMETHODIMP QueryInterface(REFIID riid, 
    void ** ppv)
        
    {
            
    if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
            

                
    *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
                
    return NOERROR;
            }
     
            
            
    return E_NOINTERFACE;
        }

        
        STDMETHODIMP SampleCB( 
    double SampleTime, IMediaSample * pSample )
        
    {
            
    return 0;
        }

    //回调函数
        STDMETHODIMP BufferCB( double dblSampleTime, unsigned char* pBuffer, long lBufferSize )
        
    {
            
    if (!pBuffer)     return E_POINTER;
            
            
    if (bIsImageProcess) 
            
    {//如果条件为真则进行数字图像处理
                dlg.ImageProcessing(pBuffer, lHeight, lWidth);
            }

            
            
    return 0;
        }

    }
    ;
    CSampleGrabberCB mCB;

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    CCaptureVideo::CCaptureVideo() 
    {
        
    //COM Library Intialization
        if(FAILED(CoInitialize(NULL))) 
        
    {
            AfxMessageBox(
    "CoInitialize Failed!\r\n"); 
            
    return;
        }

        m_hWnd 
    = NULL;
        m_pVW 
    = NULL;
        m_pMC 
    = NULL;
        m_pGB 
    = NULL;
        m_pCapture 
    = NULL; 
        bIsVideoOpen 
    = FALSE;
    }


    CCaptureVideo::
    ~CCaptureVideo()
    {
        
    if (bIsVideoOpen) 
        
    {    
            
    // Stop media playback
            if(m_pMC)
            
    {
                m_pMC
    ->Stop();
            }

            
            
    if(m_pVW)
            
    {
                m_pVW
    ->put_Visible(OAFALSE);
                m_pVW
    ->put_Owner(NULL);
            }

            
            SAFE_RELEASE(m_pCapture);
            SAFE_RELEASE(m_pMC);
            SAFE_RELEASE(m_pGB);
            SAFE_RELEASE(m_pBF);
            CoUninitialize( );
        }

    }


    ///////////////////////////////////////////////////////////////////////////
    ////
    ////                        DirectShow核心代码
    ////
    ///////////////////////////////////////////////////////////////////////////

    HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
    {
        HRESULT hr;
        hr 
    = InitCaptureGraphBuilder();
        
    if (FAILED(hr))
        
    {
            AfxMessageBox(
    "Failed to get video interfaces!");
            
    return hr;
        }


        
    // Bind Device Filter. We know the device because the id was passed in
        if(!BindFilter(iDeviceID, &m_pBF))
        
    {
            AfxMessageBox(
    "未找到USB摄像头!\n请检查设备后重试!");
            PostQuitMessage(
    0);
            
    return S_FALSE;
        }

        
        hr 
    = m_pGB->AddFilter(m_pBF, L"Capture Filter");
        
    // hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, // m_pBF, NULL, NULL);
        
    // create a sample grabber
        hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
        
    if!m_pGrabber )
        
    {
            AfxMessageBox(
    "Fail to create SampleGrabber, maybe qedit.dll is not registered?");
            
    return hr;
        }


        CComQIPtr
    < IBaseFilter, &IID_IBaseFilter > pGrabBase(m_pGrabber);
        
        
    //**********设置视频格式**********//
        AM_MEDIA_TYPE mt; 
        ZeroMemory(
    &mt, sizeof(AM_MEDIA_TYPE));
        mt.majortype 
    = MEDIATYPE_Video;
        mt.subtype 
    = MEDIASUBTYPE_RGB24;  //抓取24位位图
        hr = m_pGrabber->SetMediaType(&mt);

        
    if( FAILED( hr ) )
        
    {
            AfxMessageBox(
    "Fail to set media type!");
            
    return hr;
        }

        
        hr 
    = m_pGB->AddFilter( pGrabBase, L"Grabber" );
        
    if( FAILED( hr ) )
        
    {
            AfxMessageBox(
    "Fail to put sample grabber in graph");
            
    return hr;
        }


        
    // try to render preview/capture pin
        hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
        
    if( FAILED( hr ) )
            hr 
    = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);

        
    if( FAILED( hr ) )
        
    {
            AfxMessageBox(
    "Can't build the graph");
            
    return hr;
        }

        
        hr 
    = m_pGrabber->GetConnectedMediaType( &mt );
        
        
    if ( FAILED( hr) )
        
    {
            AfxMessageBox(
    "Failt to read the connected media type");
            
    return hr;
        }


        VIDEOINFOHEADER 
    * vih = (VIDEOINFOHEADER*) mt.pbFormat;
        mCB.lWidth 
    = vih->bmiHeader.biWidth;
        mCB.lHeight 
    = vih->bmiHeader.biHeight;
        FreeMediaType(mt);
        hr 
    = m_pGrabber->SetBufferSamples( FALSE );
        hr 
    = m_pGrabber->SetOneShot( FALSE );
        hr 
    = m_pGrabber->SetCallback( &mCB, 1 );
        
        
    //*********设置视频捕捉窗口********//
        m_hWnd = hWnd ; //picture控件的句柄
        hr = m_pVW->put_Owner((OAHWND)m_hWnd);
        
    if (FAILED(hr)) return hr;
        hr 
    = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
        
    if (FAILED(hr)) return hr;

        
    if (m_pVW)
        
    {    
            CRect rc;
            ::GetClientRect(m_hWnd,
    &rc);
            m_pVW
    ->SetWindowPosition(00, rc.right, rc.bottom);//让图像充满整个窗口
        }
     

        hr 
    = m_pVW->put_Visible(OATRUE);

        
    //*********开始视频捕捉********//
        hr = m_pMC->Run();
        
    if(FAILED(hr))
        
    {
            AfxMessageBox(
    "Couldn't run the graph!");
            
    return hr;
        }


        bIsVideoOpen 
    = TRUE;
        
    return S_OK;
    }


    HRESULT CCaptureVideo::InitCaptureGraphBuilder()
    {
        HRESULT hr;
        
    // 创建IGraphBuilder接口
        hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB);
        
    // 创建ICaptureGraphBuilder2接口
        hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,IID_ICaptureGraphBuilder2, (void **&m_pCapture);
        
    if (FAILED(hr)) return hr;
        m_pCapture
    ->SetFiltergraph(m_pGB);
        hr 
    = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
        
    if (FAILED(hr)) return hr;
        hr 
    = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *)&m_pVW);
        
    if (FAILED(hr)) return hr;
        
    return hr;
    }


    bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter)
    {
        
    if (deviceId < 0return false;

        
    // enumerate all video capture devices
        CComPtr<ICreateDevEnum> pCreateDevEnum;
        HRESULT hr 
    = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
        
    if (hr != NOERROR)
        
    {
            
    return false;
        }


        CComPtr
    <IEnumMoniker> pEm;
        hr 
    = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
        
    if (hr != NOERROR) 
        
    {
            
    return false;
        }


        pEm
    ->Reset();
        ULONG cFetched;
        IMoniker 
    *pM;
        
    int index = 0;
        
    while(hr = pEm->Next(1&pM, &cFetched), hr==S_OK, index <= deviceId)
        
    {
            IPropertyBag 
    *pBag;
            hr 
    = pM->BindToStorage(00, IID_IPropertyBag, (void **)&pBag);
            
    if(SUCCEEDED(hr)) 
            
    {
                VARIANT var;
                var.vt 
    = VT_BSTR;
                hr 
    = pBag->Read(L"FriendlyName"&var, NULL);
                
    if (hr == NOERROR) 
                
    {
                    
    if (index == deviceId)
                    
    {
                        pM
    ->BindToObject(00, IID_IBaseFilter, (void**)pFilter);
                    }


                    SysFreeString(var.bstrVal);
                }

                
                pBag
    ->Release();
            }

            
            pM
    ->Release();
            index
    ++;
        }

        
        
    return true;
    }


    void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt)
    {
        
    if (mt.cbFormat != 0
        
    {
            CoTaskMemFree((PVOID)mt.pbFormat);
            
    // Strictly unnecessary but tidier
            mt.cbFormat = 0;
            mt.pbFormat 
    = NULL;
        }

        
        
    if (mt.pUnk != NULL) 
        
    {
            mt.pUnk
    ->Release();
            mt.pUnk 
    = NULL;
        }

    }
     

    //////////////////////////////////////////////////////////////////////////////////////////

    void CCaptureVideo::SwitchImageProcess(BOOL bprocess)
    {
        bIsImageProcess 
    = bprocess;
    }


    //////////////////////////////////////////////////////////////////////////////
    /////////
    /////////                         数字图像处理       
    ////////
    ///////////////////////////////////////////////////////////////////////////////

    void CCaptureVideo::ImageProcessing(unsigned char*m_pDibBits, int m_height, int m_width)
    {    
        CImageProcess::ColorToGray(m_pDibBits,m_height, m_width); 
    //彩色转灰度
        CImageProcess::ConvertGrayToWhiteBlack(m_pDibBits, m_height, m_width, 120); //二值化
    }



    主程序


    #ifdef _DEBUG
    #pragma comment(lib,"strmbasd.lib")
    #else
    #pragma comment(lib,"STRMBASE.lib")
    #endif
    #pragma comment(lib,"strmiids.lib")
    #pragma comment(lib,"quartz.lib")

    void CUSBShowDlg::OnBUTTONOpenVideo() //打开摄像头
    {
        HWND hWnd 
    = m_StaticShow.GetSafeHwnd(); 
        HRESULT hr 
    = m_cap.Init(0,hWnd); //DirectShow初始化
    }


    void CUSBShowDlg::OnBUTTONImageProcess() //启动数字图像处理开关
    {
        m_cap.SwitchImageProcess(TRUE);
    }

  • 相关阅读:
    洛谷 1850 NOIP2016提高组 换教室
    2018牛客多校第三场 C.Shuffle Cards
    2018牛客多校第一场 B.Symmetric Matrix
    2018牛客多校第一场 A.Monotonic Matrix
    2018牛客多校第一场 D.Two Graphs
    2018宁夏邀请赛L Continuous Intervals
    2018宁夏邀请赛K Vertex Covers
    BZOJ
    HDU
    ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
  • 原文地址:https://www.cnblogs.com/wqj1212/p/1133116.html
Copyright © 2011-2022 走看看