some changes

This commit is contained in:
davoudn 2024-04-14 15:15:18 +03:30
parent d91cc4a2a1
commit 8d2141fa8a
135 changed files with 16667 additions and 0 deletions

View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [UnaNancyOwen] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]

View File

@ -0,0 +1,74 @@
How to Build Sample Program
===================
How to Install Tools and Libraries
--------------------------------------
* Visual Studio 2015
In Visual Studio 2015, Visual C++ is not installed by default. When installing, be sure to choose Custom installation and then choose the C++ components you require.
Or, if Visual Studio is already installed, choose [File]>[New]>[Project]>[C++] and you will be prompted to install the necessary components.
* Kinect for Windows SDK v2.0
Please download installer, and install follow the instructions of installer.
* OpenCV 3.1.0
Please download pre-built package, and unzip the self-extracting file.
Then, Please placed OpenCV folder in any directory. ( e.g. <code>C:\Program Files\opencv</code> )
* CMake 3.6.1
Please download installer, and install follow the instructions of installer.
* Speech Platform SDK 11 ( and Kinect for Windows SDK v2.0 Language Packs (en-US) )
Please download installer for target platform, and install follow the instructions of installer.
How to Generate Project of Samples using CMake
--------------------------------------------------------
1. Run CMake GUI
2. Fill These Fields
* **Where is the source code**
This area is directory containing CMakeLists.txt file.
If you want to build all samples, please fill path of sample directory. ( e.g. <code>C:/Kinect2Sample/sample</code> )
If you want to build any one sample, please fill path of any one directory. ( e.g. <code>C:/Kinect2Sample/sample/Color</code> )
* **Where to build the binaries**
This area is directory Visual Studio project files will be generated.
By convention, Fill the path that added the <code>\/build</code> to above path. ( e.g. <code>C:/Kinect2Sample/sample/build</code> )
3. Click Configure Button
You will be prompted for compiler and target platform.
Please specify compiler and target platform to use. ( e.g. <code>Visual Studio 14 2015 Win64</code> )
Then, click finish button.
4. Fill Configuration Fields
It will be entered almost automatically.
Please check configuration settings.
Then, click configure button.
* **KINECTSDK\_DIR** ... The directory path of Kinect for Windows SDK v2.0 ( e.g. <code>C:/Program Files/Microsoft SDKs/Kinect/v2.0_1409</code> )
* **OPENCV\_DIR** ... The directory path that to search CMake configuration file for OpenCV. ( e.g. <code>C:/Program Files/opencv/build</code> )
5. Click Generate Button
If there is no errors, the Visual Studio project files will be generated into the "Where to build the binaries" directory.
6. Set Environment Variable
You might need to add OpenCV binary directory path to environment variable "PATH" to be able to run applications. (e.g. <code>C:\Program Filesopencv\build\x64\vc14\bin</code> )
The path that have to be added to environment variable will be displayed in output area of CMake GUI.
This path is depend on Compiler, Target Platform and OpenCV Directory.
How to Build and Start Samples
------------------------------------
1. Open Visual Studio Solution File ( e.g. <code>..\build\Sample.sln</code> )
2. Set Solution Configurations
Select Release from the Solution Configuration drop-down list, which is on the Standard toolbar. ( e.g. <code>Release</code> )
Release build will be enabled optimization by compiler.
3. Build Solution ( or Project )
On the Build menu, Click "Build Solution".
Or, In Solution Explorer, select the desired build target project within your solution. Then Click "Build Project".
4. Set Startup Project
In Solution Explorer, select the desired startup project within your solution.
On the Project menu, choose "Set as StartUp Project".
5. Start Without Debugging
On the Debug menu, choose "Start Without Debugging".

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Tsukasa Sugiura
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,38 @@
Kinect for Windows SDK v2 Sample Program
============================
This repository is Sample Program of Kinect for Windows SDK v2 written in Native C++.
Environment
--------------
* Visual Studio Community 2015 <sup>*1</sup>
* Kinect for Windows SDK v2.0
* Kinect for Windows SDK v2.0 Language Packs (en-US)
* Speech Platform SDK 11
* OpenCV 3.1.0 <sup>*2</sup>
* CMake 3.6.1 <sup>*3</sup>
<sup>&#042;1 This sample program need Visual Studio Community (or upper version), because depends on ATL.</sup>
<sup>&#042;2 Pre-built OpenCV that is distributed by official team does not include library for Win32 (x86) target platform. If you want to build sample program for Win32 (x86) target platform, You need build OpenCV yourself. Similarly, If it does not include library for your target compiler, You need build OpenCV yourself.</sup>
<sup>&#042;3 You need generate project of this sample program using CMake. Please read [this document](HOWTOBUILD.md) about how to generate project using CMake.</sup>
License
---------
Copyright &copy; 2016 Tsukasa SUGIURA
Distributed under the [MIT License](http://www.opensource.org/licenses/mit-license.php "MIT License | Open Source Initiative").
Contact
---------
* Tsukasa Sugiura
* <t.sugiura0204@gmail.com>
* <https://twitter.com/UnaNancyOwen>
* <http://UnaNancyOwen.com>
Reference
------------
* KINECT for Windows SDK programming - Kinect for Windows v2 sensor supported version | Shuwa System Co.,Ltd.
<http://www.shuwasystem.co.jp/products/7980html/4395.html>
* Kinect for Windows SDK 2.0 | MSDN Library
<https://msdn.microsoft.com/en-us/library/dn799271.aspx>

View File

@ -0,0 +1,23 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( AudioBeam app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "AudioBeam" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
if( KinectSDK2_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
# Additional Dependencies
target_link_libraries( AudioBeam ${KinectSDK2_LIBRARIES} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,179 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <iostream>
#include <cmath>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
if( GetKeyState( VK_ESCAPE ) < 0 ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
// Initialize Sensor
initializeSensor();
// Initialize Audio
initializeAudio();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize Audio
inline void Kinect::initializeAudio()
{
// Retrieve Audio Source
ComPtr<IAudioSource> audioSource;
ERROR_CHECK( kinect->get_AudioSource( &audioSource ) );
// Open Audio Beam Reader
ERROR_CHECK( audioSource->OpenReader( &audioBeamFrameReader ) );
}
// Finalize
void Kinect::finalize()
{
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Audio
updateAudio();
}
// Update Audio
inline void Kinect::updateAudio()
{
// Retrieve Audio Beam Frame List
ComPtr<IAudioBeamFrameList> audioBeamFrameList;
const HRESULT ret = audioBeamFrameReader->AcquireLatestBeamFrames( &audioBeamFrameList );
if( FAILED( ret ) ){
return;
}
// Retrieve Audio Beam Frame Count
UINT beamCount = 0;
ERROR_CHECK( audioBeamFrameList->get_BeamCount( &beamCount ) );
Concurrency::parallel_for( 0, static_cast<int>( beamCount ), [&]( int i ){
// Retrieve Audio Beam Frame
ComPtr<IAudioBeamFrame> audioBeamFrame;
ERROR_CHECK( audioBeamFrameList->OpenAudioBeamFrame( i, &audioBeamFrame ) );
// Retrieve Audio Beam SubFrame Count
UINT subFrameCount = 0;
ERROR_CHECK( audioBeamFrame->get_SubFrameCount( &subFrameCount ) );
Concurrency::parallel_for( 0, static_cast<int>( subFrameCount ), [&]( int j ){
// Retrieve Audio Beam SubFrame
ComPtr<IAudioBeamSubFrame> audioBeamSubFrame;
ERROR_CHECK( audioBeamFrame->GetSubFrame( j, &audioBeamSubFrame ) );
// Retrieve Beam Angle ( Radian +/- 1.0 )
ERROR_CHECK( audioBeamSubFrame->get_BeamAngle( &beamAngle ) );
// Retrieve Beam Angle Confidence ( 0.0 - 1.0 )
ERROR_CHECK( audioBeamSubFrame->get_BeamAngleConfidence( &beamAngleConfidence ) );
} );
} );
}
// Draw Data
void Kinect::draw()
{
// Draw Audio
drawAudio();
}
// Draw Audio
inline void Kinect::drawAudio()
{
// Clear Beam Angle Result Buffer
beamAngleResult.clear();
// Check Beam Angle Confidence
if( beamAngleConfidence > confidenceThreshold ){
// Convert Degree from Radian
const float degree = static_cast<float>( beamAngle * 180.0 / M_PI );
// Add Beam Angle to Result Buffer
beamAngleResult = std::to_string( degree ) + " (" + std::to_string( beamAngleConfidence ) + ")";
}
}
// Show Data
void Kinect::show()
{
// Show Audio
showAudio();
}
// Show Audio
inline void Kinect::showAudio()
{
// Check Empty Result Buffer
if( !beamAngleResult.size() ){
return;
}
// Show Result
std::cout << beamAngleResult << std::endl;
}

View File

@ -0,0 +1,70 @@
#ifndef __APP__
#define __APP__
#define _USE_MATH_DEFINES
#include <Windows.h>
#include <Kinect.h>
#include <string>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IAudioBeamFrameReader> audioBeamFrameReader;
// Audio Buffer
float beamAngle = 0.f;
float beamAngleConfidence = 0.f;
std::string beamAngleResult;
const float confidenceThreshold = 0.3f;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Audio
inline void initializeAudio();
// Finalize
void finalize();
// Update Data
void update();
// Update Audio
inline void updateAudio();
// Draw Data
void draw();
// Draw Audio
inline void drawAudio();
// Show Data
void show();
// Show Audio
inline void showAudio();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( AudioBody app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "AudioBody" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( AudioBody ${KinectSDK2_LIBRARIES} )
target_link_libraries( AudioBody ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,308 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <limits>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Audio
initializeAudio();
// Initialize Body
initializeBody();
// Initialize BodyIndex
initializeBodyIndex();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize Audio
inline void Kinect::initializeAudio()
{
// Retrieve Audio Source
ComPtr<IAudioSource> audioSource;
ERROR_CHECK( kinect->get_AudioSource( &audioSource ) );
// Open Audio Beam Reader
ERROR_CHECK( audioSource->OpenReader( &audioBeamFrameReader ) );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
// Initialize Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
}
// Initialize BodyIndex
inline void Kinect::initializeBodyIndex()
{
// Open BodyIndex Reader
ComPtr<IBodyIndexFrameSource> bodyIndexFrameSource;
ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) );
ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) );
// Retrieve BodyIndex Description
ComPtr<IFrameDescription> bodyIndexFrameDescription;
ERROR_CHECK( bodyIndexFrameSource->get_FrameDescription( &bodyIndexFrameDescription ) );
ERROR_CHECK( bodyIndexFrameDescription->get_Width( &bodyIndexWidth ) ); // 512
ERROR_CHECK( bodyIndexFrameDescription->get_Height( &bodyIndexHeight ) ); // 424
// Allocation BodyIndex Buffer
bodyIndexBuffer.resize( bodyIndexWidth * bodyIndexHeight );
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Audio
updateAudio();
// Update Body
updateBody();
// Update BodyIndex
updateBodyIndex();
}
// Update Audio
inline void Kinect::updateAudio()
{
// Initialize Tracking ID
audioTrackingId = std::numeric_limits<unsigned long long>::max() - 1;
// Retrieve Audio Beam Frame List
ComPtr<IAudioBeamFrameList> audioBeamFrameList;
const HRESULT ret = audioBeamFrameReader->AcquireLatestBeamFrames( &audioBeamFrameList );
if( FAILED( ret ) ){
return;
}
// Retrieve Audio Beam Frame Count
UINT beamCount = 0;
ERROR_CHECK( audioBeamFrameList->get_BeamCount( &beamCount ) );
for( int i = 0; i < beamCount; i++ ){
// Retrieve Audio Beam Frame
ComPtr<IAudioBeamFrame> audioBeamFrame;
ERROR_CHECK( audioBeamFrameList->OpenAudioBeamFrame( i, &audioBeamFrame ) );
// Retrieve Audio Beam SubFrame Count
UINT subFrameCount = 0;
ERROR_CHECK( audioBeamFrame->get_SubFrameCount( &subFrameCount ) );
for( int j = 0; j < subFrameCount; j++ ){
// Retrieve Audio Beam SubFrame
ComPtr<IAudioBeamSubFrame> audioBeamSubFrame;
ERROR_CHECK( audioBeamFrame->GetSubFrame( j, &audioBeamSubFrame ) );
// Retrieve Audio Body Correlation Count
UINT32 correlationCount;
ERROR_CHECK( audioBeamSubFrame->get_AudioBodyCorrelationCount( &correlationCount ) );
// Check Correlation Count
if( correlationCount == 0 ){
return;
}
// Retrieve First Audio Body Correlation
ComPtr<IAudioBodyCorrelation> audioBodyCorrelation;
ERROR_CHECK( audioBeamSubFrame->GetAudioBodyCorrelation( 0, &audioBodyCorrelation ) );
// Retrieve Tracking ID
ERROR_CHECK( audioBodyCorrelation->get_BodyTrackingId( &audioTrackingId ) );
}
}
}
// Update Body
inline void Kinect::updateBody()
{
// Initialize Tracking Index
audioTrackingIndex = -1;
// Check Tracking ID
if( audioTrackingId == std::numeric_limits<unsigned long long>::max() - 1 ){
return;
}
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Release Previous Bodies
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Retrieve Body Data
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
for( int count = 0; count < BODY_COUNT; count++ ){
// Retrive Tracking ID
UINT64 trackingId;
bodies[count]->get_TrackingId( &trackingId );
// Check Tracking ID
if( trackingId == audioTrackingId ){
audioTrackingIndex = count;
break;
}
}
}
// Update BodyIndex
inline void Kinect::updateBodyIndex()
{
// Retrieve BodyIndex Frame
ComPtr<IBodyIndexFrame> bodyIndexFrame;
const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve BodyIndex Data
ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast<UINT>( bodyIndexBuffer.size() ), &bodyIndexBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw BodyIndex
drawBodyIndex();
}
// Draw BodyIndex
inline void Kinect::drawBodyIndex()
{
// Check Tracking Index
if( audioTrackingIndex == -1 ){
return;
}
// Visualization BodyIndex
bodyIndexMat = cv::Mat::zeros( bodyIndexHeight, bodyIndexWidth, CV_8UC3 );
bodyIndexMat.forEach<cv::Vec3b>( [&]( cv::Vec3b &p, const int* position ){
uchar index = bodyIndexBuffer[position[0] * bodyIndexWidth + position[1]];
if( index == audioTrackingIndex ){
p = colors[index];
}
} );
}
// Show Data
void Kinect::show()
{
// Show BodyIndex
showBodyIndex();
}
// Show BodyIndex
inline void Kinect::showBodyIndex()
{
if( bodyIndexMat.empty() ){
return;
}
// Show Image
cv::imshow( "AudiBody", bodyIndexMat );
}

View File

@ -0,0 +1,96 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IBodyFrameReader> bodyFrameReader;
ComPtr<IBodyIndexFrameReader> bodyIndexFrameReader;
ComPtr<IAudioBeamFrameReader> audioBeamFrameReader;
// Body Buffer
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
// BodyIndex Buffer
std::vector<BYTE> bodyIndexBuffer;
int bodyIndexWidth;
int bodyIndexHeight;
cv::Mat bodyIndexMat;
std::array<cv::Vec3b, BODY_COUNT> colors;
// Audio Buffer
UINT64 audioTrackingId;
int audioTrackingIndex;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Body
inline void initializeBody();
// Initialize BodyIndex
inline void initializeBodyIndex();
// Initialize Audio
inline void initializeAudio();
// Finalize
void finalize();
// Update Data
void update();
// Update Body
inline void updateBody();
// Update BodyIndex
inline void updateBodyIndex();
// Update Audio
inline void updateAudio();
// Draw Data
void draw();
// Draw BodyIndex
inline void drawBodyIndex();
// Draw Audio
inline void drawAudio();
// Show Data
void show();
// Show BodyIndex
inline void showBodyIndex();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Body app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Body" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Body ${KinectSDK2_LIBRARIES} )
target_link_libraries( Body ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,335 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
// Initialize Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Release Previous Bodies
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Retrieve Body Data
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Body
drawBody();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw Body
inline void Kinect::drawBody()
{
// Draw Body Data to Color Data
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IBody> body = bodies[count];
if( body == nullptr ){
return;
}
// Check Body Tracked
BOOLEAN tracked = FALSE;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Joints
std::array<Joint, JointType::JointType_Count> joints;
ERROR_CHECK( body->GetJoints( static_cast<UINT>( joints.size() ), &joints[0] ) );
Concurrency::parallel_for_each( joints.begin(), joints.end(), [&]( const Joint& joint ){
// Check Joint Tracked
if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
return;
}
// Draw Joint Position
drawEllipse( colorMat, joint, 5, colors[count] );
// Draw Left Hand State
if( joint.JointType == JointType::JointType_HandLeft ){
HandState handState;
TrackingConfidence handConfidence;
ERROR_CHECK( body->get_HandLeftState( &handState ) );
ERROR_CHECK( body->get_HandLeftConfidence( &handConfidence ) );
drawHandState( colorMat, joint, handState, handConfidence );
}
// Draw Right Hand State
if( joint.JointType == JointType::JointType_HandRight ){
HandState handState;
TrackingConfidence handConfidence;
ERROR_CHECK( body->get_HandRightState( &handState ) );
ERROR_CHECK( body->get_HandRightConfidence( &handConfidence ) );
drawHandState( colorMat, joint, handState, handConfidence );
}
} );
/*
// Retrieve Joint Orientations
std::array<JointOrientation, JointType::JointType_Count> orientations;
ERROR_CHECK( body->GetJointOrientations( JointType::JointType_Count, &orientations[0] ) );
*/
/*
// Retrieve Amount of Body Lean
PointF amount;
ERROR_CHECK( body->get_Lean( &amount ) );
*/
} );
}
// Draw Ellipse
inline void Kinect::drawEllipse( cv::Mat& image, const Joint& joint, const int radius, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Convert Coordinate System and Draw Joint
ColorSpacePoint colorSpacePoint;
ERROR_CHECK( coordinateMapper->MapCameraPointToColorSpace( joint.Position, &colorSpacePoint ) );
const int x = static_cast<int>( colorSpacePoint.X + 0.5f );
const int y = static_cast<int>( colorSpacePoint.Y + 0.5f );
if( ( 0 <= x ) && ( x < image.cols ) && ( 0 <= y ) && ( y < image.rows ) ){
cv::circle( image, cv::Point( x, y ), radius, static_cast<cv::Scalar>( color ), thickness, cv::LINE_AA );
}
}
// Draw Hand State
inline void Kinect::drawHandState( cv::Mat& image, const Joint& joint, HandState handState, TrackingConfidence handConfidence )
{
if( image.empty() ){
return;
}
// Check Tracking Confidence
if( handConfidence != TrackingConfidence::TrackingConfidence_High ){
return;
}
// Draw Hand State
const int radius = 75;
const cv::Vec3b blue = cv::Vec3b( 128, 0, 0 ), green = cv::Vec3b( 0, 128, 0 ), red = cv::Vec3b( 0, 0, 128 );
switch( handState ){
// Open
case HandState::HandState_Open:
drawEllipse( image, joint, radius, green, 5 );
break;
// Close
case HandState::HandState_Closed:
drawEllipse( image, joint, radius, red, 5 );
break;
// Lasso
case HandState::HandState_Lasso:
drawEllipse( image, joint, radius, blue, 5 );
break;
default:
break;
}
}
// Show Data
void Kinect::show()
{
// Show Body
showBody();
}
// Show Body
inline void Kinect::showBody()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Body", resizeMat );
}

