⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxmanager.cpp

📁 tracciatore di mani con webcam
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**  * HandVu - a library for computer vision-based hand gesture  * recognition.  * Copyright (C) 2004 Mathias Kolsch, matz@cs.ucsb.edu  *  * This program is free software; you can redistribute it and/or  * modify it under the terms of the GNU General Public License  * as published by the Free Software Foundation; either version 2  * of the License, or (at your option) any later version.  *  * This program is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  * GNU General Public License for more details.  *  * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place - Suite 330,   * Boston, MA  02111-1307, USA.  *  * $Id: DXManager.cpp,v 1.14 2005/10/30 23:00:43 matz Exp $**/#include "stdafx.h"
#include "HandVuFilterGUIDs.h"
#include <initguid.h> // need this before MainFrm.h
#include "Common.h"
#include "DXManager.h"
#include "DXAppView.h"
#include "Dvdmedia.h"
#include "Exceptions.h"

DXManager::DXManager() :
  m_video_scale(1.0),
  m_pParentView(NULL),
  m_handvu_logfilename(""),
  m_two_windows(false)
{
  NullComPtrs();

  /*
  // start GestureEventServer
  int m_gesture_server_port = 7047;
  int m_osc_port = 57120;
  string m_osc_ip = "128.111.28.75"; 
//  string m_osc_ip = "localhost"; 
  m_pGestureServer = new CGestureEventServer(m_gesture_server_port);
  m_pGestureServer->UseOSC(m_osc_ip, m_osc_port);
  m_pGestureServer->Start();
*/

  // for event timestamps
  _ftime(&m_startTime);

  // debugging
  m_ROTregister   = 0;
//  DbgInitialise(g_hInst);
  DbgSetModuleLevel(LOG_CUSTOM1, 3);
}

DXManager::~DXManager()
{
  StopPlayback();
  DestroyFilterGraph();

//  DbgDumpObjectRegister();
//  DbgTerminate();
}

void DXManager::NullComPtrs()
{
  m_GraphBuilder = NULL;
  m_MediaControl = NULL;
  m_MediaEventEx = NULL;
  m_FilterGraph = NULL;
  m_HandVuFilterProp = NULL;
  m_HandVuFilter = NULL;
  m_SourceFilter = NULL;
  m_CameraControl = NULL;
  m_VideoWindow = NULL;
  m_SourceVideoWindow = NULL;
  m_pIAMTCReader = NULL;
}

void DXManager::StartPlayback() 
{
  if (m_HandVuFilterProp) {
    HRESULT hr = m_HandVuFilterProp->AddListener(this);
    ASSERT(SUCCEEDED(hr));
  }
  if (m_MediaControl) {
    m_VideoWindow->put_Owner((OAHWND)m_pParentView->m_hWnd);
    m_VideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
    m_VideoWindow->put_MessageDrain((OAHWND)m_pParentView->m_hWnd);
    m_VideoWindow->put_Visible(OATRUE);
    /*
    if (m_MediaEventEx) {
      // Have the graph signal event via window callbacks for performance
      m_MediaEventEx->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
    }
    */
    m_MediaControl->Run();
  }
}

void DXManager::StopPlayback() 
{
  if (m_HandVuFilterProp) {
    HRESULT hr = m_HandVuFilterProp->RemoveListener(this);
    ASSERT(SUCCEEDED(hr));

  }
  if (m_MediaControl) {
    m_MediaControl->Stop();
    m_VideoWindow->put_Visible(OAFALSE);
    m_VideoWindow->put_Owner(NULL);
    m_VideoWindow->put_MessageDrain(0);
  }
}

bool DXManager::BuildGraph(bool two_windows, CDXAppView* parent)
{
  m_pParentView = parent;
  m_two_windows = two_windows;
  DestroyFilterGraph();
  bool success = RealBuildGraph();
  if (!success) {
    DestroyFilterGraph();
  }
  return success;
}

void DXManager::FrameTransformed(bool processed)
{
}

IHandVuFilter* DXManager::HV()
{
  ASSERT(m_HandVuFilterProp);
  return m_HandVuFilterProp.p;
}

