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

📄 handvufilter.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: HandVuFilter.cpp,v 1.22 2005/10/30 23:00:43 matz Exp $**/#include "StdAfx.h"
#include <initguid.h>
#if (1100 > _MSC_VER)
#include <olectlid.h>
#else
#include <olectl.h>
#endif

//#define USE_FDL

#include "HandVuFilterGUIDs.h"
#include "Common.h"
#include "HandVuFilter.h"
#include "HandVuFilterProp.h"
#include "MaintenanceApp.h"
#ifdef USE_FDL
#include "FrameDataLib.h"
#endif USE_FDL

#ifdef HAVE_USER_STUDY
#include "../hv_UserStudy/UserStudyA.h"
#include "../hv_UserStudy/UserStudyB.h"
#endif HAVE_USER_STUDY

#include "HandVu.h"

// wrong #define causes a warning in ipl.h ... annoying:
//#undef _VXWORKS
#include <CV.h>
#include "resource.h"

#ifndef M_PI
#define M_PI 3.141592653589793
#endif /* M_PI */





// Setup information

const AMOVIESETUP_MEDIATYPE sudPinTypes =
  {
    &MEDIATYPE_Video,       // Major type
    &MEDIASUBTYPE_NULL      // Minor type
  };

const AMOVIESETUP_PIN sudpPins[] =
  {
    { L"Input",             // Pins string name
      FALSE,                // Is it rendered
      FALSE,                // Is it an output
      FALSE,                // Are we allowed none
      FALSE,                // And allowed many
      &CLSID_NULL,          // Connects to filter
      NULL,                 // Connects to pin
      1,                    // Number of types
      &sudPinTypes          // Pin information
    },
    { L"Output",            // Pins string name
      FALSE,                // Is it rendered
      TRUE,                 // Is it an output
      FALSE,                // Are we allowed none
      FALSE,                // And allowed many
      &CLSID_NULL,          // Connects to filter
      NULL,                 // Connects to pin
      1,                    // Number of types
      &sudPinTypes          // Pin information
    }
  };

const AMOVIESETUP_FILTER sudHandVuFilter =
  {
    &CLSID_HandVuFilter,         // Filter CLSID
    L"HandVuFilter",         // String name
    MERIT_DO_NOT_USE,       // Filter merit
    2,                      // Number of pins
    sudpPins                // Pin information
  };


// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance

CFactoryTemplate g_Templates[] = {
  { L"HandVuFilter (Filter)"
    , &CLSID_HandVuFilter
    , CHandVuFilter::CreateInstance
    , NULL
    , &sudHandVuFilter }
  ,
  { L"HandVuFilter (Property Page)"
    , &CLSID_HandVuFilterPropertyPage
    , CHandVuFilterProperties::CreateInstance }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);


//
// DllRegisterServer
//
// Handles sample registry and unregistry
//
STDAPI DllRegisterServer()
{
  return AMovieDllRegisterServer2( TRUE );
} // DllRegisterServer


//
// DllUnregisterServer
//
STDAPI DllUnregisterServer()
{
  return AMovieDllRegisterServer2( FALSE );
} // DllUnregisterServer


//
// Constructor
//
CHandVuFilter::CHandVuFilter(TCHAR *tszName,
                               LPUNKNOWN punk,
                               HRESULT *phr,
                               bool bModifiesData /* = true */)
: CTransInPlaceFilter(tszName, punk, CLSID_HandVuFilter, phr, bModifiesData),
  m_img_bottom_up(false),
  m_cxImage(-1),
  m_cyImage(-1),
  m_show_maintenanceapp(false),
  m_FDL_only(false),
  m_take_one_snapshot(false),
  m_is_initialized(false),
  m_FDL_is_initialized(false),
  m_pColorHeader(NULL),
  m_pOverlay(NULL),
#ifdef HAVE_USER_STUDY
  m_pUserStudyA(NULL),
  m_pUserStudyB(NULL),
#endif
  CPersistStream(punk, phr)
{
  string root_dir("C:\\hv_tmp");
  _mkdir(root_dir.c_str());
  string fname_root(root_dir + "\\hvsnap_");  hvSetSaveFilenameRoot(fname_root);
  m_params.immediate_apply = true;

  // debugging:
  DbgSetModuleLevel(LOG_CUSTOM1, 3);
} // (Constructor)