View File

@ -0,0 +1,95 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Body Buffer
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
std::array<cv::Vec3b, BODY_COUNT> colors;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Body
inline void drawBody();
// Draw Circle
inline void drawEllipse( cv::Mat& image, const Joint& joint, const int radius, const cv::Vec3b& color, const int thickness = -1 );
// Draw Hand State
inline void drawHandState( cv::Mat& image, const Joint& joint, HandState handState, TrackingConfidence handConfidence );
// Show Data
void show();
// Show Body
inline void showBody();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( BodyIndex app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "BodyIndex" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( BodyIndex ${KinectSDK2_LIBRARIES} )
target_link_libraries( BodyIndex ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,165 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize BodyIndex
initializeBodyIndex();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize BodyIndex
inline void Kinect::initializeBodyIndex()
{
// Open BodyIndex Reader
ComPtr<IBodyIndexFrameSource> bodyIndexFrameSource;
ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) );
ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) );
// Retrieve BodyIndex Description
ComPtr<IFrameDescription> bodyIndexFrameDescription;
ERROR_CHECK( bodyIndexFrameSource->get_FrameDescription( &bodyIndexFrameDescription ) );
ERROR_CHECK( bodyIndexFrameDescription->get_Width( &bodyIndexWidth ) ); // 512
ERROR_CHECK( bodyIndexFrameDescription->get_Height( &bodyIndexHeight ) ); // 424
ERROR_CHECK( bodyIndexFrameDescription->get_BytesPerPixel( &bodyIndexBytesPerPixel ) ); // 1
// Allocation BodyIndex Buffer
bodyIndexBuffer.resize( bodyIndexWidth * bodyIndexHeight );
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update BodyIndex
updateBodyIndex();
}
// Update BodyIndex
inline void Kinect::updateBodyIndex()
{
// Retrieve BodyIndex Frame
ComPtr<IBodyIndexFrame> bodyIndexFrame;
const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve BodyIndex Data
ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast<UINT>( bodyIndexBuffer.size() ), &bodyIndexBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw BodyIndex
drawBodyIndex();
}
// Draw BodyIndex
inline void Kinect::drawBodyIndex()
{
// Visualization Color to Each Index
bodyIndexMat = cv::Mat::zeros( bodyIndexHeight, bodyIndexWidth, CV_8UC3 );
bodyIndexMat.forEach<cv::Vec3b>( [&]( cv::Vec3b &p, const int* position ){
uchar index = bodyIndexBuffer[position[0] * bodyIndexWidth + position[1]];
if( index != 0xff ){
p = colors[index];
}
} );
}
// Show Data
void Kinect::show()
{
// Show BodyIndex
showBodyIndex();
}
// Show BodyIndex
inline void Kinect::showBodyIndex()
{
// Show Image
cv::imshow( "BodyIndex", bodyIndexMat );
}

View File

@ -0,0 +1,74 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IBodyIndexFrameReader> bodyIndexFrameReader;
// BodyIndex Buffer
std::vector<BYTE> bodyIndexBuffer;
int bodyIndexWidth;
int bodyIndexHeight;
unsigned int bodyIndexBytesPerPixel;
cv::Mat bodyIndexMat;
std::array<cv::Vec3b, BODY_COUNT> colors;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize BodyIndex
inline void initializeBodyIndex();
// Finalize
void finalize();
// Update Data
void update();
// Update BodyIndex
inline void updateBodyIndex();
// Draw Data
void draw();
// Draw BodyIndex
inline void drawBodyIndex();
// Show Data
void show();
// Show BodyIndex
inline void showBodyIndex();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,32 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
# Set Binary Output Directory
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
# Sample Sub-Directories Name
set( SAMPLES Color Depth Infrared BodyIndex Body JointSmooth MultiSource CoordinateMapper Face HDFace Fusion Gesture Speech AudioBeam AudioBody ChromaKey FaceClip )
# Sample Build Option
foreach( SAMPLE ${SAMPLES} )
option( BUILD_${SAMPLE} "Build ${SAMPLE} Sample Project" ON )
endforeach()
# Sample Add Sub-Directories
foreach( SAMPLE ${SAMPLES} )
if( BUILD_${SAMPLE} )
add_subdirectory( ${SAMPLE} )
endif()
endforeach()
# Adjust ( Copy Run-Time Files )
if( BUILD_Speech )
file( COPY ${CMAKE_SOURCE_DIR}/Speech/Grammar_enUS.grxml DESTINATION ${CMAKE_BINARY_DIR}/bin )
file( COPY ${CMAKE_SOURCE_DIR}/Speech/Grammar_jaJP.grxml DESTINATION ${CMAKE_BINARY_DIR}/bin )
endif()
if( BUILD_Gesture )
file( COPY ${CMAKE_SOURCE_DIR}/Gesture/SampleDatabase.gbd DESTINATION ${CMAKE_BINARY_DIR}/bin )
endif()

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( ChromaKey app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "ChromaKey" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( ChromaKey ${KinectSDK2_LIBRARIES} )
target_link_libraries( ChromaKey ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,351 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <ppl.h>
// Choose Resolution
#define COLOR
//#define DEPTH
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Depth
initializeDepth();
// Initialize BodyIndex
initializeBodyIndex();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Depth
inline void Kinect::initializeDepth()
{
// Open Depth Reader
ComPtr<IDepthFrameSource> depthFrameSource;
ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) );
ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) );
// Retrieve Depth Description
ComPtr<IFrameDescription> depthFrameDescription;
ERROR_CHECK( depthFrameSource->get_FrameDescription( &depthFrameDescription ) );
ERROR_CHECK( depthFrameDescription->get_Width( &depthWidth ) ); // 512
ERROR_CHECK( depthFrameDescription->get_Height( &depthHeight ) ); // 424
ERROR_CHECK( depthFrameDescription->get_BytesPerPixel( &depthBytesPerPixel ) ); // 2
// Allocation Depth Buffer
depthBuffer.resize( depthWidth * depthHeight );
}
// Initialize BodyIndex
inline void Kinect::initializeBodyIndex()
{
// Open BodyIndex Reader
ComPtr<IBodyIndexFrameSource> bodyIndexFrameSource;
ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) );
ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) );
// Retrieve BodyIndex Description
ComPtr<IFrameDescription> bodyIndexFrameDescription;
ERROR_CHECK( bodyIndexFrameSource->get_FrameDescription( &bodyIndexFrameDescription ) );
ERROR_CHECK( bodyIndexFrameDescription->get_Width( &bodyIndexWidth ) ); // 512
ERROR_CHECK( bodyIndexFrameDescription->get_Height( &bodyIndexHeight ) ); // 424
ERROR_CHECK( bodyIndexFrameDescription->get_BytesPerPixel( &bodyIndexBytesPerPixel ) ); // 1
// Allocation BodyIndex Buffer
bodyIndexBuffer.resize( bodyIndexWidth * bodyIndexHeight );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Depth
updateDepth();
// Update BodyIndex
updateBodyIndex();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Depth
inline void Kinect::updateDepth()
{
// Retrieve Depth Frame
ComPtr<IDepthFrame> depthFrame;
const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Depth Data
ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast<UINT>( depthBuffer.size() ), &depthBuffer[0] ) );
}
// Update BodyIndex
inline void Kinect::updateBodyIndex()
{
// Retrieve BodyIndex Frame
ComPtr<IBodyIndexFrame> bodyIndexFrame;
const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve BodyIndex Data
ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast<UINT>( bodyIndexBuffer.size() ), &bodyIndexBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw BodyIndex
drawBodyIndex();
// Draw ChromaKey
drawChromaKey();
}
// Draw Color
inline void Kinect::drawColor()
{
#ifdef COLOR
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
#endif
#ifdef DEPTH
// Retrieve Mapped Coordinates
std::vector<ColorSpacePoint> colorSpacePoints( depthWidth * depthHeight );
ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) );
// Mapping Color to Depth Resolution
std::vector<BYTE> buffer( depthWidth * depthHeight * colorBytesPerPixel );
Concurrency::parallel_for( 0, depthHeight, [&]( const int depthY ){
const unsigned int depthOffset = depthY * depthWidth;
for( int depthX = 0; depthX < depthWidth; depthX++ ){
unsigned int depthIndex = depthOffset + depthX;
const int colorX = static_cast<int>( colorSpacePoints[depthIndex].X + 0.5f );
const int colorY = static_cast<int>( colorSpacePoints[depthIndex].Y + 0.5f );
if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
const unsigned int colorIndex = ( colorY * colorWidth + colorX ) * colorBytesPerPixel;
depthIndex = depthIndex * colorBytesPerPixel;
buffer[depthIndex + 0] = colorBuffer[colorIndex + 0];
buffer[depthIndex + 1] = colorBuffer[colorIndex + 1];
buffer[depthIndex + 2] = colorBuffer[colorIndex + 2];
buffer[depthIndex + 3] = colorBuffer[colorIndex + 3];
}
}
} );
// Create cv::Mat from Coordinate Buffer
colorMat = cv::Mat( depthHeight, depthWidth, CV_8UC4, &buffer[0] ).clone();
#endif
}
// Draw BodyIndex
inline void Kinect::drawBodyIndex()
{
#ifdef COLOR
// Retrieve Mapped Coordinates
std::vector<DepthSpacePoint> bodyIndexSpacePoints( colorWidth * colorHeight );
ERROR_CHECK( coordinateMapper->MapColorFrameToDepthSpace( depthBuffer.size(), &depthBuffer[0], bodyIndexSpacePoints.size(), &bodyIndexSpacePoints[0] ) );
// Mapping BodyIndex to Color Resolution
std::vector<BYTE> buffer( colorWidth * colorHeight, 0xff );
Concurrency::parallel_for( 0, colorHeight, [&]( const int colorY ){
const unsigned int colorOffset = colorY * colorWidth;
for( int colorX = 0; colorX < colorWidth; colorX++ ){
const unsigned int colorIndex = colorOffset + colorX;
const int bodyIndexX = static_cast<int>( bodyIndexSpacePoints[colorIndex].X + 0.5f );
const int bodyIndexY = static_cast<int>( bodyIndexSpacePoints[colorIndex].Y + 0.5f );
if( ( 0 <= bodyIndexX ) && ( bodyIndexX < bodyIndexWidth ) && ( 0 <= bodyIndexY ) && ( bodyIndexY < bodyIndexHeight ) ){
const unsigned char bodyIndex = bodyIndexBuffer[bodyIndexY * bodyIndexWidth + bodyIndexX];
buffer[colorIndex] = bodyIndex;
}
}
} );
// Create cv::Mat from Coordinate Buffer
bodyIndexMat = cv::Mat( colorHeight, colorWidth, CV_8UC1, &buffer[0] ).clone();
#endif
#ifdef DEPTH
// Create cv::Mat from BodyIndex Buffer
bodyIndexMat = cv::Mat( bodyIndexHeight, bodyIndexWidth, CV_8UC1, &bodyIndexBuffer[0] );
#endif
}
// Draw ChromaKey
inline void Kinect::drawChromaKey()
{
if( colorMat.empty() ){
return;
}
if( bodyIndexMat.empty() ){
return;
}
// ChromaKey
#ifdef COLOR
chromaKeyMat = cv::Mat::zeros( colorHeight, colorWidth, CV_8UC4 );
#endif
#ifdef DEPTH
chromaKeyMat = cv::Mat::zeros( depthHeight, depthWidth, CV_8UC4 );
#endif
chromaKeyMat.forEach<cv::Vec4b>( [&]( cv::Vec4b &p, const int* position ){
uchar bodyIndex = bodyIndexMat.at<uchar>( position[0], position[1] );
if( bodyIndex != 0xff ){
p = colorMat.at<cv::Vec4b>( position[0], position[1] );
}
} );
}
// Show Data
void Kinect::show()
{
// Show ChromaKey
showChromaKey();
}
// Show ChromaKey
inline void Kinect::showChromaKey()
{
if( chromaKeyMat.empty() ){
return;
}
#ifdef COLOR
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( chromaKeyMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "ChromaKey", resizeMat );
#endif
#ifdef DEPTH
// Show Image
cv::imshow( "ChromaKey", chromaKeyMat );
#endif
}

View File