void DXManager::ToggleExposureControl()
{
  SetExposureControl(-1);
}

void DXManager::SetExposureControl(int on/*=1*/)
{
  if (!m_CameraControl) {
    return;
  }

  if (!m_HandVuFilterProp) {
    return;
  }

  bool possible;
  HRESULT hr = m_HandVuFilterProp->CanAdjustExposure(&possible);
  ASSERT(SUCCEEDED(hr));
  if (!possible) {
    return;
  }

  if (on==-1) {
    bool is_on;
    hr = m_HandVuFilterProp->IsAdjustingExposure(&is_on);
    ASSERT(SUCCEEDED(hr));
    on = is_on?0:1;
  }

  if (on) {
    hr = m_HandVuFilterProp->SetAdjustExposure(true);
    ASSERT(SUCCEEDED(hr));
  } else {
    // turn it off in HandVu
    hr = m_HandVuFilterProp->SetAdjustExposure(false);
    ASSERT(SUCCEEDED(hr));
    // turn Auto exposure on in the camera itself
    SetCameraAutoExposure(true);
  }
}

/* CameraControl function
* returns true if camera was successfully set to adjust the exposure
*/
bool DXManager::SetCameraAutoExposure(bool enable) {  long exposure, flags;
  HRESULT hr = m_CameraControl->Get(CameraControl_Exposure, &exposure, &flags);
  if (SUCCEEDED(hr)) {
    if (enable) {
      flags = CameraControl_Flags_Auto;
    } else {
      flags = CameraControl_Flags_Manual;
    }
    hr = m_CameraControl->Set(CameraControl_Exposure, exposure, flags);
    if (SUCCEEDED(hr)) {
      VERBOSE1(3, "camera does %sauto-expose now", ((enable)?"":"not "));
    }
  }
  if (!SUCCEEDED(hr)) {
    VERBOSE0(2, "can't set camera to do auto-exposure");
  }

  return (SUCCEEDED(hr));
}/* CameraControl function
*/
double DXManager::GetCurrentExposure() {  if (!m_CameraControl) {
    throw HVException("no camera control found");
  }
  long minExp, maxExp, stepping_delta, dflt, flags;
  HRESULT hr = m_CameraControl->GetRange(CameraControl_Exposure, &minExp, &maxExp, 
    &stepping_delta, &dflt, &flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not get exposure range from camera control");
  }
  
  long currExp;
  hr = m_CameraControl->Get(CameraControl_Exposure, &currExp, &flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not get current exposure from camera control");
  }
  
  double newval = (double)(currExp-minExp)/(double)(maxExp-minExp);

  VERBOSE1(5, "DXManager: GetCurrentExposure = %f",
    (float)newval);

  return newval;
}/* CameraControl function
* true if change has an effect, false if step is too small*/
bool DXManager::SetExposure(double exposure) {  VERBOSE1(5, "DXManager: SetExposure(%f) ...",
    (float)exposure);

  if (!m_CameraControl) {
    throw HVException("no camera control found");
  }

  long minExp, maxExp, stepping_delta, dflt, flags;
  HRESULT hr = m_CameraControl->GetRange(CameraControl_Exposure, &minExp, &maxExp, 
    &stepping_delta, &dflt, &flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not get exposure range from camera control");
  }
  
  long oldExp;
  hr = m_CameraControl->Get(CameraControl_Exposure, &oldExp, &flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not get current exposure from camera control");
  }

  int newExp = (int) (exposure*(maxExp-minExp) + minExp);

  flags = CameraControl_Flags_Manual;
  hr = m_CameraControl->Set(CameraControl_Exposure, newExp, flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not set new exposure for camera control");
  }

  long currExp;
  hr = m_CameraControl->Get(CameraControl_Exposure, &currExp, &flags);
  if (!SUCCEEDED(hr)) {
    throw HVException("could not get current exposure from camera control");
  }

  VERBOSE1(5, "DXManager: SetExposure completed (%s)",
    (oldExp!=currExp)?"changed":"unchanged");

  return oldExp!=currExp;
}/* CameraControl function
*/
bool DXManager::CanAdjustExposure() {  return m_CameraControl!=NULL;
}



