some changes
This commit is contained in:
parent
d91cc4a2a1
commit
8d2141fa8a
|
@ -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]
|
|
@ -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".
|
|
@ -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.
|
|
@ -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>*1 This sample program need Visual Studio Community (or upper version), because depends on ATL.</sup>
|
||||||
|
<sup>*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>*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 © 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>
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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] );
|
||||||
|
}
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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
|
@ -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;
|
||||||
|
}
|
|
@ -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 ) );
|
||||||
|
*/
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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.
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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}")
|
|
@ -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 );
|
||||||
|
}
|
|
@ -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__
|
|
@ -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;
|
||||||
|
}
|
|
@ -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__
|
|
@ -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()
|
|
@ -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
Loading…
Reference in New Issue