@ -0,0 +1,110 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IDepthFrameReader> depthFrameReader;
ComPtr<IBodyIndexFrameReader> bodyIndexFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Depth Buffer
std::vector<UINT16> depthBuffer;
int depthWidth;
int depthHeight;
unsigned int depthBytesPerPixel;
// BodyIndex Buffer
std::vector<BYTE> bodyIndexBuffer;
int bodyIndexWidth;
int bodyIndexHeight;
unsigned int bodyIndexBytesPerPixel;
cv::Mat bodyIndexMat;
// ChromaKey Buffer
cv::Mat chromaKeyMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Depth
inline void initializeDepth();
// Initialize BodyIndex
inline void initializeBodyIndex();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Depth
inline void updateDepth();
// Update BodyIndex
inline void updateBodyIndex();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw BodyIndex
inline void drawBodyIndex();
// Draw ChromaKey
inline void drawChromaKey();
// Show Data
void show();
// Show ChromaKey
inline void showChromaKey();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Color app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Color" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Color ${KinectSDK2_LIBRARIES} )
target_link_libraries( Color ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,160 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Show Data
void Kinect::show()
{
// Show Color
showColor();
}
// Show Color
inline void Kinect::showColor()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Color", resizeMat );
}

View File

@ -0,0 +1,71 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Show Data
void show();
// Show Color
inline void showColor();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( CoordinateMapper app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "CoordinateMapper" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( CoordinateMapper ${KinectSDK2_LIBRARIES} )
target_link_libraries( CoordinateMapper ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,307 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <ppl.h>
// Choose Resolution
//#define COLOR
#define DEPTH
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Depth
initializeDepth();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Depth
inline void Kinect::initializeDepth()
{
// Open Depth Reader
ComPtr<IDepthFrameSource> depthFrameSource;
ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) );
ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) );
// Retrieve Depth Description
ComPtr<IFrameDescription> depthFrameDescription;
ERROR_CHECK( depthFrameSource->get_FrameDescription( &depthFrameDescription ) );
ERROR_CHECK( depthFrameDescription->get_Width( &depthWidth ) ); // 512
ERROR_CHECK( depthFrameDescription->get_Height( &depthHeight ) ); // 424
ERROR_CHECK( depthFrameDescription->get_BytesPerPixel( &depthBytesPerPixel ) ); // 2
// Allocation Depth Buffer
depthBuffer.resize( depthWidth * depthHeight );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Depth
updateDepth();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Depth
inline void Kinect::updateDepth()
{
// Retrieve Depth Frame
ComPtr<IDepthFrame> depthFrame;
const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Depth Data
ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast<UINT>( depthBuffer.size() ), &depthBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Depth
drawDepth();
}
// Draw Color
inline void Kinect::drawColor()
{
#ifdef DEPTH
// Retrieve Mapped Coordinates
std::vector<ColorSpacePoint> colorSpacePoints( depthWidth * depthHeight );
ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) );
// Mapping Color to Depth Resolution
std::vector<BYTE> buffer( depthWidth * depthHeight * colorBytesPerPixel );
Concurrency::parallel_for( 0, depthHeight, [&]( const int depthY ){
const unsigned int depthOffset = depthY * depthWidth;
for( int depthX = 0; depthX < depthWidth; depthX++ ){
unsigned int depthIndex = depthOffset + depthX;
const int colorX = static_cast<int>( colorSpacePoints[depthIndex].X + 0.5f );
const int colorY = static_cast<int>( colorSpacePoints[depthIndex].Y + 0.5f );
if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
const unsigned int colorIndex = ( colorY * colorWidth + colorX ) * colorBytesPerPixel;
depthIndex = depthIndex * colorBytesPerPixel;
buffer[depthIndex + 0] = colorBuffer[colorIndex + 0];
buffer[depthIndex + 1] = colorBuffer[colorIndex + 1];
buffer[depthIndex + 2] = colorBuffer[colorIndex + 2];
buffer[depthIndex + 3] = colorBuffer[colorIndex + 3];
}
}
} );
// Create cv::Mat from Coordinate Buffer
colorMat = cv::Mat( depthHeight, depthWidth, CV_8UC4, &buffer[0] ).clone();
#else
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0]);
#endif
}
// Draw Depth
inline void Kinect::drawDepth()
{
#ifdef COLOR
// Retrieve Mapped Coordinates
std::vector<DepthSpacePoint> depthSpacePoints( colorWidth * colorHeight );
ERROR_CHECK( coordinateMapper->MapColorFrameToDepthSpace( depthBuffer.size(), &depthBuffer[0], depthSpacePoints.size(), &depthSpacePoints[0] ) );
// Mapping Depth to Color Resolution
std::vector<UINT16> buffer( colorWidth * colorHeight );
Concurrency::parallel_for( 0, colorHeight, [&]( const int colorY ){
const unsigned int colorOffset = colorY * colorWidth;
for( int colorX = 0; colorX < colorWidth; colorX++ ){
const unsigned int colorIndex = colorOffset + colorX;
const int depthX = static_cast<int>( depthSpacePoints[colorIndex].X + 0.5f );
const int depthY = static_cast<int>( depthSpacePoints[colorIndex].Y + 0.5f );
if( ( 0 <= depthX ) && ( depthX < depthWidth ) && ( 0 <= depthY ) && ( depthY < depthHeight ) ){
const unsigned int depthIndex = depthY * depthWidth + depthX;
buffer[colorIndex] = depthBuffer[depthIndex];
}
}
} );
// Create cv::Mat from Coordinate Buffer
depthMat = cv::Mat( colorHeight, colorWidth, CV_16UC1, &buffer[0] ).clone();
#else
// Create cv::Mat from Depth Buffer
depthMat = cv::Mat( depthHeight, depthWidth, CV_16UC1, &depthBuffer[0]);
#endif
}
// Show Data
void Kinect::show()
{
// Show Color
showColor();
// Show Depth
showDepth();
}
// Show Color
inline void Kinect::showColor()
{
if( colorMat.empty() ){
return;
}
#ifdef COLOR
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Color", resizeMat );
#else
// Show Image
cv::imshow( "Color", colorMat );
#endif
}
// Show Depth
inline void Kinect::showDepth()
{
if( depthMat.empty() ){
return;
}
// Scaling ( 0-8000 -> 255-0 )
cv::Mat scaleMat;
depthMat.convertTo( scaleMat, CV_8U, -255.0 / 8000.0, 255.0 );
//cv::applyColorMap( scaleMat, scaleMat, cv::COLORMAP_BONE );
#ifdef COLOR
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( scaleMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Depth", resizeMat );
#else
// Show Image
cv::imshow( "Depth", scaleMat );
#endif
}

View File

@ -0,0 +1,94 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IDepthFrameReader> depthFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Depth Buffer
std::vector<UINT16> depthBuffer;
int depthWidth;
int depthHeight;
unsigned int depthBytesPerPixel;
cv::Mat depthMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Depth
inline void initializeDepth();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Depth
inline void updateDepth();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Depth
inline void drawDepth();
// Show Data
void show();
// Show Color
inline void showColor();
// Show Depth
inline void showDepth();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Depth app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Depth" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Depth ${KinectSDK2_LIBRARIES} )
target_link_libraries( Depth ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,167 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Depth
initializeDepth();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize Depth
inline void Kinect::initializeDepth()
{
// Open Depth Reader
ComPtr<IDepthFrameSource> depthFrameSource;
ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) );
ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) );
// Retrieve Depth Description
ComPtr<IFrameDescription> depthFrameDescription;
ERROR_CHECK( depthFrameSource->get_FrameDescription( &depthFrameDescription ) );
ERROR_CHECK( depthFrameDescription->get_Width( &depthWidth ) ); // 512
ERROR_CHECK( depthFrameDescription->get_Height( &depthHeight ) ); // 424
ERROR_CHECK( depthFrameDescription->get_BytesPerPixel( &depthBytesPerPixel ) ); // 2
// Retrieve Depth Reliable Range
UINT16 minReliableDistance;
UINT16 maxReliableDistance;
ERROR_CHECK( depthFrameSource->get_DepthMinReliableDistance( &minReliableDistance ) ); // 500
ERROR_CHECK( depthFrameSource->get_DepthMaxReliableDistance( &maxReliableDistance ) ); // 4500
std::cout << "Depth Reliable Range : " << minReliableDistance << " - " << maxReliableDistance << std::endl;
// Allocation Depth Buffer
depthBuffer.resize( depthWidth * depthHeight );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Depth
updateDepth();
}
// Update Depth
inline void Kinect::updateDepth()
{
// Retrieve Depth Frame
ComPtr<IDepthFrame> depthFrame;
const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Depth Data
ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast<UINT>( depthBuffer.size() ), &depthBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Depth
drawDepth();
}
// Draw Depth
inline void Kinect::drawDepth()
{
// Create cv::Mat from Depth Buffer
depthMat = cv::Mat( depthHeight, depthWidth, CV_16UC1, &depthBuffer[0] );
}
// Show Data
void Kinect::show()
{
// Show Depth
showDepth();
}
// Show Depth
inline void Kinect::showDepth()
{
if( depthMat.empty() ){
return;
}
// Scaling ( 0-8000 -> 255-0 )
cv::Mat scaleMat;
depthMat.convertTo( scaleMat, CV_8U, -255.0 / 8000.0, 255.0 );
//cv::applyColorMap( scaleMat, scaleMat, cv::COLORMAP_BONE );
// Show Image
cv::imshow( "Depth", scaleMat );
}

View File

@ -0,0 +1,71 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IDepthFrameReader> depthFrameReader;
// Depth Buffer
std::vector<UINT16> depthBuffer;
int depthWidth;
int depthHeight;
unsigned int depthBytesPerPixel;
cv::Mat depthMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Depth
inline void initializeDepth();
// Finalize
void finalize();
// Update Data
void update();
// Update Depth
inline void updateDepth();
// Draw Data
void draw();
// Draw Depth
inline void drawDepth();
// Show Data
void show();
// Show Depth
inline void showDepth();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,47 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Face app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Face" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_FACE TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Face ${KinectSDK2_LIBRARIES} )
target_link_libraries( Face ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET Face POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,440 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#define _USE_MATH_DEFINES
#include <math.h>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Initialize Face
initializeFace();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
// Initialize Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
}
// Initialize Face
inline void Kinect::initializeFace()
{
// Set Face Features to Enable
const DWORD features =
FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_PointsInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_RotationOrientation
| FaceFrameFeatures::FaceFrameFeatures_Happy
| FaceFrameFeatures::FaceFrameFeatures_RightEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_LeftEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_MouthOpen
| FaceFrameFeatures::FaceFrameFeatures_MouthMoved
| FaceFrameFeatures::FaceFrameFeatures_LookingAway
| FaceFrameFeatures::FaceFrameFeatures_Glasses
| FaceFrameFeatures::FaceFrameFeatures_FaceEngagement;
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Create Face Sources
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( CreateFaceFrameSource( kinect.Get(), 0, features, &faceFrameSource ) );
// Open Face Readers
ERROR_CHECK( faceFrameSource->OpenReader( &faceFrameReader[count] ) );
} );
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
// Face Property Label Text Table for Display
labels[0] = "Happy";
labels[1] = "Engaged";
labels[2] = "WearingGlasses";
labels[3] = "LeftEyeClosed";
labels[4] = "RightEyeClosed";
labels[5] = "MouthOpen";
labels[6] = "MouthMoved";
labels[7] = "LookingAway";
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
// Update Face
updateFace();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Release Previous Bodies
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Retrieve Body Data
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IBody> body = bodies[count];
BOOLEAN tracked;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Tracking ID
UINT64 trackingId;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
// Registration Tracking ID
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( faceFrameReader[count]->get_FaceFrameSource( &faceFrameSource ) );
ERROR_CHECK( faceFrameSource->put_TrackingId( trackingId ) );
} );
}
// Update Face
inline void Kinect::updateFace()
{
// ReSet Results
results.fill( nullptr );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Retrieve Face Frame
ComPtr<IFaceFrame> faceFrame;
const HRESULT ret = faceFrameReader[count]->AcquireLatestFrame( &faceFrame );
if( FAILED( ret ) ){
return;
}
// Check Tracking ID is Valid
BOOLEAN tracked;
ERROR_CHECK( faceFrame->get_IsTrackingIdValid( &tracked ) );
if( !tracked ){
return;
}
// Release Previous Face Result and Retrieve Face Result
ERROR_CHECK( faceFrame->get_FaceFrameResult( &results[count] ) );
} );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Face
drawFace();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw Face
inline void Kinect::drawFace()
{
if( colorMat.empty() ){
return;
}
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IFaceFrameResult> result = results[count];
if( result == nullptr ){
return;
}
// Retrieve Face Points
std::array<PointF, FacePointType::FacePointType_Count> facePoints;
ERROR_CHECK( result->GetFacePointsInColorSpace( FacePointType::FacePointType_Count, &facePoints[0] ) );
drawFacePoints( colorMat, facePoints, 5, colors[count] );
// Retrieve Face Bounding Box
RectI boundingBox;
ERROR_CHECK( result->get_FaceBoundingBoxInColorSpace( &boundingBox ) );
drawFaceBoundingBox( colorMat, boundingBox, colors[count] );
// Retrieve Face Rotation Quaternion
Vector4 rotationQuaternion;
ERROR_CHECK( result->get_FaceRotationQuaternion( &rotationQuaternion ) );
drawFaceRotation( colorMat, rotationQuaternion, boundingBox, 1.0, colors[count] );
// Retrieve Face Properties
std::array<DetectionResult, FaceProperty::FaceProperty_Count> detectionResults;
ERROR_CHECK( result->GetFaceProperties( FaceProperty::FaceProperty_Count, &detectionResults[0] ) );
drawFaceProperties( colorMat, detectionResults, boundingBox, 1.0, colors[count] );
} );
}
// Draw Face Points
inline void Kinect::drawFacePoints( cv::Mat& image, const std::array<PointF, FacePointType::FacePointType_Count>& points, const int radius, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Draw Points
Concurrency::parallel_for_each( points.begin(), points.end(), [&]( const PointF point ){
const int x = static_cast<int>( point.X + 0.5f );
const int y = static_cast<int>( point.Y + 0.5f );
cv::circle( image, cv::Point( x, y ), radius, static_cast<cv::Scalar>( color ), thickness, cv::LINE_AA );
} );
}
// Draw Face Bounding Box
inline void Kinect::drawFaceBoundingBox( cv::Mat& image, const RectI& box, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Draw Bounding Box
const int width = box.Right - box.Left;
const int height = box.Bottom - box.Top;
cv::rectangle( image, cv::Rect( box.Left, box.Top, width, height ), color, thickness, cv::LINE_AA );
}
// Draw Face Rotation Quaternion
inline void Kinect::drawFaceRotation( cv::Mat& image, Vector4& quaternion, const RectI& box, const double fontScale,const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Convert Quaternion to Degree
int pitch, yaw, roll;
quaternion2degree( &quaternion, &pitch, &yaw, &roll );
// Draw Rotation
const int offset = 30;
if( box.Left && box.Bottom ){
std::string rotation = "Pitch, Yaw, Roll : " + std::to_string( pitch ) + ", " + std::to_string( yaw ) + ", " + std::to_string( roll );
cv::putText( image, rotation, cv::Point( box.Left, box.Bottom + offset ), cv::FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, cv::LINE_AA );
}
}
// Convert Quaternion to Degree
inline void Kinect::quaternion2degree( const Vector4* quaternion, int* pitch, int* yaw, int* roll )
{
const double x = quaternion->x;
const double y = quaternion->y;
const double z = quaternion->z;
const double w = quaternion->w;
*pitch = static_cast<int>( std::atan2( 2 * ( y * z + w * x ), w * w - x * x - y * y + z * z ) / M_PI * 180.0f );
*yaw = static_cast<int>( std::asin( 2 * ( w * y - x * z ) ) / M_PI * 180.0f );
*roll = static_cast<int>( std::atan2( 2 * ( x * y + w * z ), w * w + x * x - y * y - z * z ) / M_PI * 180.0f );
}
// Draw Face Properties
inline void Kinect::drawFaceProperties( cv::Mat& image, std::array<DetectionResult, FaceProperty::FaceProperty_Count>& results, const RectI& box, const double fontScale, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Draw Properties
int offset = 30;
for( int count = 0; count < FaceProperty::FaceProperty_Count; count++ ){
if( box.Left && box.Bottom ){
offset += 30;
std::string result = labels[count] + " : " + result2string( results[count] );
cv::putText( image, result, cv::Point( box.Left, box.Bottom + offset ), cv::FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, cv::LINE_AA );
}
}
}
// Convert Detection Result to String
inline std::string Kinect::result2string( DetectionResult& result )
{
switch( result ){
case DetectionResult::DetectionResult_Yes:
return "Yes";
case DetectionResult::DetectionResult_Maybe:
return "Maybe";
case DetectionResult::DetectionResult_No:
return "No";
case DetectionResult::DetectionResult_Unknown:
return "Unknown";
default:
std::runtime_error( "not detection result of face property" );
}
return "";
}
// Show Data
void Kinect::show()
{
// Show Face
showFace();
}
// Show Face
inline void Kinect::showFace()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Face", resizeMat );
}

