USB摄像头实时视频捕获后的视频在时候预览的时候没有时间!我希望能在视频右下角处显示记录当时捕获时的时间,并在左上角显示一条文字说明,例如说明这个摄像头的位置,比如"第三教学楼入口"这样的文字说明。

解决方案 »

  1.   

    //#include "precompile.h"
    #include "stdafx.h"
    #include "Test.h"
    //#include "version.h"#pragma comment(lib,"vfw32")
    #pragma comment(lib,"winmm")//#define vfw 1
    #define dx 2CTest::CTest()
    {
    #ifdef vfw
    m_capwnd=NULL;
    #endif

    #ifdef dx
    this->g_psCurrent  = Stopped;
    g_pVW = NULL;
    g_pMC = NULL;
    g_pME = NULL;
    g_pGraph = NULL;
    g_pCapture = NULL;
    #endif
    }CTest::~CTest()
    {}BOOL CTest::Initialize()
    {
    #ifdef vfw
    char devname[100],devversion[100];
    int index=0; // xuemh  ------no window------ m_capwnd = capCreateCaptureWindow(
    "My Capture Window VFW", // window name if pop-up
    WS_SYSMENU | WS_VISIBLE, // window style
    0, 0, 320, 270, // window position and dimensions
    0,//(HWND)Application->Handle,//(HWND) hwndParent,
    0);//(int) nID); if(m_capwnd==NULL)
    {
    cout << "capCreateCaptureWindow filed" << endl;
    return FALSE;
    } capDriverConnect(m_capwnd,0);
    capPreview(m_capwnd, TRUE); // starts preview
    capPreviewRate(m_capwnd, 66);
    capPreviewScale(m_capwnd, 1); if (SetCapturePara() == FALSE)
    {
    cout << "SetCapturePara filed" << endl;
    return FALSE;
    } capGetDriverDescription(index,devname,100,devversion,100);
    cout << "\n Driver name =" << devname << "version = " << devversion << endl;

    return TRUE;
    #endif
    #ifdef dx
    return TRUE;
    #endif
    }BOOL CTest::SetCapturePara()
    {
    CAPTUREPARMS CapParms={0};
    BOOL ret;
    capCaptureGetSetup(m_capwnd,&CapParms,sizeof(CapParms)); CapParms.fAbortLeftMouse = FALSE;
    CapParms.fAbortRightMouse = FALSE;
    CapParms.fYield = TRUE;
    CapParms.fCaptureAudio = FALSE;
    CapParms.wPercentDropForError = 50; if(capCaptureSetSetup(m_capwnd,&CapParms,sizeof(CapParms))==FALSE)
    {
    cout << "capCaptureSetSetup filed" << endl;
    return FALSE;
    }
    // Set Video Format 
    capGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo)); m_bmpinfo.bmiHeader.biWidth=IMAGE_WIDTH;
    m_bmpinfo.bmiHeader.biHeight=IMAGE_HEIGHT;
    //****************************************************************
    char* pszFileName = "c:\\1.bmp"; 
    CFile myFile; CFileException fileException; if ( !myFile.Open( pszFileName, CFile::modeCreate | 
    CFile::modeReadWrite ), &fileException ) 

    TRACE( "Can't open file %s, error = %u\n", 
    pszFileName, fileException.m_cause ); 

    myFile.Write(&m_bmpinfo, sizeof(m_bmpinfo)); 
    myFile.Close(); 
    //****************************************************************
    ret = capSetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo)); return TRUE;
    }
      

  2.   

    BOOL CTest::StartCapture()
    {
    // Start capturing ..
    if(capCaptureSequenceNoFile(m_capwnd)==FALSE)
    {
    cout << "capCaptureSequenceNoFile filed" << endl;
    return FALSE;
    }    capDlgVideoDisplay(m_capwnd); return TRUE;
    }LRESULT CALLBACK CTest::StatusCallbackProc(HWND hWnd, int nID)
    {
    if(!hWnd)
    return FALSE;

    capGetStatus(hWnd, &m_CapStatus, sizeof(m_CapStatus));
    capGetUserData(hWnd);
    SetWindowPos(hWnd, NULL, 0, 0, m_CapStatus.uiImageWidth,
    m_CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);

    if(nID == 0)
    {
    SetWindowText(hWnd, (LPSTR)"Preview Window"); 
    return (LRESULT)TRUE;
    }  return (LRESULT)TRUE; 
    } LRESULT CALLBACK CTest::ErrorCallbackProc(HWND hWnd, int nID)
    {
    if(!hWnd)
    return FALSE; if(nID == 0)
    return TRUE; return (LRESULT)TRUE; 
    }BOOL CTest::StopCapture()
    {
    capCaptureStop(m_capwnd);
    capCaptureAbort(m_capwnd);
    Sleep(500); return TRUE;
    }void CTest::Destroy()
    {
    #ifdef vfw
    if(m_capwnd==NULL) 
    return;
        
        // Stop the capturing process    
    capCaptureAbort(m_capwnd);
              
        // Disable the callback function..
    capSetCallbackOnVideoStream(m_capwnd, NULL);
         
    Sleep(300); // This delay is important...

    // Finally disconnect the driver
        capDriverDisconnect(m_capwnd);
    #endif
    #ifdef dx
        // Stop previewing data
        if (g_pMC)
            g_pMC->StopWhenReady();    g_psCurrent = Stopped;
        // Relinquish ownership (IMPORTANT!) of the video window.
        // Failing to call put_Owner can lead to assert failures within
        // the video renderer, as it still assumes that it has a valid
        // parent window.
        if(g_pVW)
        {
            g_pVW->put_Visible(OAFALSE);
            g_pVW->put_Owner(NULL);
        }
       // Release DirectShow interfaces
        SAFE_RELEASE(g_pMC);
        SAFE_RELEASE(g_pME);
        SAFE_RELEASE(g_pVW);
        SAFE_RELEASE(g_pGraph);
        SAFE_RELEASE(g_pCapture);
    #endif
    }int CTest::AllocateMemory(PBITMAPINFO &bmpinfo)
    {
    /*
    int size1,size2,size;
    BITMAPINFO tbmp;
    char  str[200]; capGetVideoFormat(m_capwnd,&tbmp,sizeof(tbmp)); size1 = getFormatSize(tbmp);
    size2 = getImageSize(tbmp);
    size = size1 + size2; cout << str <<"FormatSize = " << size1 << " imagesize = " << size2 
     << " fun_size = " << capGetVideoFormatSize(m_capwnd) << endl; bmpinfo=(BITMAPINFO *) new BYTE[size];

    if(bmpinfo==NULL)
    {
    cout << "Unable to allocate memory" << endl;
    return -1;
    } memset(bmpinfo,0,sizeof(*bmpinfo)); capGetVideoFormat(m_capwnd,bmpinfo,sizeof(*bmpinfo));
    return size1;
    */
    return NULL;
    }int CTest::getFormatSize(BITMAPINFO bmp)
    {
    int size;
    size = (bmp.bmiHeader.biSize!=0) ? bmp.bmiHeader.biSize : sizeof(BITMAPINFOHEADER); return size; //RGBQUAD is absent for 24 bit bmp image.
    }int CTest::getImageSize(BITMAPINFO bmp)
    {
    int size;
    BITMAPINFOHEADER head=bmp.bmiHeader;
    if( head.biSizeImage==0 )
    size=( head.biWidth * head.biHeight * head.biBitCount)/8;
    else
    size = head.biSizeImage; return size;
    }HRESULT CTest::CaptureVideo(HWND ghApp)
    {
    #ifdef dx
        HRESULT hr;
        IBaseFilter *pSrcFilter=NULL;
    //IBaseFilter *pText= NULL;    // Get DirectShow interfaces
        hr = GetInterfaces(ghApp);
        if (FAILED(hr))
        {
            return hr;
        }    // Attach the filter graph to the capture graph
        hr = g_pCapture->SetFiltergraph(g_pGraph);
        if (FAILED(hr))
        {
            return hr;
        }    // Use the system device enumerator and class enumerator to find
        // a video capture/preview device, such as a desktop USB video camera.
        hr = FindCaptureDevice(&pSrcFilter);
        if (FAILED(hr))
        {
            return hr;
        }
       
        // Add Capture filter to our graph.
        hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
        if (FAILED(hr))
        {
            pSrcFilter->Release();
            return hr;
        }// hr = g_pGraph->AddFilter(pText, L"SampleGrabber" );
    //    if (FAILED(hr))
    //    {
    //        pText->Release();
    //        return hr;
    //    }    // Render the preview pin on the video capture filter
        // Use this instead of g_pGraph->RenderFile
        hr = g_pCapture->RenderStream (&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
                                       pSrcFilter, NULL, NULL);
        if (FAILED(hr))
        {
            pSrcFilter->Release();
            return hr;
        }    // Now that the filter has been added to the graph and we have
        // rendered its stream, we can release this reference to the filter.
        pSrcFilter->Release();    // Set video window style and position
        hr = SetupVideoWindow(ghApp);
        if (FAILED(hr))
        {
            return hr;
        }    // Start previewing video data
        hr = g_pMC->Run();
        if (FAILED(hr))
        {
            return hr;
        } JIF(InitializeWindowlessVMR());
    BlendText(ghApp);
        // Remember current state
        g_psCurrent = Running;
            
        return S_OK;
    #else
    return NULL;
    #endif
    }
      

  3.   

    HRESULT CTest::GetInterfaces(HWND ghApp)
    {
    #ifdef dx
    HRESULT hr;
        // Create the filter graph
        hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                               IID_IGraphBuilder, (void **) &g_pGraph);    if (FAILED(hr))
            return hr;    // Create the capture graph builder
        hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
                               IID_ICaptureGraphBuilder2, (void **) &g_pCapture);
        if (FAILED(hr))
            return hr;
        
        // Obtain interfaces for media control and Video Window
        hr = g_pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &g_pMC);
        if (FAILED(hr))
            return hr;    hr = g_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &g_pVW);
        if (FAILED(hr))
            return hr;    hr = g_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &g_pME);
        if (FAILED(hr))
            return hr;    return hr;
    #else
    return NULL;
    #endif
    }HRESULT CTest::FindCaptureDevice(IBaseFilter **ppSrcFilter)
    {
    #ifdef dx
    HRESULT hr;
        IBaseFilter * pSrc = NULL;
        CComPtr <IMoniker> pMoniker =NULL;
        ULONG cFetched;    if (!ppSrcFilter)
            return E_POINTER;
        // Create the system device enumerator
        CComPtr <ICreateDevEnum> pDevEnum =NULL;    hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                               IID_ICreateDevEnum, (void **) &pDevEnum);
        if (FAILED(hr))
        {
            return hr;
        }
        // Create an enumerator for the video capture devices
        CComPtr <IEnumMoniker> pClassEnum = NULL;    hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
        if (FAILED(hr))
        {
            return hr;
        }    // If there are no enumerators for the requested type, then 
        // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
        if (pClassEnum == NULL)
        {
            return E_FAIL;
        }    // Use the first video capture device on the device list.
        // Note that if the Next() call succeeds but there are no monikers,
        // it will return S_FALSE (which is not a failure).  Therefore, we
        // check that the return code is S_OK instead of using SUCCEEDED() macro.
        if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
        {
            // Bind Moniker to a filter object
            hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
            if (FAILED(hr))
            {
                return hr;
            }
        }
        else
        {
            return E_FAIL;
        }
        // Copy the found filter pointer to the output parameter.
        // Do NOT Release() the reference, since it will still be used
        // by the calling function.
        *ppSrcFilter = pSrc;
        return hr;
    #else
    return NULL;
    #endif
    }HRESULT CTest::SetupVideoWindow(HWND ghApp)
    {
    #ifdef dx  
    HRESULT hr;
        // Set the video window to be a child of the main window
        hr = g_pVW->put_Owner((OAHWND)ghApp);
        if (FAILED(hr))
            return hr;
        
        // Set video window style
        hr = g_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
        if (FAILED(hr))
            return hr;    // Use helper function to position video window in client rect 
        // of main application window
        ResizeVideoWindow(ghApp);    // Make the video window visible, now that it is properly positioned
        hr = g_pVW->put_Visible(OATRUE);
        if (FAILED(hr))
            return hr;
        return hr;
    #else
    return NULL;
    #endif
    }void CTest::ResizeVideoWindow(HWND ghApp)
    {
    #ifdef dx 
    // Resize the video preview window to match owner window size
        if (g_pVW)
        {
            RECT rc;
            
            // Make the preview video fill our window
            GetClientRect(ghApp, &rc);
            g_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
        }
    #endif
    }void CTest::CloseInterfaces()
    {
    #ifdef dx 
    // Stop previewing data
        if (g_pMC)
            g_pMC->StopWhenReady();    g_psCurrent = Stopped;    // Relinquish ownership (IMPORTANT!) of the video window.
        // Failing to call put_Owner can lead to assert failures within
        // the video renderer, as it still assumes that it has a valid
        // parent window.
        if(g_pVW)
        {
            g_pVW->put_Visible(OAFALSE);
            g_pVW->put_Owner(NULL);
        }
       // Release DirectShow interfaces
        SAFE_RELEASE(g_pMC);
        SAFE_RELEASE(g_pME);
        SAFE_RELEASE(g_pVW);
        SAFE_RELEASE(g_pGraph);
        SAFE_RELEASE(g_pCapture);
    #endif
    }
      

  4.   

    只做过DirectShow的!自己写中间的TransForm FilterWinMM 的没做过!帮楼主顶
      

  5.   

    对于 VFW 实现的采集, 可以接获 capCreateCaptureWindow 创建的视频窗口的 WM_PAINT 消息,在里面使用窗口 dc 直接绘制,但是效果不好,会有闪烁的情况。对于 DirectShow, 可以实现自己的 Transform filter 把数据合并到视频帧上,也可以实现一个自己的 video render 处理回显。(但是都存在效率问题,需要考虑 YUV 格式的数据显示。)
      

  6.   

    保存或显示图片之前先把数据转到DC上,然后TextOut/DrawText,再取回来用