Five of the kinect application series based on Dragonboard 410c - face recognition implementation code

In the previous tutorial, I told you about building a kinect application based on the Dragonboard 410c development board to implement automatic follow-up robots. Today we talk about implementing face recognition.

First, the core code:
//------------------------------------------------ ------------------------------
//
// Copyright (c) Microsoft CorporaTIon. All rights reserved.
//
//------------------------------------------------ ------------------------------
// Defines the entry point for the applicaTIon.
//
#include "stdafx.h"
#include "SingleFace.h"
#include "EggAvatar.h"
#include
#include "FTHelper.h"
Class SingleFace
{
Public:
SingleFace ()
: m_hInst ( NULL )
, m_hWnd ( NULL )
, m_hAccelTable ( NULL )
, m_pImageBuffer ( NULL )
, m_pVideoBuffer ( NULL )
, m_depthType ( NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX )
, m_colorType ( NUI_IMAGE_TYPE_COLOR )
, m_depthRes ( NUI_IMAGE_RESOLUTION_320x240 )
, m_colorRes ( NUI_IMAGE_RESOLUTION_640x480 )
, m_bNearMode ( TRUE )
, m_bSeatedSkeletonMode ( FALSE )
{}
Int Run ( HINSTANCE hInst , PWSTR lpCmdLine , int nCmdShow );
Protected:
BOOL InitInstance ( HINSTANCE hInst , PWSTR lpCmdLine , int nCmdShow );
Void ParseCmdString ( PWSTR lpCmdLine );
Void UninitInstance ();
ATOM RegisterClass ( PCWSTR szWindowClass );
Static LRESULT CALLBACK WndProcStatic ( HWND hwnd , UINT message , WPARAM wParam , LPARAM lParam );
LRESULT CALLBACK WndProc ( HWND hwnd , UINT message , WPARAM wParam , LPARAM lParam );
Static INT_PTR CALLBACK About ( HWND hwnd , UINT message , WPARAM wParam , LPARAM lParam );
BOOL PaintWindow ( HDC hdc , HWND hWnd );
BOOL ShowVideo ( HDC hdc , int width , int height , int originX , int originY );
BOOL ShowEggAvatar ( HDC hdc , int width , int height , int originX , int originY );
Static void FTHelperCallingBack ( LPVOID lpParam );
Static int const MaxLoadStringChars = 100 ;
HINSTANCE m_hInst ;
HWND m_hWnd ;
HACCEL m_hAccelTable ;
EggAvatar m_eggavatar ;
FTHelper m_FTHelper ;
IFTImage * m_pImageBuffer ;
IFTImage * m_pVideoBuffer ;
NUI_IMAGE_TYPE m_depthType ;
NUI_IMAGE_TYPE m_colorType ;
NUI_IMAGE_RESOLUTION m_depthRes ;
NUI_IMAGE_RESOLUTION m_colorRes ;
BOOL m_bNearMode ;
BOOL m_bSeatedSkeletonMode ;
};
// Run the SingleFace application.
Int SingleFace :: Run ( HINSTANCE hInst , PWSTR lpCmdLine , int nCmdShow )
{
MSG msg = { static_cast < HWND > ( 0 ), static_cast < UINT > ( 0 ), static_cast < WPARAM > ( - 1 )};
If ( InitInstance ( hInst , lpCmdLine , nCmdShow ))
{
// Main message loop:
While ( GetMessage ( & msg , NULL , 0 , 0 ))
{
If ( ! TranslateAccelerator ( msg . hwnd , m_hAccelTable , & msg ))
{
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
}
}
UninitInstance ();
Return ( int ) msg . wParam ;
}
// In this function, we save the instance handle, then create and display the main program window.
BOOL SingleFace :: InitInstance ( HINSTANCE hInstance , PWSTR lpCmdLine , int nCmdShow )
{
m_hInst = hInstance ; // Store instance handle in our global variable
ParseCmdString ( lpCmdLine );
WCHAR szTitle [ MaxLoadStringChars ]; // The title bar text
LoadString ( m_hInst , IDS_APP_TITLE , szTitle , ARRAYSIZE ( szTitle ));
Static const PCWSTR RES_MAP [] = { L"80x60" , L"320x240" , L"640x480" , L"1280x960" };
Static const PCWSTR IMG_MAP [] = { L"PLAYERID" , L"RGB" , L"YUV" , L"YUV_RAW" , L"DEPTH" };
// Add mode params in title
WCHAR szTitleComplete [ MAX_PATH ];
Swprintf_s ( szTitleComplete , L"%s -- Depth:%s:%s Color:%s:%s NearMode:%s, SeatedSkeleton:%s" , szTitle ,
IMG_MAP [ m_depthType ], ( m_depthRes < 0 ) ? L"ERROR" : RES_MAP [ m_depthRes ], IMG_MAP [ m_colorType ], ( m_colorRes < 0 ) ? L"ERROR" : RES_MAP [ m_colorRes ], m_bNearMode ? L"ON" : L "OFF" ,
m_bSeatedSkeletonMode ? L"ON" : L"OFF" );
WCHAR szWindowClass [ MaxLoadStringChars ]; // the main window class name
LoadString ( m_hInst , IDC_SINGLEFACE , szWindowClass , ARRAYSIZE ( szWindowClass ));
RegisterClass ( szWindowClass );
m_hAccelTable = LoadAccelerators ( hInstance , MAKEINTRESOURCE ( IDC_SINGLEFACE ));
m_pImageBuffer = FTCreateImage ();
m_pVideoBuffer = FTCreateImage ();
m_hWnd = CreateWindow ( szWindowClass , szTitleComplete , WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT , 0 , CW_USEDEFAULT , 0 , NULL , NULL , m_hInst , this );
If ( ! m_hWnd )
{
Return FALSE ;
}
ShowWindow ( m_hWnd , nCmdShow );
UpdateWindow ( m_hWnd );
Return SUCCEEDED ( m_FTHelper . Init ( m_hWnd ,
FTHelperCallingBack ,
This ,
m_depthType ,
m_depthRes ,
m_bNearMode ,
TRUE , // if near mode doesn't work, fall back to default mode
m_colorType ,
m_colorRes ,
m_bSeatedSkeletonMode ));
}
Void SingleFace :: UninitInstance ()
{
// Clean up the memory allocated for Face Tracking and rendering.
m_FTHelper . Stop ();
If ( m_hAccelTable )
{
DestroyAcceleratorTable ( m_hAccelTable );
m_hAccelTable = NULL ;
}
DestroyWindow ( m_hWnd );
m_hWnd = NULL ;
If ( m_pImageBuffer )
{
m_pImageBuffer -> Release ();
m_pImageBuffer = NULL ;
}
If ( m_pVideoBuffer )
{
m_pVideoBuffer -> Release ();
m_pVideoBuffer = NULL ;
}
}
// Register the window class.
ATOM SingleFace :: RegisterClass ( PCWSTR szWindowClass )
{
WNDCLASSEX wcex = { 0 };
Wcex . cbSize = sizeof ( WNDCLASSEX );
Wcex . style = CS_HREDRAW | CS_VREDRAW ;
Wcex . lpfnWndProc = & SingleFace :: WndProcStatic ;
Wcex . cbClsExtra = 0 ;
Wcex . cbWndExtra = 0 ;
Wcex . hInstance = m_hInst ;
Wcex . hIcon = LoadIcon ( m_hInst , MAKEINTRESOURCE ( IDI_SINGLEFACE ));
Wcex . hCursor = LoadCursor ( NULL , IDC_ARROW );
Wcex . hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
Wcex . lpszMenuName = MAKEINTRESOURCE ( IDC_SINGLEFACE );
Wcex . lpszClassName = szWindowClass ;
Return RegisterClassEx ( & wcex );
}
LRESULT CALLBACK SingleFace :: WndProcStatic ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam )
{
Static SingleFace * pThis = NULL ; // cheating, but since there is just one window now, it will suffice.
If ( WM_CREATE == message )
{
pThis = reinterpret_cast < SingleFace *> ( reinterpret_cast < CREATESTRUCT *> ( lParam ) -> lpCreateParams );
}
Return pThis ? pThis -> WndProc ( hWnd , message , wParam , lParam ) : DefWindowProc ( hWnd , message , wParam , lParam );
}
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_KEYUP - Exit in response to ESC key
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
LRESULT CALLBACK SingleFace :: WndProc ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam )
{
UINT wmId , wmEvent ;
PAINTSTRUCT ps ;
HDC hdc ;
Switch ( message )
{
Case WM_COMMAND :
wmId = LOWORD ( wParam );
wmEvent = HIWORD ( wParam );
// Parse the menu selections:
Switch ( wmId )
{
case IDM_ABOUT:
DialogBox ( m_hInst , MAKEINTRESOURCE ( IDD_ABOUTBOX ), hWnd , About );
Break ;
case IDM_EXIT:
PostQuitMessage ( 0 );
Break ;
Default:
Return DefWindowProc ( hWnd , message , wParam , lParam );
}
Break ;
case WM_KEYUP:
If ( wParam == VK_ESCAPE )
{
PostQuitMessage ( 0 );
}
Break ;
Case WM_PAINT :
Hdc = BeginPaint ( hWnd , & ps );
// Draw the avatar window and the video window
PaintWindow ( hdc , hWnd );
EndPaint ( hWnd , & ps );
Break ;
case WM_DESTROY:
PostQuitMessage ( 0 );
Break ;
Default:
Return DefWindowProc ( hWnd , message , wParam , lParam );
}
Return 0 ;
}
// Message handler for about box.
INT_PTR CALLBACK SingleFace :: About ( HWND hDlg , UINT message , WPARAM wParam , LPARAM lParam )
{
UNREFERENCED_PARAMETER ( lParam );
Switch ( message )
{
case WM_INITDIALOG:
Return ( INT_PTR ) TRUE ;
Case WM_COMMAND :
If ( LOWORD ( wParam ) == IDOK || LOWORD ( wParam ) == IDCANCEL )
{
EndDialog ( hDlg , LOWORD ( wParam ));
Return ( INT_PTR ) TRUE ;
}
Break ;
}
Return ( INT_PTR ) FALSE ;
}
// Drawing the video window
BOOL SingleFace :: ShowVideo ( HDC hdc , int width , int height , int originX , int originY )
{
BOOL ret = TRUE ;
// Now, copy a fraction of the camera image into the screen.
IFTImage * colorImage = m_FTHelper . GetColorImage ();
If ( colorImage )
{
Int iWidth = colorImage -> GetWidth ();
Int iHeight = colorImage -> GetHeight ();
If ( iWidth > 0 && iHeight > 0 )
{
Int iTop = 0 ;
Int iBottom = iHeight ;
Int iLeft = 0 ;
Int iRight = iWidth ;
// Keep a separate buffer.
If ( m_pVideoBuffer && SUCCEEDED ( m_pVideoBuffer -> Allocate ( iWidth , iHeight , FTIMAGEFORMAT_UINT8_B8G8R8A8 )))
{
// Copy do the video buffer while converting bytes
colorImage -> CopyTo ( m_pVideoBuffer , NULL , 0 , 0 );
// Compute the best approximate copy ratio.
Float w1 = ( float ) iHeight * ( float ) width ;
Float w2 = ( float ) iWidth * ( float ) height ;
If ( w2 > w1 && height > 0 )
{
// video image too wide
Float wx = w1 / height ;
iLeft = ( int ) max ( 0 , m_FTHelper . GetXCenterFace () - wx / 2 );
iRight = iLeft + ( int ) wx ;
If ( iRight > iWidth )
{
iRight = iWidth ;
iLeft = iRight - ( int ) wx ;
}
}
Else if ( w1 > w2 && width > 0 )
{
// video image too narrow
Float hy = w2 / width ;
iTop = ( int ) max ( 0 , m_FTHelper . GetYCenterFace () - hy / 2 );
iBottom = iTop + ( int ) hy ;
If ( iBottom > iHeight )
{
iBottom = iHeight ;
iTop = iBottom - ( int ) hy ;
}
}
Int const bmpPixSize = m_pVideoBuffer -> GetBytesPerPixel ();
SetStretchBltMode ( hdc , HALFTONE );
BITMAPINFO bmi = { sizeof ( BITMAPINFO ), iWidth , iHeight , 1 , static_cast < WORD > ( bmpPixSize * CHAR_BIT ), BI_RGB , m_pVideoBuffer -> GetStride () * iHeight , 5000 , 5000 , 0 , 0 };
If ( 0 == StretchDIBits ( hdc , originX , originY , width , height ,
iLeft , iBottom , iRight - iLeft , iTop - iBottom , m_pVideoBuffer -> GetBuffer (), & bmi , DIB_RGB_COLORS , SRCCOPY ))
{
Ret = FALSE ;
}
}
}
}
Return ret ;
}
// Drawing code
BOOL SingleFace :: ShowEggAvatar ( HDC hdc , int width , int height , int originX , int originY )
{
Static int errCount = 0 ;
BOOL ret = FALSE ;
If ( m_pImageBuffer && SUCCEEDED ( m_pImageBuffer -> Allocate ( width , height , FTIMAGEFORMAT_UINT8_B8G8R8A8 )))
{
memset (m_pImageBuffer -> GetBuffer () , 0, m_pImageBuffer -> GetStride () * height); // clear to black
M_eggavatar . SetScaleAndTranslationToWindow ( height , width );
M_eggavatar . DrawImage ( m_pImageBuffer );
BITMAPINFO bmi = { sizeof ( BITMAPINFO ), width , height , 1 , static_cast < WORD > ( m_pImageBuffer -> GetBytesPerPixel () * CHAR_BIT ), BI_RGB , m_pImageBuffer -> GetStride () * height , 5000 , 5000 , 0 , 0 };
errCount += ( 0 == StretchDIBits ( hdc , 0 , 0 , width , height , 0 , 0 , width , height , m_pImageBuffer -> GetBuffer (), & bmi , DIB_RGB_COLORS , SRCCOPY ));
Ret = TRUE ;
}
Return ret ;
}
// Draw the egg head and the camera video with the mask superimposed.
BOOL SingleFace :: PaintWindow ( HDC hdc , HWND hWnd )
{
Static int errCount = 0 ;
BOOL ret = FALSE ;
RECT rect ;
GetClientRect ( hWnd , & rect );
Int width = rect . right - rect . left ;
Int height = rect . bottom - rect . top ;
Int halfWidth = width / 2 ;
// Show the video on the right of the window
errCount += ! ShowVideo ( hdc , width - halfWidth , height , halfWidth , 0 );
// Draw the egg avatar on the left of the window
errCount += ! ShowEggAvatar ( hdc , halfWidth , height , 0 , 0 );
Horizontal Capacitive Touch Display

capacitive Touch Screen products,advertising display screens,query all-in-one monitors,widely used in our life.The Flat Panel Displays LCD advertising message information Activpanel release system is prepared by the company`s store owners in advance. Digital Signage Media Player digital signage for chromecast,digital signage for schools,digital signage media player,The Digital Signage Displays audience does not need to increase personal investment and consumption costs, but only needs to "focus on" resources. Flat Panel Displays media player for digital signage This is easy to accept for everyone. At this point, the popularization of advertising words on LCD screens is a kind of work that is profitable and has the characteristics of Interactive Flat Panel social development and Digital Signage Displays public welfare.

capacitive touch display screen,20 points capacitive touch technology, widely used in different industries

Jumei Video(Shenzhen)Co.,Ltd , https://www.jmsxdisplay.com

Posted on