View File

@ -0,0 +1,121 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <Kinect.Face.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
std::array<ComPtr<IFaceFrameReader>, BODY_COUNT> faceFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Body Buffer
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
// Face Buffer
std::array<ComPtr<IFaceFrameResult>, BODY_COUNT> results;
std::array<std::string, FaceProperty::FaceProperty_Count> labels;
std::array<cv::Vec3b, BODY_COUNT> colors;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Initialize Face
inline void initializeFace();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Update Face
inline void updateFace();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Face
inline void drawFace();
// Draw Face Points
inline void drawFacePoints( cv::Mat& image, const std::array<PointF, FacePointType::FacePointType_Count>& points, const int radius, const cv::Vec3b& color, const int thickness = -1 );
// Draw Face Bounding Box
inline void drawFaceBoundingBox( cv::Mat& image, const RectI& box, const cv::Vec3b& color, const int thickness = 1 );
// Draw Face Rotation
inline void drawFaceRotation( cv::Mat& image, Vector4& quaternion, const RectI& box, const double fontScale, const cv::Vec3b& color, const int thickness = 2 );
// Convert Quaternion to Degree
inline void quaternion2degree( const Vector4* quaternion, int* pitch, int* yaw, int* roll );
// Draw Face Properties
inline void drawFaceProperties( cv::Mat& image, std::array<DetectionResult, FaceProperty::FaceProperty_Count>& detections, const RectI& box, const double fontScale, const cv::Vec3b& color, const int thickness = 2 );
// Convert Detection Result to String
inline std::string Kinect::result2string( DetectionResult& result );
// Show Data
void show();
// Show Face
inline void showFace();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,47 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( FaceClip app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "FaceClip" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_FACE TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( FaceClip ${KinectSDK2_LIBRARIES} )
target_link_libraries( FaceClip ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET FaceClip POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,312 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#define _USE_MATH_DEFINES
#include <math.h>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE || GetKeyState( VK_ESCAPE ) < 0 ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Initialize Face
initializeFace();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
// Initialize Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
}
// Initialize Face
inline void Kinect::initializeFace()
{
// Set Face Features to Enable
const DWORD features =
FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace;
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Create Face Sources
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( CreateFaceFrameSource( kinect.Get(), 0, features, &faceFrameSource ) );
// Open Face Readers
ERROR_CHECK( faceFrameSource->OpenReader( &faceFrameReader[count] ) );
} );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
// Update Face
updateFace();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Release Previous Bodies
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Retrieve Body Data
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IBody> body = bodies[count];
BOOLEAN tracked;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Tracking ID
UINT64 trackingId;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
// Registration Tracking ID
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( faceFrameReader[count]->get_FaceFrameSource( &faceFrameSource ) );
ERROR_CHECK( faceFrameSource->put_TrackingId( trackingId ) );
} );
}
// Update Face
inline void Kinect::updateFace()
{
// ReSet Results
results.fill( nullptr );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Retrieve Face Frame
ComPtr<IFaceFrame> faceFrame;
const HRESULT ret = faceFrameReader[count]->AcquireLatestFrame( &faceFrame );
if( FAILED( ret ) ){
return;
}
// Check Tracking ID is Valid
BOOLEAN tracked;
ERROR_CHECK( faceFrame->get_IsTrackingIdValid( &tracked ) );
if( !tracked ){
return;
}
// Release Previous Face Result and Retrieve Face Result
ERROR_CHECK( faceFrame->get_FaceFrameResult( &results[count] ) );
} );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Face Clip
drawFaceClip();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw Face
inline void Kinect::drawFaceClip()
{
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IFaceFrameResult> result = results[count];
if( result == nullptr ){
return;
}
// Retrieve Bounding Box
RectI boundingBox;
ERROR_CHECK( result->get_FaceBoundingBoxInColorSpace( &boundingBox ) );
// Retrieve Face Clip using Bounding Box
retrieveFaceClip( faceClipMat[count], boundingBox );
} );
}
// Retrieve Face Clip
inline void Kinect::retrieveFaceClip( cv::Mat& image, const RectI& box )
{
if( colorMat.empty() ){
return;
}
// Retrieve Face Clip using Bounding Box
const int width = box.Right - box.Left;
const int height = box.Bottom - box.Top;
image = colorMat( cv::Rect( box.Left, box.Top, width, height ) ).clone();
}
// Show Data
void Kinect::show()
{
// Show Face Clip
showFaceClip();
}
// Show Face Clip
inline void Kinect::showFaceClip()
{
for( int count = 0; count < BODY_COUNT; count++ ){
if( faceClipMat[count].empty() ){
cv::destroyWindow( "Face" + std::to_string( count ) );
continue;
}
// Resize Clip to Constant Size
cv::resize( faceClipMat[count], faceClipMat[count], cv::Size( 200, 200 ) );
// Show Image
cv::imshow( "Face" + std::to_string( count ), faceClipMat[count] );
}
}

View File

@ -0,0 +1,105 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <Kinect.Face.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
std::array<ComPtr<IFaceFrameReader>, BODY_COUNT> faceFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Body Buffer
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
// Face Buffer
std::array<ComPtr<IFaceFrameResult>, BODY_COUNT> results;
std::array<cv::Mat, BODY_COUNT> faceClipMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Initialize Face
inline void initializeFace();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Update Face
inline void updateFace();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Face Clip
inline void drawFaceClip();
// Retrieve Face Clip
inline void retrieveFaceClip( cv::Mat& image, const RectI& box );
// Show Data
void show();
// Show Face Clip
inline void showFaceClip();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,54 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( FaceRecognition app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "FaceRecognition" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_FACE TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Required Face Module
if( OpenCV_FOUND )
if( NOT "opencv_face" IN_LIST OpenCV_LIBS )
message( FATAL_ERROR "not found opencv_face module." )
endif()
endif()
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( FaceRecognition ${KinectSDK2_LIBRARIES} )
target_link_libraries( FaceRecognition ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET FaceRecognition POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,410 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#define _USE_MATH_DEFINES
#include <math.h>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Initialize Face
initializeFace();
// Initialize Recognition
initializeRecognition();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
// Initialize Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
}
// Initialize Face
inline void Kinect::initializeFace()
{
// Set Face Features to Enable
const DWORD features = FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace;
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Create Face Sources
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( CreateFaceFrameSource( kinect.Get(), 0, features, &faceFrameSource ) );
// Open Face Readers
ERROR_CHECK( faceFrameSource->OpenReader( &faceFrameReader[count] ) );
} );
}
// Initialize Recognition
inline void Kinect::initializeRecognition()
{
// Create Recognizer
//recognizer = cv::face::createFisherFaceRecognizer();
//recognizer = cv::face::createEigenFaceRecognizer();
recognizer = cv::face::createLBPHFaceRecognizer();
// Load Recognizer
recognizer->load( model );
if( recognizer.empty() ){
throw std::runtime_error( "failed cv::face::FaceRecognizer::load()" );
}
// Set Distance Threshold
recognizer->setThreshold( threshold );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Body Buffer
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
// Update Face
updateFace();
// Update Recognition
updateRecognition();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Release Previous Bodies
Concurrency::parallel_for_each( bodies.begin(), bodies.end(), []( IBody*& body ){
SafeRelease( body );
} );
// Retrieve Body Data
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IBody> body = bodies[count];
BOOLEAN tracked;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Tracking ID
UINT64 trackingId;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
// Registration Tracking ID
ComPtr<IFaceFrameSource> faceFrameSource;
ERROR_CHECK( faceFrameReader[count]->get_FaceFrameSource( &faceFrameSource ) );
ERROR_CHECK( faceFrameSource->put_TrackingId( trackingId ) );
} );
}
// Update Face
inline void Kinect::updateFace()
{
// ReSet Results
results.fill( nullptr );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Retrieve Face Frame
ComPtr<IFaceFrame> faceFrame;
const HRESULT ret = faceFrameReader[count]->AcquireLatestFrame( &faceFrame );
if( FAILED( ret ) ){
return;
}
// Check Tracking ID is Valid
BOOLEAN tracked;
ERROR_CHECK( faceFrame->get_IsTrackingIdValid( &tracked ) );
if( !tracked ){
return;
}
// Release Previous Face Result and Retrieve Face Result
ERROR_CHECK( faceFrame->get_FaceFrameResult( &results[count] ) );
} );
}
// Update Recognition
inline void Kinect::updateRecognition()
{
// Create cv::Mat from Color Buffer
cv::Mat colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
if( colorMat.empty() ){
return;
}
// ReSet Labels and Distances
labels.fill( -1 );
distances.fill( 0.0 );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IFaceFrameResult> result = results[count];
if( result == nullptr ){
return;
}
// Retrieve Face Bounding Box
RectI boundingBox;
ERROR_CHECK( result->get_FaceBoundingBoxInColorSpace( &boundingBox ) );
// Retrieve Face
const cv::Rect roi = { boundingBox.Left, boundingBox.Top, ( boundingBox.Right - boundingBox.Left ), ( boundingBox.Bottom - boundingBox.Top ) };
cv::Mat faceMat = colorMat( roi ).clone();
if( faceMat.empty() ){
return;
}
// Resize
//cv::resize( faceMat, faceMat, cv::Size( 200, 200 ) );
// Convert BGRA to Gray
cv::cvtColor( faceMat, faceMat, cv::COLOR_BGRA2GRAY );
// Recognition
recognizer->predict( faceMat, labels[count], distances[count] );
} );
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Recognition
drawRecognition();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw Recognition
inline void Kinect::drawRecognition()
{
if( colorMat.empty() ){
return;
}
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IFaceFrameResult> result = results[count];
if( result == nullptr ){
return;
}
std::cout << count << std::endl;
// Retrieve Label and Distance
const int label = labels[count];
const double distance = distances[count];
// Set Draw Color by Recognition Results
const cv::Vec3b color = ( label != -1 ) ? cv::Vec3b( 0, 255, 0 ) : cv::Vec3b( 0, 0, 255 );
// Draw Face Bounding Box
RectI boundingBox;
ERROR_CHECK( result->get_FaceBoundingBoxInColorSpace( &boundingBox ) );
drawFaceBoundingBox( colorMat, boundingBox, color );
// Draw Recognition Results
drawRecognitionResults( colorMat, label, distance, cv::Point( boundingBox.Left, boundingBox.Top ), 1.0, color );
} );
}
// Draw Face Bounding Box
inline void Kinect::drawFaceBoundingBox( cv::Mat& image, const RectI& box, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Draw Bounding Box
const int width = box.Right - box.Left;
const int height = box.Bottom - box.Top;
cv::rectangle( image, cv::Rect( box.Left, box.Top, width, height ), color, thickness, cv::LINE_AA );
}
// Draw Recognition Results
inline void Kinect::drawRecognitionResults( cv::Mat& image, const int label, const double distance, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Set Recognition Results
std::string result;
if( label != -1 ){
result = std::to_string( label ) + " (" + std::to_string( distance ) + ")";
//result = recognizer->getLabelInfo( label );
}
else{
result = "Unknown";
}
// Draw Recognition Results
cv::putText( image, result, point, cv::FONT_HERSHEY_SIMPLEX, scale, color, thickness, cv::LINE_AA );
}
// Show Data
void Kinect::show()
{
// Show Recognition
showRecognition();
}
// Show Recognition
inline void Kinect::showRecognition()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Recognition", resizeMat );
}

View File