CHandVuFilter::~CHandVuFilter()
{
  hvUninitialize();
}

//
// CreateInstance
//
// Provide the way for COM to create a HandVuFilter object
//
CUnknown *CHandVuFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
{
  CHandVuFilter *pNewObject =
    new CHandVuFilter(NAME("HandVuFilter"), punk, phr);
  if (pNewObject == NULL) {
    *phr = E_OUTOFMEMORY;
  }
  return pNewObject;
} // CreateInstance


//
// NonDelegatingQueryInterface
//
// Reveals IHandVuFilter and ISpecifyPropertyPages
//
STDMETHODIMP CHandVuFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
  CheckPointer(ppv,E_POINTER);

  if (riid == IID_IHandVuFilter) {
    return GetInterface((IHandVuFilter *) this, ppv);
  } else if (riid == IID_ISpecifyPropertyPages) {
    return GetInterface((ISpecifyPropertyPages *) this, ppv);
  } else {
    return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
  }
} // NonDelegatingQueryInterface


//
// Transform (in place)
//
HRESULT CHandVuFilter::Transform(IMediaSample *pMediaSample)
{
#if 0
  static dropme = false;
  if (dropme) {
    dropme = false;
    m_bSampleSkipped = true;
    return S_FALSE;
  } else {
    dropme = true;
  }
#endif //0 

  CAutoLock lock(&m_HandVuFilterLock);
  AM_MEDIA_TYPE* pType = &m_pInput->CurrentMediaType();
  VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat;

  BYTE *pData;                // Pointer to the actual image buffer
  long lDataLen;              // Holds length of any given sample

  pMediaSample->GetPointer(&pData);
  lDataLen = pMediaSample->GetSize();
  m_bSampleSkipped = false;

  if (!m_is_initialized) {
    VERBOSE0(3, "HandVuFilter: init during playback");

    // Get the image properties from the BITMAPINFOHEADER
    int iPixelSize = pvi->bmiHeader.biBitCount / 8;
    int width      = pvi->bmiHeader.biWidth;
    int height     = pvi->bmiHeader.biHeight;
    
    HRESULT hr = Initialize(width, height, iPixelSize, NULL);
    if (!SUCCEEDED(hr)) {
      throw HVException("HandVuFilter: concurrent initialization");
    }
  }

  { // test if change from initialization
    int width      = pvi->bmiHeader.biWidth;
    int height     = pvi->bmiHeader.biHeight;
    bool img_bottom_up = true;
    if (height<0) {
      // norm for RGB images
      img_bottom_up = false;
      height = -height;
    }
    if (width!=m_cxImage || height!=m_cyImage || img_bottom_up!=m_img_bottom_up) {
      VERBOSE0(1, "HandVuFilter: format changed!");
      throw HVException("HandVuFilter: format changed!");
    }
  }

  m_pColorHeader->imageData = (char*) pData;
  m_pColorHeader->imageSize = lDataLen;

  REFERENCE_TIME st_start, st_end;
  pMediaSample->GetTime(&st_start, &st_end);
  m_t_sample = st_start/10;

#ifdef HAVE_USER_STUDY
  // check DV input for marks
  if (m_pUserStudyB) {
    if (!m_pIAMTCReader) {
      AfxMessageBox("need time code reader for StudyHV2");
    } else {
      m_pUserStudyB->AtTimecode(GetTimecode());
    }
  }
#endif

  if (m_img_bottom_up) {
    cvMirror(m_pColorHeader, NULL, 0); // flip on horizontal axis
  }

  // ------- main library call ---------
  VERBOSE0(5, "HandVuFilter: will process frame");  hvAction action = HV_INVALID_ACTION;
  action = hvProcessFrame(m_pColorHeader);
  VERBOSE0(5, "HandVuFilter: HandVu finished processing frame");  // -------

  for (int i=0; i<(int)m_HVFListenerPtrs.size(); i++) {
    m_HVFListenerPtrs[i]->FrameTransformed(action!=HV_DROP_FRAME);
  }

  if (action==HV_DROP_FRAME) {
    // HandVu recommends dropping the frame entirely
#ifdef HAVE_USER_STUDY
    if (m_pUserStudyA) {
      m_pUserStudyA->DontDraw(m_pColorHeader);
    }
#endif
    m_bSampleSkipped = true;
    VERBOSE0(3, "HandVuFilter: dropping frame");
    return S_FALSE;
  } else if (action==HV_SKIP_FRAME) {
    // HandVu recommends displaying the frame, but not doing any further
    // processing on it - keep going
  } else if (action==HV_PROCESS_FRAME) {
    // full processing was done and is recommended for following steps;
    // keep going
  } else {
    ASSERT(0); // unknown action
  }

  if (m_show_maintenanceapp) {
    ASSERT(m_pOverlay);
    //
    // overlay
    //
    hvState state;
    hvGetState(0, state);    COverlayEvent event;
    event.m_ptr1_tracked = state.tracked;
    event.m_ptr1_recognized = state.recognized;
    event.m_ptr1_x = state.center_xpos;
    event.m_ptr1_y = state.center_ypos;
    event.m_ptr1_type = state.posture;
    m_pOverlay->Tracked(event);    m_pOverlay->Draw(m_pColorHeader);
  }

#ifdef HAVE_USER_STUDY
  if (m_pUserStudyA) {
    hvVState state;
    hvGetState(0, state);    COverlayEvent event;
    event.m_ptr1_tracked = state.tracked;
    event.m_ptr1_recognized = state.recognized;
    event.m_ptr1_x = state.center_xpos;
    event.m_ptr1_y = state.center_ypos;
    event.m_ptr1_type = state.posture;
    m_pUserStudyA->Tracked(event);
    m_pUserStudyA->Draw(m_pColorHeader);
  }

  if (m_pUserStudyB) {
    hvState state;
    hvGetState(0, state);    COverlayEvent event;
    event.m_ptr1_tracked = state.tracked;
    event.m_ptr1_recognized = state.recognized;
    event.m_ptr1_x = state.center_xpos;
    event.m_ptr1_y = state.center_ypos;
    event.m_ptr1_type = state.posture;
    m_pUserStudyB->Tracked(event);
    m_pUserStudyB->Draw(m_pColorHeader);
  }
#endif

  if (m_take_one_snapshot) {
    m_take_one_snapshot = false;
    SaveImageArea(m_pColorHeader);
  }

#ifdef USE_FDL
  if (m_FDL_only && action==HV_PROCESS_FRAME) {
    if (!m_FDL_is_initialized) {
      int iPixelSize = pvi->bmiHeader.biBitCount / 8;
      FDL_Initialize(m_cxImage, m_cyImage, iPixelSize);
      m_FDL_is_initialized = true;
    }
    FDL_PutImage((BYTE*) m_pColorHeader->imageData);
    m_bSampleSkipped = true;
    VERBOSE0(4, "HandVuFilter: frame sent to FDL, no display");
    return S_FALSE;
  }
#endif USE_FDL

  if (m_img_bottom_up) {
    cvMirror(m_pColorHeader, NULL, 0); // flip on horizontal axis
  }

  VERBOSE0(3, "HandVuFilter: processed frame");

  return NOERROR;
} // Transform (in place)