void DXManager::ToggleFullscreen()
{
  long fullscreen;
  CComPtr<IVideoWindow> vw = NULL;
  vw = m_VideoWindow;
  HRESULT hr = vw->get_FullScreenMode(&fullscreen);
  if (SUCCEEDED(hr)) {
    if (fullscreen==OATRUE) {
      fullscreen = OAFALSE;
      ReleaseCapture();
      ShowCursor(true);
      m_pParentView->SetTrapMouse(false);
    } else {
      ASSERT(fullscreen==OAFALSE);
      fullscreen = OATRUE;
      SetCapture(m_pParentView->m_hWnd);
      ShowCursor(false);
      m_pParentView->SetTrapMouse(true);
    }
  	hr = vw->put_FullScreenMode(fullscreen);
  }
  if (!SUCCEEDED(hr)) {
    AfxMessageBox("can not render in full-screen mode");
  }
}



bool DXManager::RealBuildGraph()
{
  HRESULT hr;
//  hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, 
//                        IID_ICaptureGraphBuilder2, (void **)&m_GraphBuilder);
  hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&m_GraphBuilder);
  if (!SUCCEEDED(hr) || !m_GraphBuilder) { 
    AfxMessageBox("Can't access graph builder interface");
    return false; 
  }

  CreateCamera();
  if (m_SourceFilter==0) {
    AfxMessageBox("Can't connect to a camera");
    return false;
  }

  if (!CreateHandVuFilter()) {
    AfxMessageBox("Can't create HandVu filter");
    return false;
  }


  /* create generic graph objects */
  m_GraphBuilder->QueryInterface(IID_IMediaControl,(void**)&m_MediaControl);
  m_GraphBuilder->QueryInterface(IID_IMediaEventEx,(void**)&m_MediaEventEx);
  m_GraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&m_VideoWindow );
  m_GraphBuilder->QueryInterface(IID_IFilterGraph, (void**)&m_FilterGraph);

  if (!m_FilterGraph) {
    AfxMessageBox("Can't access filter graph interface");
    return false;
  }

  if (!ConnectFilters()) {
    int device;
    for (device=1; device<=10; device++) {
      CreateCamera(device);
      if (ConnectFilters()) {
        break;
      }
    }
    if (device==11) {
      AfxMessageBox("Can't connect to a camera, tried 10 devices");
      return false;
    }
  }
#ifdef DEBUG
  // ROT debugging stuff
  hr = AddToROT(m_GraphBuilder, &m_ROTregister);
  ASSERT(SUCCEEDED(hr));
#endif // DEBUG

  return true;
}