@ -0,0 +1,122 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <Kinect.Face.h>
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>
#include <vector>
#include <array>
#include <string>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
std::array<ComPtr<IFaceFrameReader>, BODY_COUNT> faceFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Body Buffer
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
// Face Buffer
std::array<ComPtr<IFaceFrameResult>, BODY_COUNT> results;
// Face Recognition
cv::Ptr<cv::face::FaceRecognizer> recognizer;
const std::string model = "../model.xml"; // Pre-Trained Model File Path ( *.xml or *.yaml )
const double threshold = 40.0; // Max Matching Distance
std::array<int, BODY_COUNT> labels;
std::array<double, BODY_COUNT> distances;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Initialize Face
inline void initializeFace();
// Initialize Recognition
inline void initializeRecognition();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Update Face
inline void updateFace();
// Update Recognition
inline void updateRecognition();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Recognition
inline void drawRecognition();
// Draw Face Bounding Box
inline void drawFaceBoundingBox( cv::Mat& image, const RectI& box, const cv::Vec3b& color, const int thickness = 1 );
// Draw Recognition Results
inline void drawRecognitionResults( cv::Mat& image, const int label, const double distance, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness = 2 );
// Show Data
void show();
// Show Recognition
inline void showRecognition();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,47 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Fusion app.h app.cpp main.cpp util.h KinectFusionHelper.h KinectFusionHelper.cpp )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Fusion" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_FUSION TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Fusion ${KinectSDK2_LIBRARIES} )
target_link_libraries( Fusion ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET Fusion POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,456 @@
//------------------------------------------------------------------------------
// <copyright file="KinectFusionHelper.h" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#pragma once
#include "NuiKinectFusionApi.h"
#include <vector>
#include <string>
/// <summary>
/// Set Identity in a Matrix4
/// </summary>
/// <param name="mat">The matrix to set to identity</param>
void SetIdentityMatrix(Matrix4 &mat);
/// <summary>
/// Extract translation values from the 4x4 Matrix4 transformation in M41,M42,M43
/// </summary>
/// <param name="transform">The transform matrix.</param>
/// <param name="translation">Array of 3 floating point values for translation.</param>
void ExtractVector3Translation(const Matrix4 &transform, _Out_cap_c_(3) float *translation);
/// <summary>
/// Extract translation Vector3 from the 4x4 Matrix transformation in M41,M42,M43
/// </summary>
/// <param name="transform">The transform matrix.</param>
/// <returns>Returns a Vector3 containing the translation.</returns>
Vector3 ExtractVector3Translation(const Matrix4 &transform);
/// <summary>
/// Extract 3x3 rotation from the 4x4 Matrix and return in new Matrix4
/// </summary>
/// <param name="transform">The transform matrix.</param>
/// <returns>Returns a Matrix4 containing the rotation.</returns>
Matrix4 Extract3x3Rotation(const Matrix4 &transform);
/// <summary>
/// Extract 3x3 rotation matrix from the Matrix4 4x4 transformation:
/// Then convert to Euler angles.
/// </summary>
/// <param name="transform">The transform matrix.</param>
/// <param name="rotation">Array of 3 floating point values for euler angles.</param>
void ExtractRot2Euler(const Matrix4 &transform, _Out_cap_c_(3) float *rotation);
/// <summary>
/// Test whether the camera moved too far between sequential frames by looking at starting and end transformation matrix.
/// We assume that if the camera moves or rotates beyond a reasonable threshold, that we have lost track.
/// Note that on lower end machines, if the processing frame rate decreases below 30Hz, this limit will potentially have
/// to be increased as frames will be dropped and hence there will be a greater motion between successive frames.
/// </summary>
/// <param name="T_initial">The transform matrix from the previous frame.</param>
/// <param name="T_final">The transform matrix from the current frame.</param>
/// <param name="maxTrans">The maximum translation in meters we expect per x,y,z component between frames under normal motion.</param>
/// <param name="maxRotDegrees">The maximum rotation in degrees we expect about the x,y,z axes between frames under normal motion.</param>
/// <returns>true if camera transformation is greater than the threshold, otherwise false</returns>
bool CameraTransformFailed(const Matrix4 &T_initial, const Matrix4 &T_final, float maxTrans, float maxRotDegrees);
/// <summary>
/// Invert the 3x3 Rotation Matrix Component of a 4x4 matrix
/// </summary>
/// <param name="rot">The rotation matrix to invert.</param>
void InvertRotation(Matrix4 &rot);
/// <summary>
/// Negate the 3x3 Rotation Matrix Component of a 4x4 matrix
/// </summary>
/// <param name="rot">The rotation matrix to negate.</param>
void NegateRotation(Matrix4 &rot);
/// <summary>
/// Rotate a vector with the 3x3 Rotation Matrix Component of a 4x4 matrix
/// </summary>
/// <param name="vec">The Vector3 to rotate.</param>
/// <param name="rot">Rotation matrix.</param>
Vector3 RotateVector(const Vector3 &vec, const Matrix4 &rot);
/// <summary>
/// Invert Matrix4 Pose either from WorldToCameraTransform (view) matrix to CameraToWorldTransform pose matrix (world/SE3) or vice versa
/// </summary>
/// <param name="transform">The camera pose transform matrix.</param>
/// <returns>Returns a Matrix4 containing the inverted camera pose.</returns>
Matrix4 InvertMatrix4Pose(const Matrix4 &transform);
/// <summary>
/// Write Binary .STL mesh file
/// see http://en.wikipedia.org/wiki/STL_(file_format) for STL format
/// </summary>
/// <param name="mesh">The Kinect Fusion mesh object.</param>
/// <param name="lpOleFileName">The full path and filename of the file to save.</param>
/// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save.</param>
/// <returns>indicates success or failure</returns>
HRESULT WriteBinarySTLMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true);
/// <summary>
/// Write ASCII Wavefront .OBJ mesh file
/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format
/// </summary>
/// <param name="mesh">The Kinect Fusion mesh object.</param>
/// <param name="lpOleFileName">The full path and filename of the file to save.</param>
/// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save.</param>
/// <returns>indicates success or failure</returns>
HRESULT WriteAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true);
/// <summary>
/// Write ASCII .PLY file
/// See http://paulbourke.net/dataformats/ply/ for .PLY format
/// </summary>
/// <param name="mesh">The Kinect Fusion mesh object.</param>
/// <param name="lpOleFileName">The full path and filename of the file to save.</param>
/// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save.</param>
/// <param name="outputColor">Set this true to write out the surface color to the file when it has been captured.</param>
/// <returns>indicates success or failure</returns>
HRESULT WriteAsciiPlyMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true, bool outputColor = false);
/// <summary>
/// Write ASCII Wavefront .OBJ file with bitmap texture and material file
/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format
/// </summary>
/// <param name="mesh">The Kinect Fusion mesh object.</param>
/// <param name="lpOleFileName">The full path and filename of the file to save.</param>
/// <param name="flipYZ">Flag to determine whether the Y and Z values are flipped on save.</param>
/// <param name="pTexture">The Kinect Fusion color texture image.</param>
/// <param name="texcoords">Three Vector3 texture coordinates per mesh triangle, normalized by the image size.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT WriteTexturedeAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ, NUI_FUSION_IMAGE_FRAME *pTexture, const std::vector<Vector3> &texcoords);
/// <summary>
/// Returns whether this is running as a 32 or 64bit application.
/// </summary>
/// <returns>TRUE indicates a 64bit app.</returns>
BOOL Is64BitApp();
/// <summary>
/// Write 32bit BMP image file
/// </summary>
/// <param name="pszFile">The full path and filename of the file to save.</param>
/// <param name="imageBytes">A pointer to the image bytes to save.</param>
/// <param name="width">The width of the image to save.</param>
/// <param name="height">The width of the image to save.</param>
/// <returns>indicates success or failure</returns>
HRESULT SaveBMPFile(LPCWSTR pszFile, const byte *pImageBytes, unsigned int width, unsigned int height);
/// <summary>
/// Copy an image with identical sizes and parameters.
/// </summary>
/// <param name="pSrc">A pointer to the source image.</param>
/// <param name="pDest">A pointer to the destination image.</param>
/// <returns>indicates success or failure</returns>
HRESULT CopyImageFrame(const NUI_FUSION_IMAGE_FRAME *pSrc, const NUI_FUSION_IMAGE_FRAME *pDest);
/// <summary>
/// Horizontally mirror a 32bit (color/float) image in-place.
/// </summary>
/// <param name="pImage">A pointer to the image to mirror.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT HorizontalMirror32bitImageInPlace(const NUI_FUSION_IMAGE_FRAME *pImage);
/// <summary>
/// Horizontally mirror a 32bit (color/float) image.
/// </summary>
/// <param name="pSrcImage">A pointer to the image to mirror.</param>
/// <param name="pDestImage">A pointer to the destination mirrored image.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT HorizontalMirror32bitImage(const NUI_FUSION_IMAGE_FRAME *pSrcImage, const NUI_FUSION_IMAGE_FRAME *pDestImage);
/// <summary>
/// Color the residual/delta image from the AlignDepthFloatToReconstruction call
/// </summary>
/// <param name="pFloatDeltaFromReference">A pointer to the source pFloatDeltaFromReference image.</param>
/// <param name="pShadedDeltaFromReference">A pointer to the destination ShadedDeltaFromReference image.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT ColorResiduals(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, const NUI_FUSION_IMAGE_FRAME *pShadedDeltaFromReference);
/// <summary>
/// Statistics calculated for a FloatDeltaFromReference Image after the
/// AlignDepthFloatToReconstruction and CalculateResidualStatistics calls.
/// </summary>
struct DeltaFromReferenceImageStatistics
{
unsigned int totalPixels;
unsigned int zeroPixels;
unsigned int validPixels;
unsigned int invalidDepthOutsideVolumePixels;
float totalValidPixelsDistance;
};
/// <summary>
/// Calculate statistics on the residual/delta image from the AlignDepthFloatToReconstruction call.
/// </summary>
/// <param name="pFloatDeltaFromReference">A pointer to the source FloatDeltaFromReference image.</param>
/// <param name="stats">A pointer to a DeltaFromReferenceImageStatistics struct to fill with the statistics.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT CalculateResidualStatistics(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, DeltaFromReferenceImageStatistics *stats);
/// <summary>
/// Down sample color, depth float or point cloud frame with nearest neighbor
/// </summary>
/// <param name="src">The source color, depth float or pointcloud image.</param>
/// <param name="dest">The destination down sampled color, depth float or pointcloud image.</param>
/// <param name="factor">The down sample factor (1=just copy, 2=x/2,y/2, 4=x/4,y/4).</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT DownsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor);
/// <summary>
/// Up sample color or depth float (32 bits/pixel) frame with nearest neighbor - replicates pixels
/// </summary>
/// <param name="src">The source color image.</param>
/// <param name="dest">The destination up-sampled color image.</param>
/// <param name="factor">The up sample factor (1=just copy, 2=x*2,y*2, 4=x*4,y*4).</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT UpsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor);
/// <summary>
/// Down sample color frame with nearest neighbor to the depth frame resolution
/// </summary>
/// <param name="src">The source color image.</param>
/// <param name="dest">The destination down sampled image.</param>
/// <returns>S_OK on success, otherwise failure code</returns>
HRESULT DownsampleColorFrameToDepthResolution(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest);
/// <summary>
/// Convert int to string
/// </summary>
/// <param name="theValue">The int value to convert.</param>
/// <returns>Returns a string containing the int value.</returns>
inline std::string to_string(int theValue)
{
char buffer[65];
errno_t err = _itoa_s(theValue, buffer, ARRAYSIZE(buffer), 10);
if (0 != err)
{
return std::string("");
}
return std::string(buffer);
}
/// <summary>
/// Convert float to string
/// </summary>
/// <param name="theValue">The float value to convert.</param>
/// <returns>Returns a string containing the float value.</returns>
inline std::string to_string(float theValue)
{
char buffer[_CVTBUFSIZE];
errno_t err = _gcvt_s(buffer, _CVTBUFSIZE, theValue, 6);
if (0 != err)
{
return std::string("");
}
return std::string(buffer);
}
/// <summary>
/// Clamp a value if outside two given thresholds
/// </summary>
/// <param name="x">The value to clamp.</param>
/// <param name="a">The minimum inclusive threshold.</param>
/// <param name="b">The maximum inclusive threshold.</param>
/// <returns>Returns the clamped value.</returns>
template <typename T>
inline T clamp(const T& x, const T& a, const T& b)
{
if (x < a)
return a;
else if (x > b)
return b;
else
return x;
}
/// <summary>
/// Load an 24bit RGB color from a packed int pixel image and return as float values
/// </summary>
/// <param name="colorImage">The int image array.</param>
/// <param name="x">The x coordinate of the pixel to return.</param>
/// <param name="y">The y coordinate of the pixel to return.</param>
/// <param name="imageWidth">The width of the image in pixels.</param>
/// <returns>Returns a Vector3 containing the rgb color components.</returns>
inline Vector3 load_color(const unsigned int *colorImage, int x, int y, int imageWidth)
{
Vector3 rgb;
unsigned int packedValue = colorImage[(y * imageWidth) + x];
rgb.x = static_cast<float>(packedValue & 255); // r
rgb.y = static_cast<float>((packedValue >> 8) & 255); // g
rgb.z = static_cast<float>((packedValue >> 16) & 255); // b
return rgb;
}
/// <summary>
/// Linearly interpolate (Lerp) between two values.
/// </summary>
/// <param name="z">The first value.</param>
/// <param name="b">The second value.</param>
/// <param name="f">The amount to interpolate between the values.</param>
/// <returns>Returns the interpolated value.</returns>
template <typename T, typename Tf>
inline auto lerp(const T& a, const T& b, Tf f) -> decltype(a + f * (b - a))
{
return a + f * (b - a);
}
/// <summary>
/// Linearly interpolate (Lerp) between two Vector3-based RGB color pixels.
/// </summary>
/// <param name="z">The first color pixel.</param>
/// <param name="b">The second color pixel.</param>
/// <param name="f">The amount to interpolate between the values.</param>
/// <returns>Returns the interpolated value.</returns>
inline Vector3 lerp_color(const Vector3 &a, const Vector3 &b, float f)
{
Vector3 rgb;
rgb.x = lerp(a.x, b.x, f); // r
rgb.y = lerp(a.y, b.y, f); // g
rgb.z = lerp(a.z, b.z, f); // b
return rgb;
}
/// <summary>
/// Bilinear sample an RGB int image
/// </summary>
/// <param name="colorImage">The int image array.</param>
/// <param name="x">The x coordinate of the pixel to return.</param>
/// <param name="y">The y coordinate of the pixel to return.</param>
/// <param name="imageWidth">The width of the image in pixels.</param>
/// <param name="imageHeight">The height of the image in pixels.</param>
/// <returns>Returns a packed int containing the rgb color components.</returns>
inline unsigned int bilinear_sample(const unsigned int *colorImage, float x, float y, int imageWidth, int imageHeight)
{
const float half = 0.5f;
const unsigned int xi = static_cast<unsigned int>(x - half);
const unsigned int yi = static_cast<unsigned int>(y - half);
const float xf = x - half - static_cast<float>(xi);
const float yf = y - half - static_cast<float>(yi);
const unsigned int posax = clamp<unsigned int>(xi, 0, imageWidth - 1);
const unsigned int posay = clamp<unsigned int>(yi, 0, imageHeight - 1);
const unsigned int posbx = clamp<unsigned int>(xi+1, 0, imageWidth - 1);
const unsigned int posby = clamp<unsigned int>(yi+1, 0, imageHeight - 1);
// Load the corners
Vector3 d00 = load_color(colorImage, posax, posay, imageWidth);
Vector3 d01 = load_color(colorImage, posax, posby, imageWidth);
Vector3 d10 = load_color(colorImage, posbx, posay, imageWidth);
Vector3 d11 = load_color(colorImage, posbx, posby, imageWidth);
// Interpolate over x
auto dx0 = lerp_color(d00, d10, xf);
auto dx1 = lerp_color(d01, d11, xf);
// Interpolate over y
auto dxy = lerp_color(dx0, dx1, yf);
return (255 << 24 | static_cast<unsigned int>(dxy.z) << 16 | static_cast<unsigned int>(dxy.y) << 8 | static_cast<unsigned int>(dxy.x) ); // always full alpha
}
/// <summary>
/// Calculate the squared difference between two Vector3 vertices
/// </summary>
/// <param name="v1">The first vertex.</param>
/// <param name="v2">The second vertex.</param>
/// <returns>Returns the squared difference.</returns>
inline float squared_difference(const Vector3 &v1, const Vector3 &v2)
{
float dx = v1.x-v2.x;
float dy = v1.y-v2.y;
float dz = v1.z-v2.z;
return (dx*dx) + (dy*dy) + (dz*dz);
}
/// <summary>
/// Calculate the distance between two Vector3 vertices
/// </summary>
/// <param name="v1">The first vertex.</param>
/// <param name="v2">The second vertex.</param>
/// <returns>Returns the distance.</returns>
inline float distance(const Vector3 &v1, const Vector3 &v2)
{
return sqrtf(squared_difference(v1, v2));
}
/// <summary>
/// Calculate the normalized dot product between two vectors.
/// Must be normalized input Vector3s.
/// Output: 1 if parallel, same dir, 0 if 90 degrees, -1 if parallel, looking opposite direction
/// </summary>
/// <param name="v1">The first vector.</param>
/// <param name="v2">The second vector.</param>
/// <returns>Returns the dot product.</returns>
inline float dot_normalized(const Vector3 &v1, const Vector3 &v2)
{
return (v1.x*v2.x) + (v1.y*v2.y) + (v1.z*v2.z);
}
/// <summary>
/// Transform a vertex in the world coordinate system by the worldToCamera pose,
/// into the camera coordinate system.
/// </summary>
/// <param name="v1">The vertex to transform.</param>
/// <param name="worldToCamera">The worldToCamera pose.</param>
/// <returns>Returns the transformed vertex.</returns>
inline Vector3 transform(const Vector3 &v1, const Matrix4 &worldToCamera)
{
// Transform the point from the global frame into the local camera frame.
Vector3 R;
R.x = worldToCamera.M41 + (worldToCamera.M11 * v1.x) + (worldToCamera.M21 * v1.y) + (worldToCamera.M31 * v1.z);
R.y = worldToCamera.M42 + (worldToCamera.M12 * v1.x) + (worldToCamera.M22 * v1.y) + (worldToCamera.M32 * v1.z);
R.z = worldToCamera.M43 + (worldToCamera.M13 * v1.x) + (worldToCamera.M23 * v1.y) + (worldToCamera.M33 * v1.z);
return R;
}
/// <summary>
/// Project a 3D vertex in the world coordinate system into a 2D camera image,
/// given its known intrinsic parameters and camera pose.
/// </summary>
/// <param name="v1">The vertex to transform.</param>
/// <param name="flx">The focal length in the x axis, in pixels.</param>
/// <param name="fly">The focal length in the y axis, in pixels.</param>
/// <param name="ppx">The principal point of the image in the x axis, in pixels.</param>
/// <param name="ppy">The principal point of the image in the y axis, in pixels.</param>
/// <param name="worldToCamera">The worldToCamera pose.</param>
/// <returns>Returns the 3D vertex transformed into a pixel in the 2D camera image.</returns>
inline Vector3 fast_project(const Vector3 &v1, float flx, float fly, float ppx, float ppy, const Matrix4 &worldToCamera)
{
// Transform from world to camera coordinate system
Vector3 R = transform(v1, worldToCamera);
Vector3 uv;
uv.x = R.x / R.z;
uv.y = R.y / R.z;
// Project from camera plane in world to image
uv.x = ppx + flx * uv.x;
uv.y = ppy + fly * uv.y;
uv.z = R.z;
return uv;
}

View File

@ -0,0 +1,365 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <ppl.h>
#include <atlbase.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
else if( key == 'r' ){
std::cout << "Reset Reconstruction" << std::endl;
reset();
}
else if( key == 's' ){
std::cout << "Save Mesh Data to File" << std::endl;
save();
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Depth
initializeDepth();
// Initialize Fusion
initializeFusion();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Depth
inline void Kinect::initializeDepth()
{
// Open Depth Reader
ComPtr<IDepthFrameSource> depthFrameSource;
ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) );
ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) );
// Retrieve Depth Description
ComPtr<IFrameDescription> depthFrameDescription;
ERROR_CHECK( depthFrameSource->get_FrameDescription( &depthFrameDescription ) );
ERROR_CHECK( depthFrameDescription->get_Width( &depthWidth ) ); // 512
ERROR_CHECK( depthFrameDescription->get_Height( &depthHeight ) ); // 424
ERROR_CHECK( depthFrameDescription->get_BytesPerPixel( &depthBytesPerPixel ) ); // 2
// Allocation Depth Buffer
depthBuffer.resize( depthWidth * depthHeight );
}
// Initialize Fusion
inline void Kinect::initializeFusion()
{
// Set Reconstruction Parameters
reconstructionParameters.voxelsPerMeter = 256;
reconstructionParameters.voxelCountX = 512;
reconstructionParameters.voxelCountY = 384;
reconstructionParameters.voxelCountZ = 512;
// Create Reconstruction
SetIdentityMatrix( worldToCameraTransform );
ERROR_CHECK( NuiFusionCreateColorReconstruction( &reconstructionParameters, NUI_FUSION_RECONSTRUCTION_PROCESSOR_TYPE::NUI_FUSION_RECONSTRUCTION_PROCESSOR_TYPE_AMP, -1, &worldToCameraTransform, &reconstruction ) );
// Set Camera Parameters
cameraParameters.focalLengthX = NUI_KINECT_DEPTH_NORM_FOCAL_LENGTH_X;
cameraParameters.focalLengthY = NUI_KINECT_DEPTH_NORM_FOCAL_LENGTH_Y;
cameraParameters.principalPointX = NUI_KINECT_DEPTH_NORM_PRINCIPAL_POINT_X;
cameraParameters.principalPointY = NUI_KINECT_DEPTH_NORM_PRINCIPAL_POINT_Y;
// Create Image Frame Buffers
ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_FLOAT, depthWidth, depthHeight, &cameraParameters, &depthImageFrame ) );
ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_FLOAT, depthWidth, depthHeight, &cameraParameters, &smoothDepthImageFrame ) );
ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_COLOR, depthWidth, depthHeight, &cameraParameters, &colorImageFrame ) );
ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_POINT_CLOUD, depthWidth, depthHeight, &cameraParameters, &pointCloudImageFrame ) );
ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_COLOR, depthWidth, depthHeight, &cameraParameters, &surfaceImageFrame ) );
/*ERROR_CHECK( NuiFusionCreateImageFrame( NUI_FUSION_IMAGE_TYPE::NUI_FUSION_IMAGE_TYPE_COLOR, depthWidth, depthHeight, &cameraParameters, &normalImageFrame ) );*/
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Release Image Frame Buffers
ERROR_CHECK( NuiFusionReleaseImageFrame( depthImageFrame ) );
ERROR_CHECK( NuiFusionReleaseImageFrame( smoothDepthImageFrame ) );
ERROR_CHECK( NuiFusionReleaseImageFrame( colorImageFrame ) );
ERROR_CHECK( NuiFusionReleaseImageFrame( pointCloudImageFrame ) );
ERROR_CHECK( NuiFusionReleaseImageFrame( surfaceImageFrame ) );
/*ERROR_CHECK( NuiFusionReleaseImageFrame( normalImageFrame ) );*/
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Depth
updateDepth();
// Update Fusion
updateFusion();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Depth
inline void Kinect::updateDepth()
{
// Retrieve Depth Frame
ComPtr<IDepthFrame> depthFrame;
const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Depth Data
ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast<UINT>( depthBuffer.size() ), &depthBuffer[0] ) );
}
// Update Fusion
inline void Kinect::updateFusion()
{
// Set Depth Data to Depth Float Frame Buffer
ERROR_CHECK( reconstruction->DepthToDepthFloatFrame( &depthBuffer[0], static_cast<UINT>( depthBuffer.size() * depthBytesPerPixel ), depthImageFrame, NUI_FUSION_DEFAULT_MINIMUM_DEPTH/* 0.5[m] */, NUI_FUSION_DEFAULT_MAXIMUM_DEPTH/* 8.0[m] */, true ) );
// Smoothing Depth Float Frame
ERROR_CHECK( reconstruction->SmoothDepthFloatFrame( depthImageFrame, smoothDepthImageFrame, NUI_FUSION_DEFAULT_SMOOTHING_KERNEL_WIDTH, NUI_FUSION_DEFAULT_SMOOTHING_DISTANCE_THRESHOLD ) );
// Retrieve Mapped Coordinates
std::vector<ColorSpacePoint> points( depthWidth * depthHeight );
ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthWidth * depthHeight, &depthBuffer[0], depthWidth * depthHeight, &points[0] ) );
// Mapping Color to Depth Resolution and Set Color Data to Color Frame Buffer
NUI_FUSION_BUFFER* colorImageFrameBuffer = colorImageFrame->pFrameBuffer;
RGBQUAD* src = reinterpret_cast<RGBQUAD*>( &colorBuffer[0] );
RGBQUAD* dst = reinterpret_cast<RGBQUAD*>( colorImageFrameBuffer->pBits );
Concurrency::parallel_for( 0, depthHeight, [&]( const int y ){
for( int x = 0; x < depthWidth; x++ ){
unsigned int index = y * depthWidth + x;
const ColorSpacePoint point = points[index];
int colorX = static_cast<int>( point.X + 0.5f );
int colorY = static_cast<int>( point.Y + 0.5f );
if( ( 0 <= colorX ) && ( colorX < colorWidth ) && ( 0 <= colorY ) && ( colorY < colorHeight ) ){
dst[index] = src[colorY * colorWidth + colorX];
}
else{
dst[index] = {};
}
}
} );
// Retrieve Transformation Matrix to Camera Coordinate System from World Coordinate System
ERROR_CHECK( reconstruction->GetCurrentWorldToCameraTransform( &worldToCameraTransform ) );
// Reconstruction Frame Process
HRESULT ret = reconstruction->ProcessFrame( smoothDepthImageFrame, colorImageFrame, NUI_FUSION_DEFAULT_ALIGN_ITERATION_COUNT, NUI_FUSION_DEFAULT_INTEGRATION_WEIGHT, NUI_FUSION_DEFAULT_COLOR_INTEGRATION_OF_ALL_ANGLES, nullptr, &worldToCameraTransform );
if( FAILED( ret ) ){
// Reset Reconstruction when Retrived Many Accumulated Error Frames ( Over 100 Error Frames )
static unsigned int errorCount = 0;
if( ++errorCount >= 100 ){
errorCount = 0;
reset();
}
}
// Calculate Point Cloud
ERROR_CHECK( reconstruction->CalculatePointCloud( pointCloudImageFrame, surfaceImageFrame, &worldToCameraTransform ) );
/*
// Shading Color Transform Matrix
Matrix4 worldToBGRTransform = { 0.0f };
worldToBGRTransform.M11 = reconstructionParameters.voxelsPerMeter / reconstructionParameters.voxelCountX;
worldToBGRTransform.M22 = reconstructionParameters.voxelsPerMeter / reconstructionParameters.voxelCountY;
worldToBGRTransform.M33 = reconstructionParameters.voxelsPerMeter / reconstructionParameters.voxelCountZ;
worldToBGRTransform.M41 = 0.5f;
worldToBGRTransform.M42 = 0.5f;
worldToBGRTransform.M43 = 0.0f;
worldToBGRTransform.M44 = 1.0f;
// Shading Point Cloud
ERROR_CHECK( NuiFusionShadePointCloud( pointCloudImageFrame, &worldToCameraTransform, &worldToBGRTransform, surfaceImageFrame, normalImageFrame ) );
*/
}
// Reset Reconstruction
inline void Kinect::reset()
{
// Set Identity Matrix
SetIdentityMatrix( worldToCameraTransform );
// Reset Reconstruction
ERROR_CHECK( reconstruction->ResetReconstruction( &worldToCameraTransform, nullptr ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Fusion
drawFusion();
}
// Draw Fusion
inline void Kinect::drawFusion()
{
// Retrive Surface Image from Surface Frame Buffer
NUI_FUSION_BUFFER* surfaceImageFrameBuffer = surfaceImageFrame->pFrameBuffer;
surfaceMat = cv::Mat( depthHeight, depthWidth, CV_8UC4, surfaceImageFrameBuffer->pBits );
/*
// Retrive Normal Image from Normal Frame Buffer
NUI_FUSION_BUFFER* normalImageFrameBuffer = normalImageFrame->pFrameBuffer;
normalMat = cv::Mat( depthHeight, depthWidth, CV_8UC4, normalImageFrameBuffer->pBits );
*/
}
// Show Data
void Kinect::show()
{
// Show Fusion
showFusion();
}
// Show Fusion
inline void Kinect::showFusion()
{
if( surfaceMat.empty() ){
return;
}
// Show Surface Image
cv::imshow( "Surface", surfaceMat );
/*
if( normalMat.empty() ){
return;
}
// Show Normal Image
cv::imshow( "Normal", normalMat );
*/
}
// Save Mesh
inline void Kinect::save()
{
// Calculate Mesh Data
ComPtr<INuiFusionColorMesh> mesh;
ERROR_CHECK( reconstruction->CalculateMesh( 1, &mesh ) );
// Save Mesh Data to PLY File
wchar_t* fileName = L"../mesh.ply";
WriteAsciiPlyMeshFile( mesh.Get(), W2OLE( fileName ), true, true );
/*
// Save Mesh Data to STL File
wchar_t* fileName = L"../mesh.stl";
ERROR_CHECK( WriteBinarySTLMeshFile( mesh, W2OLE( fileName ), true ) );
*/
/*
// Save Mesh Data to Obj File
wchar_t* fileName = L"../mesh.obj";
ERROR_CHECK( WriteAsciiObjMeshFile( mesh, W2OLE( fileName ), true ) );
*/
}

View File

@ -0,0 +1,118 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <NuiKinectFusionApi.h>
// Quote from Kinect for Windows SDK v2.0 - Samples/Native/KinectFusionExplorer-D2D, and Partial Modification
// KinectFusionHelper is: Copyright (c) Microsoft Corporation. All rights reserved.
#include "KinectFusionHelper.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IDepthFrameReader> depthFrameReader;
// Fusion
ComPtr<INuiFusionColorReconstruction> reconstruction;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
// Depth Buffer
std::vector<UINT16> depthBuffer;
int depthWidth;
int depthHeight;
unsigned int depthBytesPerPixel;
// Fusion Buffer
NUI_FUSION_IMAGE_FRAME* depthImageFrame;
NUI_FUSION_IMAGE_FRAME* smoothDepthImageFrame;
NUI_FUSION_IMAGE_FRAME* colorImageFrame;
NUI_FUSION_IMAGE_FRAME* pointCloudImageFrame;
NUI_FUSION_IMAGE_FRAME* surfaceImageFrame;
/*NUI_FUSION_IMAGE_FRAME* normalImageFrame;*/
NUI_FUSION_RECONSTRUCTION_PARAMETERS reconstructionParameters;
NUI_FUSION_CAMERA_PARAMETERS cameraParameters;
Matrix4 worldToCameraTransform;
cv::Mat surfaceMat;
/*cv::Mat normalMat;*/
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Depth
inline void initializeDepth();
// Initialize Fusion
inline void initializeFusion();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Depth
inline void updateDepth();
// Update Fusion
inline void updateFusion();
// Reset Reconstruction
inline void reset();
// Draw Data
void draw();
// Draw Fusion
inline void drawFusion();
// Show Data
void show();
// Show Fusion
inline void showFusion();
// Save Mesh
inline void save();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,47 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Gesture app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Gesture" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_VGB TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Gesture ${KinectSDK2_LIBRARIES} )
target_link_libraries( Gesture ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET Gesture POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

Binary file not shown.

View File

@ -0,0 +1,431 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Initialize Gesture
initializeGesture();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
}
// Initialize Gesture
inline void Kinect::initializeGesture()
{
for( int count = 0; count < BODY_COUNT; count++ ){
// Create Gesture Source
ComPtr<IVisualGestureBuilderFrameSource> gestureFrameSource;
ERROR_CHECK( CreateVisualGestureBuilderFrameSource( kinect.Get(), 0, &gestureFrameSource ) );
// Open Gesture Reader
ERROR_CHECK( gestureFrameSource->OpenReader( &gestureFrameReader[count] ) );
};
// Read Gesture Databese from File (*.gdb)
// SampleDatabase recognize gestures that is steering wheel operations of car.
ComPtr<IVisualGestureBuilderDatabase> gestureDatabase;
ERROR_CHECK( CreateVisualGestureBuilderDatabaseInstanceFromFile( L"../SampleDatabase.gbd", &gestureDatabase ) );
// Retrive Number of Gestures that included in Gesture Database
UINT gestureCount;
ERROR_CHECK( gestureDatabase->get_AvailableGesturesCount( &gestureCount ) );
// Retrive Gestures
gestures.resize( gestureCount );
ERROR_CHECK( gestureDatabase->get_AvailableGestures( gestureCount, &gestures[0] ) );
for( int count = 0; count < BODY_COUNT; count++ ){
// Create Gesture Source
ComPtr<IVisualGestureBuilderFrameSource> gestureFrameSource;
ERROR_CHECK( gestureFrameReader[count]->get_VisualGestureBuilderFrameSource( &gestureFrameSource ) );
// Registration Gestures
ERROR_CHECK( gestureFrameSource->AddGestures( gestureCount, gestures[0].GetAddressOf() ) );
// Set Gesture Detection to Enable
Concurrency::parallel_for_each( gestures.begin(), gestures.end(), [&]( const ComPtr<IGesture>& gesture ){
ERROR_CHECK( gestureFrameSource->SetIsEnabled( gesture.Get(), TRUE ) );
} );
}
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
// Update Gesture
updateGesture();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Body Data
std::array<ComPtr<IBody>, BODY_COUNT> bodies = { nullptr };
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const ComPtr<IBody> body = bodies[count];
BOOLEAN tracked;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Tracking ID
UINT64 trackingId;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
// Registration Tracking ID
ComPtr<IVisualGestureBuilderFrameSource> gestureFrameSource;
ERROR_CHECK( gestureFrameReader[count]->get_VisualGestureBuilderFrameSource( &gestureFrameSource ) );
gestureFrameSource->put_TrackingId( trackingId );
} );
}
// Update Gesture
inline void Kinect::updateGesture()
{
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
// Clear Gesture Result Buffer
std::vector<std::string>& result = results[count];
result.clear();
// Retrieve Gesture Frame
ComPtr<IVisualGestureBuilderFrame> gestureFrame;
HRESULT ret = gestureFrameReader[count]->CalculateAndAcquireLatestFrame( &gestureFrame );
if( FAILED( ret ) ){
return;
}
// Check Tracking ID is Valid
BOOLEAN tracked;
ERROR_CHECK( gestureFrame->get_IsTrackingIdValid( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Gesture Result
Concurrency::parallel_for_each( gestures.begin(), gestures.end(), [&]( const ComPtr<IGesture>& gesture ){
// Switch Processing of Retrieve Gesture Result by Gesture Type
GestureType gestureType;
ERROR_CHECK( gesture->get_GestureType( &gestureType ) );
switch( gestureType ){
case GestureType::GestureType_Discrete:
{
// Retrieve Discrete Gesture Result
const std::string gestureResult = retrieveDiscreteGestureResult( gestureFrame, gesture );
// Add Gesture Result to Buffer
if( !gestureResult.empty() ){
result.push_back( gestureResult );
}
break;
}
case GestureType::GestureType_Continuous:
{
// Retrieve Continuous Gesture Result
const std::string gestureResult = retrieveContinuousGestureResult( gestureFrame, gesture );
// Add Gesture Result Buffer
result.push_back( gestureResult );
break;
}
}
} );
} );
}
// Retrieve Discrete Gesture Result
inline std::string Kinect::retrieveDiscreteGestureResult( const ComPtr<IVisualGestureBuilderFrame>& gestureFrame, const ComPtr<IGesture>& gesture )
{
// Retrieve Discrete Gesture Result
ComPtr<IDiscreteGestureResult> gestureResult;
ERROR_CHECK( gestureFrame->get_DiscreteGestureResult( gesture.Get(), &gestureResult ) );
// Check Detected
BOOLEAN detected;
ERROR_CHECK( gestureResult->get_Detected( &detected ) );
if( !detected ){
return "";
}
// Retrieve Confidence ( 0.0f - 1.0f )
float confidence;
ERROR_CHECK( gestureResult->get_Confidence( &confidence ) );
const std::string gestureConfidence = std::to_string( confidence );
// Retrive Gesture Name
const std::string gestureName = gesture2string( gesture );
return gestureName + " : Detected (" + gestureConfidence + ")";
}
// Retrieve Continuous Gesture Result
inline std::string Kinect::retrieveContinuousGestureResult( const ComPtr<IVisualGestureBuilderFrame>& gestureFrame, const ComPtr<IGesture>& gesture )
{
// Retrieve Continuous Gesture Result
ComPtr<IContinuousGestureResult> gestureResult;
ERROR_CHECK( gestureFrame->get_ContinuousGestureResult( gesture.Get(), &gestureResult ) );
// Retrieve Progress ( 0.0f - 1.0f )
float progress;
ERROR_CHECK( gestureResult->get_Progress( &progress ) );
// Adjustment Decimal Point Format ( Visualization to Two Decimal Places )
std::ostringstream oss;
oss << std::fixed << std::setprecision( 2 ) << ( progress * 100.0f );
const std::string gestureProgress = oss.str();
// Retrive Gesture Name
const std::string gestureName = gesture2string( gesture );
return gestureName + " : Progress " + gestureProgress + "%";
}
// Retrive Gesture Name
inline std::string Kinect::gesture2string( const ComPtr<IGesture>& gesture )
{
// Retrive Gesture Name
std::wstring buffer( BUFSIZ, L' ' );
ERROR_CHECK( gesture->get_Name( BUFSIZ, &buffer[0] ) );
// Trim Valid String Except Blank
const std::wstring::size_type last = buffer.find_last_not_of( L' ' );
if( last == std::wstring::npos ){
throw std::runtime_error( "failed " __FUNCTION__ );
}
const std::wstring temp = buffer.substr( 0, last );
// Convert Wide String to String
const std::string name( temp.begin(), temp.end() );
return name;
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw Gesture
drawGesture();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw Gesture
inline void Kinect::drawGesture()
{
if( colorMat.empty() ){
return;
}
// Reset New Line Offset for Visualization
offset = 0;
// Draw Gesture Results
Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){
const std::vector<std::string>& result = results[count];
drawResult( colorMat, result, cv::Point( 50, 50 ), 1.0, colors[count] );
} );
}
// Draw Results
inline void Kinect::drawResult( cv::Mat& image, const std::vector<std::string>& results, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Check Empty Gesture Result Buffer
if( results.empty() ){
return;
}
// Draw Results
for( const std::string result : results ){
cv::putText( image, result, cv::Point( point.x, point.y + offset ), cv::FONT_HERSHEY_SIMPLEX, scale, color, thickness, cv::LINE_AA );
offset += 30;
}
}
// Show Data
void Kinect::show()
{
// Show Gesture
showGesture();
}
// Show Gesture
inline void Kinect::showGesture()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "Gesture", resizeMat );
}

View File

@ -0,0 +1,114 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <Kinect.VisualGestureBuilder.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
std::array<ComPtr<IVisualGestureBuilderFrameReader>, BODY_COUNT> gestureFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// Gesture Buffer
std::vector<ComPtr<IGesture>> gestures;
std::array<std::vector<std::string>, BODY_COUNT> results;
std::array<cv::Vec3b, BODY_COUNT> colors;
int offset;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Initialize Gesture
inline void initializeGesture();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Update Gesture
inline void updateGesture();
// Retrieve Discrete Gesture Result
inline std::string retrieveDiscreteGestureResult( const ComPtr<IVisualGestureBuilderFrame>& gestureFrame, const ComPtr<IGesture>& gesture );
// Retrieve Continuous Gesture Result
inline std::string retrieveContinuousGestureResult( const ComPtr<IVisualGestureBuilderFrame>& gestureFrame, const ComPtr<IGesture>& gesture );
// Retrive Gesture Name
inline std::string gesture2string( const ComPtr<IGesture>& gesture );
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw Gesture
inline void drawGesture();
// Draw Results
inline void drawResult( cv::Mat& image, const std::vector<std::string>& results, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness = 2 );
// Show Data
void show();
// Show Gesture
inline void showGesture();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,47 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( HDFace app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "HDFace" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
set( KinectSDK2_FACE TRUE )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( HDFace ${KinectSDK2_LIBRARIES} )
target_link_libraries( HDFace ${OpenCV_LIBS} )
# Post Build Event
add_custom_command( TARGET HDFace POST_BUILD ${KinectSDK2_COMMANDS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,478 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
#include <limits>
#define _USE_MATH_DEFINES
#include <math.h>
#include <ppl.h>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Color
initializeColor();
// Initialize Body
initializeBody();
// Initialize HDFace
initializeHDFace();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
// Retrieve Coordinate Mapper
ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
}
// Initialize Color
inline void Kinect::initializeColor()
{
// Open Color Reader
ComPtr<IColorFrameSource> colorFrameSource;
ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
// Retrieve Color Description
ComPtr<IFrameDescription> colorFrameDescription;
ERROR_CHECK( colorFrameSource->CreateFrameDescription( ColorImageFormat::ColorImageFormat_Bgra, &colorFrameDescription ) );
ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) ); // 1920
ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) ); // 1080
ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) ); // 4
// Allocation Color Buffer
colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
}
// Initialize Body
inline void Kinect::initializeBody()
{
// Open Body Reader
ComPtr<IBodyFrameSource> bodyFrameSource;
ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
}
// Initialize HDFace
inline void Kinect::initializeHDFace()
{
// Create HDFace Sources
ComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
ERROR_CHECK( CreateHighDefinitionFaceFrameSource( kinect.Get(), &hdFaceFrameSource ) );
// Open HDFace Readers
ERROR_CHECK( hdFaceFrameSource->OpenReader( &hdFaceFrameReader ) );
// Create Face Alignment
ERROR_CHECK( CreateFaceAlignment( &faceAlignment ) );
// Create Face Model and Retrieve Vertex Count
ERROR_CHECK( CreateFaceModel( 1.0f, FaceShapeDeformations::FaceShapeDeformations_Count, &faceShapeUnits[0], &faceModel ) );
ERROR_CHECK( GetFaceModelVertexCount( &vertexCount ) ); // 1347
// Create and Start Face Model Builder
FaceModelBuilderAttributes attribures = FaceModelBuilderAttributes::FaceModelBuilderAttributes_None;
ERROR_CHECK( hdFaceFrameSource->OpenModelBuilder( attribures, &faceModelBuilder ) );
ERROR_CHECK( faceModelBuilder->BeginFaceDataCollection() );
// Color Table for Visualization
colors[0] = cv::Vec3b( 255, 0, 0 ); // Blue
colors[1] = cv::Vec3b( 0, 255, 0 ); // Green
colors[2] = cv::Vec3b( 0, 0, 255 ); // Red
colors[3] = cv::Vec3b( 255, 255, 0 ); // Cyan
colors[4] = cv::Vec3b( 255, 0, 255 ); // Magenta
colors[5] = cv::Vec3b( 0, 255, 255 ); // Yellow
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Color
updateColor();
// Update Body
updateBody();
// Update HDFace
updateHDFace();
}
// Update Color
inline void Kinect::updateColor()
{
// Retrieve Color Frame
ComPtr<IColorFrame> colorFrame;
const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
if( FAILED( ret ) ){
return;
}
// Convert Format ( YUY2 -> BGRA )
ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) );
}
// Update Body
inline void Kinect::updateBody()
{
// Retrieve Body Frame
ComPtr<IBodyFrame> bodyFrame;
const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Body Data
std::array<ComPtr<IBody>, BODY_COUNT> bodies;
ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
// Find Closest Body
findClosestBody( bodies );
}
// Find Closest Body
inline void Kinect::findClosestBody( const std::array<ComPtr<IBody>, BODY_COUNT>& bodies )
{
float closestDistance = std::numeric_limits<float>::max();
for( int count = 0; count < BODY_COUNT; count++ ){
const ComPtr<IBody> body = bodies[count];
BOOLEAN tracked;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
if( !tracked ){
continue;
}
// Retrieve Joint (Head)
std::array<Joint, JointType::JointType_Count> joints;
ERROR_CHECK( body->GetJoints( static_cast<UINT>( joints.size() ), &joints[0] ) );
const Joint joint = joints[JointType::JointType_Head];
if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
continue;
}
// Calculate Distance from Sensor ( <20><>( x^2 + y^2 + z^2 ) )
const CameraSpacePoint point = joint.Position;
const float distance = std::sqrt( std::pow( point.X, 2 ) + std::pow( point.Y, 2 ) + std::pow( point.Z, 2 ) );
if( closestDistance <= distance ){
continue;
}
closestDistance = distance;
// Retrieve Tracking ID
UINT64 trackingId;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
if( this->trackingId == trackingId ){
continue;
}
// Registration Tracking ID
ComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
ERROR_CHECK( hdFaceFrameReader->get_HighDefinitionFaceFrameSource( &hdFaceFrameSource ) );
ERROR_CHECK( hdFaceFrameSource->put_TrackingId( trackingId ) );
// Update Current
this->trackingId = trackingId;
this->trackingCount = count;
this->produced = false;
}
}
// Update HDFace
inline void Kinect::updateHDFace()
{
// Retrieve HDFace Frame
ComPtr<IHighDefinitionFaceFrame> hdFaceFrame;
const HRESULT ret = hdFaceFrameReader->AcquireLatestFrame( &hdFaceFrame );
if( FAILED( ret ) ){
return;
}
// Check Traced
BOOLEAN tracked;
ERROR_CHECK( hdFaceFrame->get_IsFaceTracked( &tracked ) );
if( !tracked ){
return;
}
// Retrieve Face Alignment Result
ERROR_CHECK( hdFaceFrame->GetAndRefreshFaceAlignmentResult( faceAlignment.Get() ) );
// Check Face Model Builder Status
FaceModelBuilderCollectionStatus collection;
ERROR_CHECK( faceModelBuilder->get_CollectionStatus( &collection ) );
if( collection ){
return;
}
// Retrieve Fitting Face Model
ComPtr<IFaceModelData> faceModelData;
ERROR_CHECK( faceModelBuilder->GetFaceData( &faceModelData ) );
ERROR_CHECK( faceModelData->ProduceFaceModel( &faceModel ) );
produced = true;
}
// Draw Data
void Kinect::draw()
{
// Draw Color
drawColor();
// Draw HDFace
drawHDFace();
}
// Draw Color
inline void Kinect::drawColor()
{
// Create cv::Mat from Color Buffer
colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
}
// Draw HDFace
inline void Kinect::drawHDFace()
{
if( colorMat.empty() ){
return;
}
// Draw Face Model Builder Status
drawFaceModelBuilderStatus( colorMat, cv::Point( 50, 50 ), 1.0, colors[trackingCount] );
// Retrieve Vertexes
std::vector<CameraSpacePoint> vertexes( vertexCount );
ERROR_CHECK( faceModel->CalculateVerticesForAlignment( faceAlignment.Get(), vertexCount, &vertexes[0] ) );
drawVertexes( colorMat, vertexes, 2, colors[trackingCount] );
/*
// Retrieve Head Pivot Point
CameraSpacePoint point;
ERROR_CHECK( faceAlignment->get_HeadPivotPoint( &point ) );
std::cout << point.X << ", " << point.Y << ", " << point.Z << std::endl;
*/
/*
// Retrieve Animation Units ... Motion of Face Parts that Represent Expression (17 AUs)
std::array<float, FaceShapeAnimations::FaceShapeAnimations_Count> animationUnits;
ERROR_CHECK( faceAlignment->GetAnimationUnits( FaceShapeAnimations::FaceShapeAnimations_Count, &animationUnits[0] ) );
for( const float animationUnit : animationUnits ){
std::cout << std::to_string( animationUnit ) << std::endl;
}
*/
/*
// Retrieve Shape Units ... Deformations from Default Face Model (94 SUs)
ERROR_CHECK( faceModel->GetFaceShapeDeformations( FaceShapeDeformations::FaceShapeDeformations_Count, &shapeUnits[0] ) );
for( const float shapeUnit : shapeUnits ){
std::cout << std::to_string( shapeUnit ) << std::endl;
}
*/
/*
// Retrieve Face Model Scale
float scale;
ERROR_CHECK( faceModel->get_Scale( &scale ) );
std::cout << std::to_string( scale ) << std::endl;
*/
/*
// Retrieve Hair Color (XBGR)
// Set FaceModelBuilderAttributes::FaceModelBuilderAttributes_HairColor to IHighDefinitionFaceFrameSource::OpenModelBuilder()
UINT32 hairColor;
ERROR_CHECK( faceModel->get_HairColor( &hairColor ) );
std::cout << ( ( hairColor & 0xff000000 ) >> 24 ) << std::endl; // X
std::cout << ( ( hairColor & 0x00ff0000 ) >> 16 ) << std::endl; // B
std::cout << ( ( hairColor & 0x0000ff00 ) >> 8 ) << std::endl; // G
std::cout << ( ( hairColor & 0x000000ff ) >> 0 ) << std::endl; // R
*/
/*
// Retrieve Skin Color (XBGR)
// Set FaceModelBuilderAttributes::FaceModelBuilderAttributes_SkinColor to IHighDefinitionFaceFrameSource::OpenModelBuilder()
UINT32 skinColor;
ERROR_CHECK( faceModel->get_SkinColor( &skinColor ) );
std::cout << ( ( skinColor & 0xff000000 ) >> 24 ) << std::endl; // X
std::cout << ( ( skinColor & 0x00ff0000 ) >> 16 ) << std::endl; // B
std::cout << ( ( skinColor & 0x0000ff00 ) >> 8 ) << std::endl; // G
std::cout << ( ( skinColor & 0x000000ff ) >> 0 ) << std::endl; // R
*/
}
// Draw Face Model Builder Status
inline void Kinect::drawFaceModelBuilderStatus( cv::Mat& image, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Check Produced
if( produced ){
cv::putText( image, "Collection Complete", cv::Point( point.x, point.y ), cv::FONT_HERSHEY_SIMPLEX, scale, color, thickness, cv::LINE_AA );
return;
}
// Retrieve Face Model Builder Collection Status
FaceModelBuilderCollectionStatus collection;
ERROR_CHECK( faceModelBuilder->get_CollectionStatus( &collection ) );
// Retrieve Face Model Builder Capture Status
FaceModelBuilderCaptureStatus capture;
ERROR_CHECK( faceModelBuilder->get_CaptureStatus( &capture ) );
// Draw Status
cv::putText( image, status2string( collection ), cv::Point( point.x, point.y ), cv::FONT_HERSHEY_SIMPLEX, scale, color, thickness, cv::LINE_AA );
cv::putText( image, status2string( capture ), cv::Point( point.x, point.y + 30 ), cv::FONT_HERSHEY_SIMPLEX, scale, color, thickness, cv::LINE_AA );
}
// Convert Collection Status to String
inline std::string Kinect::status2string( const FaceModelBuilderCollectionStatus collection )
{
std::string status;
if( collection & FaceModelBuilderCollectionStatus::FaceModelBuilderCollectionStatus_TiltedUpViewsNeeded ){
status = "Collection Status : Needed Tilted Up Views";
}
else if( collection & FaceModelBuilderCollectionStatus::FaceModelBuilderCollectionStatus_RightViewsNeeded ){
status = "Collection Status : Needed Right Views";
}
else if( collection & FaceModelBuilderCollectionStatus::FaceModelBuilderCollectionStatus_LeftViewsNeeded ){
status = "Collection Status : Needed Left Views";
}
else if( collection & FaceModelBuilderCollectionStatus::FaceModelBuilderCollectionStatus_FrontViewFramesNeeded ){
status = "Collection Status : Needed Front View Frames";
}
return status;
}
// Convert Capture Status to String
inline std::string Kinect::status2string( const FaceModelBuilderCaptureStatus capture )
{
std::string status;
switch( capture ){
case FaceModelBuilderCaptureStatus::FaceModelBuilderCaptureStatus_FaceTooFar:
status = "Capture Status : Warning Face Too Far from Camera";
break;
case FaceModelBuilderCaptureStatus::FaceModelBuilderCaptureStatus_FaceTooNear:
status = "Capture Status : WWarning Face Too Near to Camera";
break;
case FaceModelBuilderCaptureStatus::FaceModelBuilderCaptureStatus_MovingTooFast:
status = "Capture Status : WWarning Moving Too Fast";
break;
default:
status = "";
break;
}
return status;
}
// Draw Vertexes
inline void Kinect::drawVertexes( cv::Mat& image, const std::vector<CameraSpacePoint> vertexes, const int radius, const cv::Vec3b& color, const int thickness )
{
if( image.empty() ){
return;
}
// Draw Vertex Points Converted to Color Coordinate System
Concurrency::parallel_for_each( vertexes.begin(), vertexes.end(), [&]( const CameraSpacePoint vertex ){
ColorSpacePoint point;
ERROR_CHECK( coordinateMapper->MapCameraPointToColorSpace( vertex, &point ) );
const int x = static_cast<int>( point.X + 0.5f );
const int y = static_cast<int>( point.Y + 0.5f );
if( ( 0 <= x ) && ( x < image.cols ) && ( 0 <= y ) && ( y < image.rows ) ){
cv::circle( image, cv::Point( x, y ), radius, color, thickness, cv::LINE_AA );
}
} );
}
// Show Data
void Kinect::show()
{
// Show HDFace
showHDFace();
}
// Show HDFace
inline void Kinect::showHDFace()
{
if( colorMat.empty() ){
return;
}
// Resize Image
cv::Mat resizeMat;
const double scale = 0.5;
cv::resize( colorMat, resizeMat, cv::Size(), scale, scale );
// Show Image
cv::imshow( "HDFace", resizeMat );
}