RefTime CHandVuFilter::GetSampleTimeUsec() const
{
  return m_t_sample;
}

RefTime CHandVuFilter::GetCurrentTimeUsec() const
{
  if (m_tStart.m_time==0) {
    return 0;
  }

  CRefTime t_curr;
  ((CHandVuFilter*)this)->StreamTime(t_curr);
  return t_curr.m_time/10;
}




// Check the input type is OK - return an error otherwise

HRESULT CHandVuFilter::CheckInputType(const CMediaType *mtIn)
{
  // check this is a VIDEOINFOHEADER type
  if (*mtIn->FormatType() != FORMAT_VideoInfo) {
    return E_INVALIDARG;
  }

  // Can we transform this type
  if (CanPerformHandVuFilter(mtIn)) {
    return NOERROR;
  }
  return E_FAIL;
}


//
// Checktransform
//
// Check a transform can be done between these formats
//
HRESULT CHandVuFilter::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
  if (CanPerformHandVuFilter(mtIn)) {
    if (*mtIn == *mtOut) {
      return NOERROR;
    }
  }
  return E_FAIL;
} // CheckTransform


//
// DecideBufferSize
//
// Tell the output pin's allocator what size buffers we
// require. Can only do this when the input is connected
//
HRESULT CHandVuFilter::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties)
{
  // Is the input pin connected

  if (m_pInput->IsConnected() == FALSE) {

⌨️ 快捷键说明

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