Video Motion Detection Multi Thread Class Used in DVR

-->

Environment: VC++

Introduction

In Digital Video Recording (DVR) System, one most important feature is the Video Motion Detection. Most DVR is consisted by multi video capture cards. The card number sometime will be up to 16. In order to make the system working more effectively and quickly, the best way is using Multi Thread method and each thread cooperate with one video capture card. In this way, system can monitor up 16 video motion alarm and not reduce the system performance.

System Frame

In DVR system, there are three layers in the software structure. The lowest one is the Video Capture Card drivers and sound card drivers; the middle one is the DLL and COM units; so the top one can be realized by different language such as VC, Delphi and VB.

In Video Motion Detection middleware realization, first, design one multi thread class to realize the functions. Secondly, wrap this class by the Dynamic Link Library (DLL).

Wrapped DLL Implementation

This DLL wrapper intended for simplified function using. This DLL can support the basic video motion detection functionality, such as Sample Step Number setting, Comparison value setting, Comparison Percent Number setting, Save BMP picture or Warning if video motion detected.

How to use this DLL in your application

  • Create video motion detection objects one by one by using WnWd_CreateHWDrv.
  • Set the comparison parameter by call WnWd_SetCmpStepXY, WnWd_SetCmpStepYUV and WnWd_SetCmpPercent.
  • Call WnWd_SetCurrentCard to specify one video card.
  • Call WnWd_StartHWDrv to start this video card video comparison work.
  • Call WnWd_SuspendHWDrv to stop this video card video comparison work.
  • Call WnWd_KillHWDrv to kill all video motion detection objects.

Multi Thread Video Motion Detection Class Analysis

How to create the thread

To create one thread need two steps. First, Create one video motion detection object by calling this multi thread class constructor. Secondly, Create this object's thread by calling CWinThread::CreateThread.


// This Constructor is used to create an object & initialize it.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Video Motion Detection Class Construction and initialization
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CWnDrv::CWnDrv( CWnd* pWnd, 
                WORD  wHWCardNo,
                BYTE* lpImage,
                BITMAPINFO* lpDIBHdr)
{
   m_hDatProcThread = NULL ;
   if( !wnwd_SystemInit(wHWCardNo,lpImage,lpDIBHdr) ) 
      PRINTF("(WnWizard)Initializing Error" );
} 

// In here create a real thread and set the priority of it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Create This Video Motion Detection Thread
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BOOL CWnDrv::CreateThread( DWORD dwCreateFlags, 
                           UINT nStackSize, 
                           LPSECURITY_ATTRIBUTES lpSecurityAttrs )
{

    DWORD dwThreadID;
    m_DatProcMilliSecond = 0;
    m_hDatProcThread = ::CreateThread(
                    NULL,
                    0,
                    (unsigned long (__stdcall *)
                            (void *))DatProcThreadInitialProc,
                    this,
                    CREATE_SUSPENDED,
                    &dwThreadID);

    if( m_hDatProcThread )
       ::SetThreadPriority(m_hDatProcThread,
                           THREAD_PRIORITY_HIGHEST);
    return TRUE ;
}

How to define the thread function

The thread function must be run forever, because if the function is returned, this thread will exit too. The function wnwd_VImgIsMotify() in here is used to judge the motion detection.

// In here define the thread function.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Begin This Video Motion Detection Thread to Monitor the Video Motion
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CWnDrv::DatProcThreadProc(void)
{

  for (;;)  
  {
     ::WaitForSingleObject( m_hDatProcThread,
                            m_DatProcMilliSecond);

     if( wnwd_VImgIsMotify() )
     {
        m_WarnStatus = TRUE;
        // warning 
        if(m_bIsWarn )
        MessageBeep( MB_ICONEXCLAMATION  );
        //write BMP 
        if(m_bIsSave ) 
        {
          char pTemp[100] , pTempA[100] ; 
          strcpy(pTempA, "C:\\");
          sprintf(pTemp,"MotionDetect%d", m_wHWCurrentCardNum);
          strcat(pTempA, pTemp);
          wnwd_SaveBMP((char *)((const char*)pTempA));
        }
     }
     else
       m_WarnStatus = FALSE;
     
  }
}

How to realize the video motion detection

This function sample the real time video frame image, convert to YUV format and compare to the prior one, if the result is larger than the comparison value, count the number. At last, if the counted number is larger than the comparison percent number, motion detection alarm and replace this value to the prior one.