View File

@ -0,0 +1,122 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <Kinect.Face.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <array>
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <array>
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Coordinate Mapper
ComPtr<ICoordinateMapper> coordinateMapper;
// Reader
ComPtr<IColorFrameReader> colorFrameReader;
ComPtr<IBodyFrameReader> bodyFrameReader;
ComPtr<IHighDefinitionFaceFrameReader> hdFaceFrameReader;
// Color Buffer
std::vector<BYTE> colorBuffer;
int colorWidth;
int colorHeight;
unsigned int colorBytesPerPixel;
cv::Mat colorMat;
// HDFace Buffer
ComPtr<IFaceModelBuilder> faceModelBuilder;
ComPtr<IFaceAlignment> faceAlignment;
ComPtr<IFaceModel> faceModel;
std::array<float, FaceShapeDeformations::FaceShapeDeformations_Count> faceShapeUnits = { 0.0f };
UINT32 vertexCount;
UINT64 trackingId;
int trackingCount = 0;
bool produced = false;
std::array<cv::Vec3b, BODY_COUNT> colors;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Color
inline void initializeColor();
// Initialize Body
inline void initializeBody();
// Initialize HDFace
inline void initializeHDFace();
// Finalize
void finalize();
// Update Data
void update();
// Update Color
inline void updateColor();
// Update Body
inline void updateBody();
// Find Closest Body
inline void findClosestBody( const std::array<ComPtr<IBody>, BODY_COUNT>& bodies );
// Update HDFace
inline void updateHDFace();
// Draw Data
void draw();
// Draw Color
inline void drawColor();
// Draw HDFace
inline void drawHDFace();
// Draw Face Model Builder Status
inline void drawFaceModelBuilderStatus( cv::Mat& image, const cv::Point& point, const double scale, const cv::Vec3b& color, const int thickness = 2 );
// Convert Collection Status to String
inline std::string status2string( const FaceModelBuilderCollectionStatus collection );
// Convert Capture Status to String
inline std::string status2string( const FaceModelBuilderCaptureStatus capture );
// Draw Vertexes
inline void Kinect::drawVertexes( cv::Mat& image, const std::vector<CameraSpacePoint> vertexes, const int radius, const cv::Vec3b& color, const int thickness = -1 );
// Show Data
void show();
// Show HDFace
inline void showHDFace();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Infrared app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Infrared" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Infrared ${KinectSDK2_LIBRARIES} )
target_link_libraries( Infrared ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

View File

@ -0,0 +1,161 @@
#include "app.h"
#include "util.h"
#include <thread>
#include <chrono>
// Constructor
Kinect::Kinect()
{
// Initialize
initialize();
}
// Destructor
Kinect::~Kinect()
{
// Finalize
finalize();
}
// Processing
void Kinect::run()
{
// Main Loop
while( true ){
// Update Data
update();
// Draw Data
draw();
// Show Data
show();
// Key Check
const int key = cv::waitKey( 10 );
if( key == VK_ESCAPE ){
break;
}
}
}
// Initialize
void Kinect::initialize()
{
cv::setUseOptimized( true );
// Initialize Sensor
initializeSensor();
// Initialize Infrared
initializeInfrared();
// Wait a Few Seconds until begins to Retrieve Data from Sensor ( about 2000-[ms] )
std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
}
// Initialize Sensor
inline void Kinect::initializeSensor()
{
// Open Sensor
ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
ERROR_CHECK( kinect->Open() );
// Check Open
BOOLEAN isOpen = FALSE;
ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
if( !isOpen ){
throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
}
}
// Initialize Infrared
inline void Kinect::initializeInfrared()
{
// Open Infrared Reader
ComPtr<IInfraredFrameSource> infraredFrameSource;
ERROR_CHECK( kinect->get_InfraredFrameSource( &infraredFrameSource ) );
ERROR_CHECK( infraredFrameSource->OpenReader( &infraredFrameReader ) );
// Retrieve Infrared Description
ComPtr<IFrameDescription> infraredFrameDescription;
ERROR_CHECK( infraredFrameSource->get_FrameDescription( &infraredFrameDescription ) );
ERROR_CHECK( infraredFrameDescription->get_Width( &infraredWidth ) ); // 512
ERROR_CHECK( infraredFrameDescription->get_Height( &infraredHeight ) ); // 424
ERROR_CHECK( infraredFrameDescription->get_BytesPerPixel( &infraredBytesPerPixel ) ); // 2
// Allocation Depth Buffer
infraredBuffer.resize( infraredWidth * infraredHeight );
}
// Finalize
void Kinect::finalize()
{
cv::destroyAllWindows();
// Close Sensor
if( kinect != nullptr ){
kinect->Close();
}
}
// Update Data
void Kinect::update()
{
// Update Infrared
updateInfrared();
}
// Update Infrared
inline void Kinect::updateInfrared()
{
// Retrieve Infrared Frame
ComPtr<IInfraredFrame> infraredFrame;
const HRESULT ret = infraredFrameReader->AcquireLatestFrame( &infraredFrame );
if( FAILED( ret ) ){
return;
}
// Retrieve Infrared Data
ERROR_CHECK( infraredFrame->CopyFrameDataToArray( static_cast<UINT>( infraredBuffer.size() ), &infraredBuffer[0] ) );
}
// Draw Data
void Kinect::draw()
{
// Draw Infrared
drawInfrared();
}
// Draw Infrared
inline void Kinect::drawInfrared()
{
// Create cv::Mat from Infrared Buffer
infraredMat = cv::Mat( infraredHeight, infraredWidth, CV_16UC1, &infraredBuffer[0] );
}
// Show Data
void Kinect::show()
{
// Show Infrared
showInfrared();
}
// Show Infrared
inline void Kinect::showInfrared()
{
if( infraredMat.empty() ){
return;
}
// Scaling ( 0b1111'1111'0000'0000 -> 0b1111'1111 )
cv::Mat scaleMat( infraredHeight, infraredWidth, CV_8UC1 );
scaleMat.forEach<uchar>([&]( uchar &p, const int* position ){
p = infraredMat.at<ushort>( position[0], position[1] ) >> 8;
});
// Show Image
cv::imshow( "Infrared", scaleMat );
}

View File

@ -0,0 +1,71 @@
#ifndef __APP__
#define __APP__
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <vector>
#include <wrl/client.h>
using namespace Microsoft::WRL;
class Kinect
{
private:
// Sensor
ComPtr<IKinectSensor> kinect;
// Reader
ComPtr<IInfraredFrameReader> infraredFrameReader;
// Infrared Buffer
std::vector<UINT16> infraredBuffer;
int infraredWidth;
int infraredHeight;
unsigned int infraredBytesPerPixel;
cv::Mat infraredMat;
public:
// Constructor
Kinect();
// Destructor
~Kinect();
// Processing
void run();
private:
// Initialize
void initialize();
// Initialize Sensor
inline void initializeSensor();
// Initialize Infrared
inline void initializeInfrared();
// Finalize
void finalize();
// Update Data
void update();
// Update Infrared
inline void updateInfrared();
// Draw Data
void draw();
// Draw Infrared
inline void drawInfrared();
// Show Data
void show();
// Show Infrared
inline void showInfrared();
};
#endif // __APP__

View File

@ -0,0 +1,16 @@
#include <iostream>
#include <sstream>
#include "app.h"
int main( int argc, char* argv[] )
{
try{
Kinect kinect;
kinect.run();
} catch( std::exception& ex ){
std::cout << ex.what() << std::endl;
}
return 0;
}

View File

@ -0,0 +1,37 @@
#ifndef __UTIL__
#define __UTIL__
#include <sstream>
#include <stdexcept>
// Error Check Macro
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
// Safe Release
template<class T>
inline void SafeRelease( T*& rel )
{
if( rel != NULL ){
rel->Release();
rel = NULL;
}
}
// C++ Style Line Types For OpenCV 2.x
#if ( CV_MAJOR_VERSION < 3 )
namespace cv{
enum LineTypes{
FILLED = -1,
LINE_4 = 4,
LINE_8 = 8,
LINE_AA = 16
};
}
#endif
#endif // __UTIL__

View File

@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Sample )
add_executable( Inpaint app.h app.cpp main.cpp util.h )
# Set StartUp Project
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Inpaint" )
# Find Package
set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} )
find_package( KinectSDK2 REQUIRED )
set( OpenCV_DIR "C:/Program Files/opencv/build" )
option( OpenCV_STATIC OFF )
find_package( OpenCV REQUIRED )
# Set Static Link Runtime Library
if( OpenCV_STATIC )
foreach( flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO )
if( ${flag_var} MATCHES "/MD" )
string( REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}" )
endif()
endforeach()
endif()
if( KinectSDK2_FOUND AND OpenCV_FOUND )
# Additional Include Directories
include_directories( ${KinectSDK2_INCLUDE_DIRS} )
include_directories( ${OpenCV_INCLUDE_DIRS} )
# Additional Library Directories
link_directories( ${KinectSDK2_LIBRARY_DIRS} )
link_directories( ${OpenCV_LIB_DIR} )
# Additional Dependencies
target_link_libraries( Inpaint ${KinectSDK2_LIBRARIES} )
target_link_libraries( Inpaint ${OpenCV_LIBS} )
endif()

View File

@ -0,0 +1,182 @@
#.rst:
# FindKinectSDK2
# --------------
#
# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands
#
# Use this module by invoking find_package with the form::
#
# find_package( KinectSDK2 [REQUIRED] )
#
# Results for users are reported in following variables::
#
# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE".
# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc)
# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64)
# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.))
# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.)
#
# This module reads hints about search locations from following environment variables::
#
# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.)
#
# CMake entries::
#
# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR})
# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck)
# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck)
# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck)
#
# Example to find Kinect SDK v2::
#
# cmake_minimum_required( VERSION 2.8 )
#
# project( project )
# add_executable( project main.cpp )
#
# # Find package using this module.
# find_package( KinectSDK2 REQUIRED )
#
# if(KinectSDK2_FOUND)
# # [C/C++]>[General]>[Additional Include Directories]
# include_directories( ${KinectSDK2_INCLUDE_DIRS} )
#
# # [Linker]>[General]>[Additional Library Directories]
# link_directories( ${KinectSDK2_LIBRARY_DIRS} )
#
# # [Linker]>[Input]>[Additional Dependencies]
# target_link_libraries( project ${KinectSDK2_LIBRARIES} )
#
# # [Build Events]>[Post-Build Event]>[Command Line]
# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} )
# endif()
#
# =============================================================================
#
# Copyright (c) 2016 Tsukasa SUGIURA
# Distributed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# =============================================================================
##### Utility #####
# Check Directory Macro
macro(CHECK_DIR _DIR)
if(NOT EXISTS "${${_DIR}}")
message(WARNING "Directory \"${${_DIR}}\" not found.")
set(KinectSDK2_FOUND FALSE)
unset(_DIR)
endif()
endmacro()
# Check Files Macro
macro(CHECK_FILES _FILES _DIR)
set(_MISSING_FILES)
foreach(_FILE ${${_FILES}})
if(NOT EXISTS "${_FILE}")
get_filename_component(_FILE ${_FILE} NAME)
set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ")
endif()
endforeach()
if(_MISSING_FILES)
message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}")
set(KinectSDK2_FOUND FALSE)
unset(_FILES)
endif()
endmacro()
# Target Platform
set(TARGET_PLATFORM)
if(NOT CMAKE_CL_64)
set(TARGET_PLATFORM x86)
else()
set(TARGET_PLATFORM x64)
endif()
##### Find Kinect SDK v2 #####
# Found
set(KinectSDK2_FOUND TRUE)
if(MSVC_VERSION LESS 1700)
message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.")
set(KinectSDK2_FOUND FALSE)
endif()
# Options
option(KinectSDK2_FACE "Face and HDFace features" FALSE)
option(KinectSDK2_FUSION "Fusion features" FALSE)
option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE)
# Root Directoty
set(KinectSDK2_DIR)
if(KinectSDK2_FOUND)
set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE)
check_dir(KinectSDK2_DIR)
endif()
# Include Directories
set(KinectSDK2_INCLUDE_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc)
check_dir(KinectSDK2_INCLUDE_DIRS)
endif()
# Library Directories
set(KinectSDK2_LIBRARY_DIRS)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM})
check_dir(KinectSDK2_LIBRARY_DIRS)
endif()
# Dependencies
set(KinectSDK2_LIBRARIES)
if(KinectSDK2_FOUND)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib)
if(KinectSDK2_FACE)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib)
endif()
check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS)
endif()
# Custom Commands
set(KinectSDK2_COMMANDS)
if(KinectSDK2_FOUND)
if(KinectSDK2_FACE)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_FUSION)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
if(KinectSDK2_VGB)
set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM})
check_dir(KinectSDK2_REDIST_DIR)
list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL)
endif()
# Empty Commands
if(NOT KinectSDK2_COMMANDS)
set(KinectSDK2_COMMANDS COMMAND)
endif()
endif()
message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}")

Some files were not shown because too many files have changed in this diff Show More