/* link the created filters */
bool DXManager::ConnectFilters()
{
  HRESULT hr;
  bool success = false;

  CComPtr<IPin> pSourceOut          = NULL;
  CComPtr<IPin> pHandVuIn           = NULL;
  CComPtr<IPin> pHandVuOut          = NULL;
  CComPtr<IBaseFilter> pSmartTee    = NULL;
  CComPtr<IBaseFilter> pColorConv   = NULL;
  CComPtr<IPin> pProcessThis        = NULL;
  CComPtr<IBaseFilter> pAppRenderer = NULL;
  CComPtr<IPin> pSmartTPreviewOut   = NULL;


  // get a video output pin
  hr = AddFilter(m_SourceFilter, L"Video Source" );
  pSourceOut = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
  if (!SUCCEEDED(hr) || pSourceOut==NULL) goto release_and_return;

  // make two application windows
  if (!m_two_windows) {
    pProcessThis = pSourceOut;
  } else {
    hr = CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, 
		                      IID_IBaseFilter, (void**)&pSmartTee);
    if (!SUCCEEDED(hr)) goto release_and_return;

    hr = AddFilter(pSmartTee, L"SmartT");
    CComPtr<IPin> pSmartTIn         = GetPin(pSmartTee, PINDIR_INPUT);
    CComPtr<IPin> pSmartTCaptureOut = GetPin(pSmartTee, PINDIR_OUTPUT, 0);//, &PIN_CATEGORY_CAPTURE);
    pSmartTPreviewOut = GetPin(pSmartTee, PINDIR_OUTPUT, 1);//, &PIN_CATEGORY_PREVIEW);
    if (!SUCCEEDED(hr) || !pSmartTIn || !pSmartTCaptureOut || !pSmartTPreviewOut) goto release_and_return;

    hr = ConnectPins(pSourceOut, pSmartTIn);
    if (!SUCCEEDED(hr)) goto release_and_return;

    hr = CoCreateInstance( CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, 
		      IID_IBaseFilter, (void**)&pAppRenderer );
    if (!SUCCEEDED(hr)) goto release_and_return;

    pAppRenderer->QueryInterface(IID_IVideoWindow,(void**)&m_SourceVideoWindow);
    if (!SUCCEEDED(hr) || !m_SourceVideoWindow) goto release_and_return;

    m_SourceWin.m_pDXManager = this;
    if (m_SourceWin.m_hWnd==NULL) {
  //    m_SourceWin.CreateEx(NULL, "", "source display", WS_POPUP | WS_MAXIMIZE, CRect(10, 10, 300, 200), m_pParent, 1, NULL);
      m_SourceWin.Create(NULL, "source display", WS_CHILD, CRect(50, 50, 160, 120), m_pParentView, 1, NULL);
    }
    m_SourceVideoWindow->put_Owner((OAHWND)m_SourceWin.m_hWnd);
    m_SourceVideoWindow->put_MessageDrain((OAHWND)m_SourceWin.m_hWnd);
    m_SourceVideoWindow->SetWindowPosition(50, 50, 160, 120);

    hr = CoCreateInstance( CLSID_Colour, NULL, CLSCTX_INPROC_SERVER, 
		    IID_IBaseFilter, (void**)&pColorConv );
    if (!SUCCEEDED(hr) || !pColorConv) goto release_and_return;
    CComPtr<IPin> pColorConvIn    = GetPin(pColorConv, PINDIR_INPUT);
    CComPtr<IPin> pColorConvOut   = GetPin(pColorConv, PINDIR_OUTPUT);
    hr = AddFilter(pColorConv, L"Source Renderer" );
    if (!SUCCEEDED(hr)) goto release_and_return;

    hr = ConnectPins(pSmartTCaptureOut, pColorConvIn );
    if (!SUCCEEDED(hr)) goto release_and_return;

    pSmartTIn.Release();

    pProcessThis = pColorConvOut;
  }

  hr = AddFilter(m_HandVuFilter, L"HandVuFilter");
  pHandVuIn         = GetPin(m_HandVuFilter, PINDIR_INPUT);
  pHandVuOut        = GetPin(m_HandVuFilter, PINDIR_OUTPUT);
  if (!SUCCEEDED(hr) || !pHandVuIn || !pHandVuOut) goto release_and_return;

  hr = ConnectPins(pProcessThis, pHandVuIn);      
  if (!SUCCEEDED(hr)) goto release_and_return;

  if (!InitHandVuFilter()) goto release_and_return;

  hr = m_GraphBuilder->Render(pHandVuOut);
  if (!SUCCEEDED(hr)) goto release_and_return;

  if (m_two_windows) {
    CComPtr<IPin> pAppRendererIn    = GetPin(pAppRenderer, PINDIR_INPUT);
    hr = AddFilter(pAppRenderer, L"Source Renderer" );
    if (!SUCCEEDED(hr) || !pAppRendererIn) goto release_and_return;

    hr = ConnectPins(pSmartTPreviewOut, pAppRendererIn );
    if (!SUCCEEDED(hr)) goto release_and_return;

    m_SourceWin.EnableWindow(TRUE);
    m_SourceWin.Invalidate();

    pAppRenderer.Release();
    pAppRendererIn.Release();
//    pSmartTCaptureOut.Release();

⌨️ 快捷键说明

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