// In here define how to compare the video frame image.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  Compare the realtime(m_pYUV) YUV value to the saved(m_pYUVSample) 
//  YUV value and saved the new value into the old one if motion detect
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BOOL CWnDrv::wnwd_VImgIsMotify()
{
   DWORD i , Count =0L;

   memcpy(m_pBtImageBak, m_pBtImage,m_lVImgSize);

   switch(m_iVGABits)
   {
   case CF_RGB15 : wnwd_RGB15_toYUV(m_pBtImageBak,
                                    m_pYUV,
                                    m_lImgWid,
                                    m_lImgHei,
                                    m_wStepX,
                                    m_wStepY );
                   break ;

   case CF_RGB16 : wnwd_RGB16_toYUV(m_pBtImageBak,
                                    m_pYUV,
                                    m_lImgWid,
                                    m_lImgHei, 
                                    m_wStepX,
                                    m_wStepY );
                   break ;

   case CF_RGB24 : wnwd_RGB24_toYUV(m_pBtImageBak,
                                    m_pYUV,
                                    m_lImgWid,
                                    m_lImgHei, 
                                    m_wStepX,
                                    m_wStepY );
                   break ;

   case CF_RGB32 : wnwd_RGB32_toYUV(m_pBtImageBak,
                                    m_pYUV,
                                    m_lImgWid,
                                    m_lImgHei,
                                    m_wStepX,
                                    m_wStepY );
                   break ;
   }

    #define Yi  m_pYUV[i]
    #define Ui  m_pYUV[i+1]
    #define Vi  m_pYUV[i+2]
    #define Ys  m_pYUVSample[i]
    #define Us  m_pYUVSample[i+1]
    #define Vs  m_pYUVSample[i+2]

   for(i=0 ; i < m_lYUVSize; i+=3)
   {
      if( abs(Yi - Ys )   > m_cStepY || //Y 
          abs(Ui - Us )   > m_cStepU || //CB 
          abs(Vi - Vs )   > m_cStepV )  //CR 
        Count ++;
     
      if( Count > m_lYUVSampleSize ) break ;

   }

   if( Count > m_lYUVSampleSize ) 
   {
      memcpy(m_pYUVSample , m_pYUV , m_lYUVSize );
      return TRUE ;
   }

   return  FALSE ;
}

Demo programs

Included is one demo program in common workspace file. Project was compiled and tested with MSVC++ 5.0 & 6.0. WnWizard.dll uses CWnDrv class for real time video motion detection. The CWnDrv is a whole multi thread class and can be wrapped in another way, such as COM.

Downloads

Download demo project - 124 Kb
Download source - 7 Kb


Comments

  • Nice.

    Posted by dinus on 04/02/2004 01:27pm

    Nice article and it would be very hard to provide an example, since the author would have to present the code for driver (wdm, sys or vxd), the code for capture card initialisation (which is very unic for each type of video digitizer used) and the code for video processing. The only comment I have about this article is that the code is not efficient, since it has to convert EACH frame from RGB to YUV. It's really a lot of work. I would suggest to convert "on the fly" each pixel from RGB to YUV representation right before checking with m_cStepY, m_cStepU, m_cStepV values. An yet better solution would be to work with YUV video stream (almast all professional DVRs do that) directly and convert it to RGB only when a picture snapshot is needed (BMP, JPG...).

    Reply
  • Any example of using it??

    Posted by Legacy on 11/03/2003 12:00am

    Originally posted by: Jimmy

    This is cool ! Could anyone send me some examples ?

    Reply
  • Full project example wouild be helpful

    Posted by Legacy on 08/27/2003 12:00am

    Originally posted by: Ian

    same as the others really. An explanation of an executable to use, and how to specify and interact with particular capture cards if the system has more than one. I want to be able to detect motion and send notification to a remote device via the network by email or sms. The dll compiles OK, but you need to make sure that in VC++ , project , project settings, You set "settings for" to "all configurations", and in the General tab, set "Microsoft Foundation Classes" to "Use MFC in a shared DLL". Then select OK.

    Reply
  • I'm disapointed : your "motion bla-bla there" is a simple BMP to BMP YUV comparator

    Posted by Legacy on 06/18/2003 12:00am

    Originally posted by: doris

    Sir,
    As your "captured images" come from a camera capture card with it's own DLLs, etc, where damned is your video programming contribution there ? I'm a little bit disapointed.

    Reply
  • 请教,怎么实现分时采集?

    Posted by Legacy on 04/25/2003 12:00am

    Originally posted by: Super

    即单芯片如何实现同时采集多路(比如4路)

    Reply
  • anyone got any examples

    Posted by Legacy on 04/19/2003 12:00am

    Originally posted by: yaniv

    this looks intresting,

    am i suppose to use this
    BOOL CWnDrv::wnwd_SystemInit (WORD wHWCurrentCardNum,BYTE* lpImage,BITMAPINFO* lpDIBHdr)
    {

    to do my motion detection?

    a good example would be very handy.

    cheers


    Reply
  • anyone got any examples

    Posted by Legacy on 04/19/2003 12:00am

    Originally posted by: yaniv

    this looks intresting,

    am i suppose to use this
    BOOL CWnDrv::wnwd_SystemInit (WORD wHWCurrentCardNum,BYTE* lpImage,BITMAPINFO* lpDIBHdr)
    {

    to do my motion detection?

    a good example would be very handy.

    cheers


    Reply
  • Need VCD output code

    Posted by Legacy on 12/22/2002 12:00am

    Originally posted by: Pat O'Neil

    Does anyone know where I can find code to write out VCD's?

    Thanks
    Pat

    Reply
  • Need VCD output code

    Posted by Legacy on 12/22/2002 12:00am

    Originally posted by: Pat O'Neil

    Does anyone know where I can find code to write out VCD's?

    Thanks
    Pat

    Reply
  • any simple demo of using it ?

    Posted by Legacy on 08/15/2002 12:00am

    Originally posted by: gemiur

    This is very cool, but is there a simple demo ? Can you please send it to me ? thanks a lot!

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds