diff --git a/Kinect2Sample-master/.github/FUNDING.yml b/Kinect2Sample-master/.github/FUNDING.yml new file mode 100644 index 0000000..fe6c3b5 --- /dev/null +++ b/Kinect2Sample-master/.github/FUNDING.yml @@ -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] diff --git a/Kinect2Sample-master/HOWTOBUILD.md b/Kinect2Sample-master/HOWTOBUILD.md new file mode 100644 index 0000000..2833a60 --- /dev/null +++ b/Kinect2Sample-master/HOWTOBUILD.md @@ -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. C:\Program Files\opencv ) + +* 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. C:/Kinect2Sample/sample ) + If you want to build any one sample, please fill path of any one directory. ( e.g. C:/Kinect2Sample/sample/Color ) + + * **Where to build the binaries** + This area is directory Visual Studio project files will be generated. + By convention, Fill the path that added the \/build to above path. ( e.g. C:/Kinect2Sample/sample/build ) + +3. Click Configure Button + You will be prompted for compiler and target platform. + Please specify compiler and target platform to use. ( e.g. Visual Studio 14 2015 Win64 ) + 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. C:/Program Files/Microsoft SDKs/Kinect/v2.0_1409 ) + * **OPENCV\_DIR** ... The directory path that to search CMake configuration file for OpenCV. ( e.g. C:/Program Files/opencv/build ) + +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. C:\Program Filesopencv\build\x64\vc14\bin ) + 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. ..\build\Sample.sln ) + +2. Set Solution Configurations + Select Release from the Solution Configuration drop-down list, which is on the Standard toolbar. ( e.g. Release ) + 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". diff --git a/Kinect2Sample-master/LICENSE b/Kinect2Sample-master/LICENSE new file mode 100644 index 0000000..484e9b4 --- /dev/null +++ b/Kinect2Sample-master/LICENSE @@ -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. diff --git a/Kinect2Sample-master/README.md b/Kinect2Sample-master/README.md new file mode 100644 index 0000000..00ddfc3 --- /dev/null +++ b/Kinect2Sample-master/README.md @@ -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 *1 +* Kinect for Windows SDK v2.0 +* Kinect for Windows SDK v2.0 Language Packs (en-US) +* Speech Platform SDK 11 +* OpenCV 3.1.0 *2 +* CMake 3.6.1 *3 + +*1 This sample program need Visual Studio Community (or upper version), because depends on ATL. +*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. +*3 You need generate project of this sample program using CMake. Please read [this document](HOWTOBUILD.md) about how to generate project using CMake. + +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 + * + * + * + +Reference +------------ +* KINECT for Windows SDK programming - Kinect for Windows v2 sensor supported version | Shuwa System Co.,Ltd. + + +* Kinect for Windows SDK 2.0 | MSDN Library + \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/CMakeLists.txt b/Kinect2Sample-master/sample/AudioBeam/CMakeLists.txt new file mode 100644 index 0000000..5cb94b7 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/AudioBeam/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/app.cpp b/Kinect2Sample-master/sample/AudioBeam/app.cpp new file mode 100644 index 0000000..8eb51b8 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/app.cpp @@ -0,0 +1,179 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include +#include + +#include + +// 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 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 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( beamCount ), [&]( int i ){ + // Retrieve Audio Beam Frame + ComPtr 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( subFrameCount ), [&]( int j ){ + // Retrieve Audio Beam SubFrame + ComPtr 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( 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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/app.h b/Kinect2Sample-master/sample/AudioBeam/app.h new file mode 100644 index 0000000..4b99b85 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/app.h @@ -0,0 +1,70 @@ +#ifndef __APP__ +#define __APP__ + +#define _USE_MATH_DEFINES +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/main.cpp b/Kinect2Sample-master/sample/AudioBeam/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBeam/util.h b/Kinect2Sample-master/sample/AudioBeam/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBeam/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/CMakeLists.txt b/Kinect2Sample-master/sample/AudioBody/CMakeLists.txt new file mode 100644 index 0000000..6be74c4 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/AudioBody/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/app.cpp b/Kinect2Sample-master/sample/AudioBody/app.cpp new file mode 100644 index 0000000..59c1439 --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/app.cpp @@ -0,0 +1,308 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include + +#include + +// 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 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 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 bodyIndexFrameSource; + ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) ); + ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) ); + + // Retrieve BodyIndex Description + ComPtr 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::max() - 1; + + // Retrieve Audio Beam Frame List + ComPtr 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 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 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 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::max() - 1 ){ + return; + } + + // Retrieve Body Frame + ComPtr 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( 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 bodyIndexFrame; + const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve BodyIndex Data + ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast( 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 &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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/app.h b/Kinect2Sample-master/sample/AudioBody/app.h new file mode 100644 index 0000000..a73feee --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/app.h @@ -0,0 +1,96 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr bodyFrameReader; + ComPtr bodyIndexFrameReader; + ComPtr audioBeamFrameReader; + + // Body Buffer + std::array bodies = { nullptr }; + + // BodyIndex Buffer + std::vector bodyIndexBuffer; + int bodyIndexWidth; + int bodyIndexHeight; + cv::Mat bodyIndexMat; + std::array 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/main.cpp b/Kinect2Sample-master/sample/AudioBody/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/AudioBody/util.h b/Kinect2Sample-master/sample/AudioBody/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/AudioBody/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/CMakeLists.txt b/Kinect2Sample-master/sample/Body/CMakeLists.txt new file mode 100644 index 0000000..d7d6afc --- /dev/null +++ b/Kinect2Sample-master/sample/Body/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Body/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Body/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/app.cpp b/Kinect2Sample-master/sample/Body/app.cpp new file mode 100644 index 0000000..6f9a4ed --- /dev/null +++ b/Kinect2Sample-master/sample/Body/app.cpp @@ -0,0 +1,335 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr 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( 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 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 joints; + ERROR_CHECK( body->GetJoints( static_cast( 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 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( colorSpacePoint.X + 0.5f ); + const int y = static_cast( 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( 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/app.h b/Kinect2Sample-master/sample/Body/app.h new file mode 100644 index 0000000..f659522 --- /dev/null +++ b/Kinect2Sample-master/sample/Body/app.h @@ -0,0 +1,95 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Body Buffer + std::array bodies = { nullptr }; + std::array 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/main.cpp b/Kinect2Sample-master/sample/Body/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Body/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Body/util.h b/Kinect2Sample-master/sample/Body/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Body/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/CMakeLists.txt b/Kinect2Sample-master/sample/BodyIndex/CMakeLists.txt new file mode 100644 index 0000000..89ffd22 --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/BodyIndex/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/app.cpp b/Kinect2Sample-master/sample/BodyIndex/app.cpp new file mode 100644 index 0000000..41b81cd --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/app.cpp @@ -0,0 +1,165 @@ +#include "app.h" +#include "util.h" + +#include +#include + +// 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 bodyIndexFrameSource; + ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) ); + ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) ); + + // Retrieve BodyIndex Description + ComPtr 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 bodyIndexFrame; + const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve BodyIndex Data + ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast( 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 &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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/app.h b/Kinect2Sample-master/sample/BodyIndex/app.h new file mode 100644 index 0000000..5a5bf2d --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/app.h @@ -0,0 +1,74 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr bodyIndexFrameReader; + + // BodyIndex Buffer + std::vector bodyIndexBuffer; + int bodyIndexWidth; + int bodyIndexHeight; + unsigned int bodyIndexBytesPerPixel; + cv::Mat bodyIndexMat; + std::array 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/main.cpp b/Kinect2Sample-master/sample/BodyIndex/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/BodyIndex/util.h b/Kinect2Sample-master/sample/BodyIndex/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/BodyIndex/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CMakeLists.txt b/Kinect2Sample-master/sample/CMakeLists.txt new file mode 100644 index 0000000..20bd161 --- /dev/null +++ b/Kinect2Sample-master/sample/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/CMakeLists.txt b/Kinect2Sample-master/sample/ChromaKey/CMakeLists.txt new file mode 100644 index 0000000..fbbe3a0 --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/ChromaKey/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/app.cpp b/Kinect2Sample-master/sample/ChromaKey/app.cpp new file mode 100644 index 0000000..fadd399 --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/app.cpp @@ -0,0 +1,351 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 bodyIndexFrameSource; + ERROR_CHECK( kinect->get_BodyIndexFrameSource( &bodyIndexFrameSource ) ); + ERROR_CHECK( bodyIndexFrameSource->OpenReader( &bodyIndexFrameReader ) ); + + // Retrieve BodyIndex Description + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth() +{ + // Retrieve Depth Frame + ComPtr depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( depthBuffer.size() ), &depthBuffer[0] ) ); +} + +// Update BodyIndex +inline void Kinect::updateBodyIndex() +{ + // Retrieve BodyIndex Frame + ComPtr bodyIndexFrame; + const HRESULT ret = bodyIndexFrameReader->AcquireLatestFrame( &bodyIndexFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve BodyIndex Data + ERROR_CHECK( bodyIndexFrame->CopyFrameDataToArray( static_cast( 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 colorSpacePoints( depthWidth * depthHeight ); + ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) ); + + // Mapping Color to Depth Resolution + std::vector 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( colorSpacePoints[depthIndex].X + 0.5f ); + const int colorY = static_cast( 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 bodyIndexSpacePoints( colorWidth * colorHeight ); + ERROR_CHECK( coordinateMapper->MapColorFrameToDepthSpace( depthBuffer.size(), &depthBuffer[0], bodyIndexSpacePoints.size(), &bodyIndexSpacePoints[0] ) ); + + // Mapping BodyIndex to Color Resolution + std::vector 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( bodyIndexSpacePoints[colorIndex].X + 0.5f ); + const int bodyIndexY = static_cast( 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 &p, const int* position ){ + uchar bodyIndex = bodyIndexMat.at( position[0], position[1] ); + if( bodyIndex != 0xff ){ + p = colorMat.at( 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 +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/app.h b/Kinect2Sample-master/sample/ChromaKey/app.h new file mode 100644 index 0000000..1835bd9 --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/app.h @@ -0,0 +1,110 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr depthFrameReader; + ComPtr bodyIndexFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Depth Buffer + std::vector depthBuffer; + int depthWidth; + int depthHeight; + unsigned int depthBytesPerPixel; + + // BodyIndex Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/main.cpp b/Kinect2Sample-master/sample/ChromaKey/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/ChromaKey/util.h b/Kinect2Sample-master/sample/ChromaKey/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/ChromaKey/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/CMakeLists.txt b/Kinect2Sample-master/sample/Color/CMakeLists.txt new file mode 100644 index 0000000..6230a34 --- /dev/null +++ b/Kinect2Sample-master/sample/Color/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Color/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Color/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/app.cpp b/Kinect2Sample-master/sample/Color/app.cpp new file mode 100644 index 0000000..6ecc9a8 --- /dev/null +++ b/Kinect2Sample-master/sample/Color/app.cpp @@ -0,0 +1,160 @@ +#include "app.h" +#include "util.h" + +#include +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/app.h b/Kinect2Sample-master/sample/Color/app.h new file mode 100644 index 0000000..4843a5d --- /dev/null +++ b/Kinect2Sample-master/sample/Color/app.h @@ -0,0 +1,71 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr colorFrameReader; + + // Color Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/main.cpp b/Kinect2Sample-master/sample/Color/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Color/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Color/util.h b/Kinect2Sample-master/sample/Color/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Color/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/CMakeLists.txt b/Kinect2Sample-master/sample/CoordinateMapper/CMakeLists.txt new file mode 100644 index 0000000..fecf614 --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/CoordinateMapper/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/app.cpp b/Kinect2Sample-master/sample/CoordinateMapper/app.cpp new file mode 100644 index 0000000..554730b --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/app.cpp @@ -0,0 +1,307 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth() +{ + // Retrieve Depth Frame + ComPtr depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( 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 colorSpacePoints( depthWidth * depthHeight ); + ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) ); + + // Mapping Color to Depth Resolution + std::vector 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( colorSpacePoints[depthIndex].X + 0.5f ); + const int colorY = static_cast( 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 depthSpacePoints( colorWidth * colorHeight ); + ERROR_CHECK( coordinateMapper->MapColorFrameToDepthSpace( depthBuffer.size(), &depthBuffer[0], depthSpacePoints.size(), &depthSpacePoints[0] ) ); + + // Mapping Depth to Color Resolution + std::vector 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( depthSpacePoints[colorIndex].X + 0.5f ); + const int depthY = static_cast( 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 +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/app.h b/Kinect2Sample-master/sample/CoordinateMapper/app.h new file mode 100644 index 0000000..d598f68 --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/app.h @@ -0,0 +1,94 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr depthFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Depth Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/main.cpp b/Kinect2Sample-master/sample/CoordinateMapper/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/CoordinateMapper/util.h b/Kinect2Sample-master/sample/CoordinateMapper/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/CoordinateMapper/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/CMakeLists.txt b/Kinect2Sample-master/sample/Depth/CMakeLists.txt new file mode 100644 index 0000000..1b42d61 --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Depth/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/app.cpp b/Kinect2Sample-master/sample/Depth/app.cpp new file mode 100644 index 0000000..4eb9472 --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/app.cpp @@ -0,0 +1,167 @@ +#include "app.h" +#include "util.h" + +#include +#include + +// 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/app.h b/Kinect2Sample-master/sample/Depth/app.h new file mode 100644 index 0000000..0afc2f0 --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/app.h @@ -0,0 +1,71 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr depthFrameReader; + + // Depth Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/main.cpp b/Kinect2Sample-master/sample/Depth/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Depth/util.h b/Kinect2Sample-master/sample/Depth/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Depth/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/CMakeLists.txt b/Kinect2Sample-master/sample/Face/CMakeLists.txt new file mode 100644 index 0000000..ee899c6 --- /dev/null +++ b/Kinect2Sample-master/sample/Face/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Face/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Face/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/app.cpp b/Kinect2Sample-master/sample/Face/app.cpp new file mode 100644 index 0000000..334314b --- /dev/null +++ b/Kinect2Sample-master/sample/Face/app.cpp @@ -0,0 +1,440 @@ +#include "app.h" +#include "util.h" + +#include +#include +#define _USE_MATH_DEFINES +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr 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( bodies.size() ), &bodies[0] ) ); + Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){ + const ComPtr 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 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 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 result = results[count]; + if( result == nullptr ){ + return; + } + + // Retrieve Face Points + std::array 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 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& 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( point.X + 0.5f ); + const int y = static_cast( point.Y + 0.5f ); + cv::circle( image, cv::Point( x, y ), radius, static_cast( 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( std::atan2( 2 * ( y * z + w * x ), w * w - x * x - y * y + z * z ) / M_PI * 180.0f ); + *yaw = static_cast( std::asin( 2 * ( w * y - x * z ) ) / M_PI * 180.0f ); + *roll = static_cast( 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& 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/app.h b/Kinect2Sample-master/sample/Face/app.h new file mode 100644 index 0000000..43b4e43 --- /dev/null +++ b/Kinect2Sample-master/sample/Face/app.h @@ -0,0 +1,121 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + std::array, BODY_COUNT> faceFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Body Buffer + std::array bodies = { nullptr }; + + // Face Buffer + std::array, BODY_COUNT> results; + std::array labels; + std::array 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& 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& 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/main.cpp b/Kinect2Sample-master/sample/Face/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Face/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Face/util.h b/Kinect2Sample-master/sample/Face/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Face/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/CMakeLists.txt b/Kinect2Sample-master/sample/FaceClip/CMakeLists.txt new file mode 100644 index 0000000..386d74e --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/FaceClip/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/app.cpp b/Kinect2Sample-master/sample/FaceClip/app.cpp new file mode 100644 index 0000000..929a4b4 --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/app.cpp @@ -0,0 +1,312 @@ +#include "app.h" +#include "util.h" + +#include +#include +#define _USE_MATH_DEFINES +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr 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( bodies.size() ), &bodies[0] ) ); + Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){ + const ComPtr 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 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 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 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] ); + } +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/app.h b/Kinect2Sample-master/sample/FaceClip/app.h new file mode 100644 index 0000000..1a9c9ce --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/app.h @@ -0,0 +1,105 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + std::array, BODY_COUNT> faceFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Body Buffer + std::array bodies = { nullptr }; + + // Face Buffer + std::array, BODY_COUNT> results; + std::array 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/main.cpp b/Kinect2Sample-master/sample/FaceClip/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceClip/util.h b/Kinect2Sample-master/sample/FaceClip/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/FaceClip/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/CMakeLists.txt b/Kinect2Sample-master/sample/FaceRecognition/CMakeLists.txt new file mode 100644 index 0000000..0c278b4 --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/FaceRecognition/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/app.cpp b/Kinect2Sample-master/sample/FaceRecognition/app.cpp new file mode 100644 index 0000000..73e0f8e --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/app.cpp @@ -0,0 +1,410 @@ +#include "app.h" +#include "util.h" + +#include +#include +#define _USE_MATH_DEFINES +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr 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( bodies.size() ), &bodies[0] ) ); + Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){ + const ComPtr 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 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 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 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 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/app.h b/Kinect2Sample-master/sample/FaceRecognition/app.h new file mode 100644 index 0000000..5d44856 --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/app.h @@ -0,0 +1,122 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + std::array, BODY_COUNT> faceFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Body Buffer + std::array bodies = { nullptr }; + + // Face Buffer + std::array, BODY_COUNT> results; + + // Face Recognition + cv::Ptr 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 labels; + std::array 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/main.cpp b/Kinect2Sample-master/sample/FaceRecognition/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/FaceRecognition/util.h b/Kinect2Sample-master/sample/FaceRecognition/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/FaceRecognition/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/CMakeLists.txt b/Kinect2Sample-master/sample/Fusion/CMakeLists.txt new file mode 100644 index 0000000..7d5dcd2 --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Fusion/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/KinectFusionHelper.cpp b/Kinect2Sample-master/sample/Fusion/KinectFusionHelper.cpp new file mode 100644 index 0000000..3dedb35 --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/KinectFusionHelper.cpp @@ -0,0 +1,1524 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +// System includes +//#include "stdafx.h" +#include + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable:6255) +#pragma warning(disable:6263) +#pragma warning(disable:4995) +#include "ppl.h" +#pragma warning(pop) + +// Project includes +#include "KinectFusionHelper.h" + +/// +/// Set Identity in a Matrix4 +/// +/// The matrix to set to identity +void SetIdentityMatrix(Matrix4 &mat) +{ + mat.M11 = 1; mat.M12 = 0; mat.M13 = 0; mat.M14 = 0; + mat.M21 = 0; mat.M22 = 1; mat.M23 = 0; mat.M24 = 0; + mat.M31 = 0; mat.M32 = 0; mat.M33 = 1; mat.M34 = 0; + mat.M41 = 0; mat.M42 = 0; mat.M43 = 0; mat.M44 = 1; +} + +/// +/// Extract translation Vector3 from the Matrix4 4x4 transformation in M41,M42,M43 +/// +/// The transform matrix. +/// Array of 3 floating point values for translation. +void ExtractVector3Translation(const Matrix4 &transform, _Out_cap_c_(3) float *translation) +{ + translation[0] = transform.M41; + translation[1] = transform.M42; + translation[2] = transform.M43; +} + +/// +/// Extract translation Vector3 from the 4x4 Matrix in M41,M42,M43 +/// +/// The transform matrix. +/// Returns a Vector3 containing the translation. +Vector3 ExtractVector3Translation(const Matrix4 &transform) +{ + Vector3 translation; + translation.x = transform.M41; + translation.y = transform.M42; + translation.z = transform.M43; + return translation; +} + +/// +/// Extract 3x3 rotation from the 4x4 Matrix and return in new Matrix4 +/// +/// The transform matrix. +/// Returns a Matrix4 containing the rotation. +Matrix4 Extract3x3Rotation(const Matrix4 &transform) +{ + Matrix4 rotation; + + rotation.M11 = transform.M11; + rotation.M12 = transform.M12; + rotation.M13 = transform.M13; + rotation.M14 = 0; + + rotation.M21 = transform.M21; + rotation.M22 = transform.M22; + rotation.M23 = transform.M23; + rotation.M24 = 0; + + rotation.M31 = transform.M31; + rotation.M32 = transform.M32; + rotation.M33 = transform.M33; + rotation.M34 = 0; + + rotation.M41 = 0; + rotation.M42 = 0; + rotation.M43 = 0; + rotation.M44 = 1; + + return rotation; +} + +/// +/// Extract 3x3 rotation matrix from the Matrix4 4x4 transformation: +/// Then convert to Euler angles. +/// +/// The transform matrix. +/// Array of 3 floating point values for euler angles. +void ExtractRot2Euler(const Matrix4 &transform, _Out_cap_c_(3) float *rotation) +{ + float phi = atan2f(transform.M23, transform.M33); + float theta = asinf(-transform.M13); + float psi = atan2f(transform.M12, transform.M11); + + rotation[0] = phi; // This is rotation about x,y,z, or pitch, yaw, roll respectively + rotation[1] = theta; + rotation[2] = psi; +} + +/// +/// 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. +/// +/// The transform matrix from the previous frame. +/// The transform matrix from the current frame. +/// The maximum translation in meters we expect per x,y,z component between frames under normal motion. +/// The maximum rotation in degrees we expect about the x,y,z axes between frames under normal motion. +/// true if camera transformation is greater than the threshold, otherwise false +bool CameraTransformFailed(const Matrix4 &T_initial, const Matrix4 &T_final, float maxTrans, float maxRotDegrees) +{ + // Check if the transform is too far out to be reasonable + float deltaTrans = maxTrans; + float angDeg = maxRotDegrees; + float deltaRot = (angDeg * (float)M_PI) / 180.0f; + + // Calculate the deltas + float eulerInitial[3]; + float eulerFinal[3]; + + ExtractRot2Euler(T_initial, eulerInitial); + ExtractRot2Euler(T_final, eulerFinal); + + float transInitial[3]; + float transFinal[3]; + + ExtractVector3Translation(T_initial, transInitial); + ExtractVector3Translation(T_final, transFinal); + + bool failRot = false; + bool failTrans = false; + + float rDeltas[3]; + float tDeltas[3]; + + static const float pi = static_cast(M_PI); + + for (int i = 0; i < 3; i++) + { + // Handle when one angle is near PI, and the other is near -PI. + if (eulerInitial[i] >= (pi - deltaRot) && eulerFinal[i] < (deltaRot - pi)) + { + eulerInitial[i] -= pi * 2; + } + else if (eulerFinal[i] >= (pi - deltaRot) && eulerInitial[i] < (deltaRot - pi)) + { + eulerFinal[i] -= pi * 2; + } + + rDeltas[i] = eulerInitial[i] - eulerFinal[i]; + tDeltas[i] = transInitial[i] - transFinal[i]; + + if (fabs(rDeltas[i]) > deltaRot) + { + failRot = true; + break; + } + if (fabs(tDeltas[i]) > deltaTrans) + { + failTrans = true; + break; + } + } + + return failRot || failTrans; +} + +/// +/// Invert/Transpose the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The rotation matrix to invert. +void InvertRotation(Matrix4 &rot) +{ + // Invert equivalent to a transpose for 3x3 rotation rotrices when orthogonal + float tmp = rot.M12; + rot.M12 = rot.M21; + rot.M21 = tmp; + + tmp = rot.M13; + rot.M13 = rot.M31; + rot.M31 = tmp; + + tmp = rot.M23; + rot.M23 = rot.M32; + rot.M32 = tmp; +} + +/// +/// Negate the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The rotation matrix to negate. +void NegateRotation(Matrix4 &rot) +{ + rot.M11 = -rot.M11; + rot.M12 = -rot.M12; + rot.M13 = -rot.M13; + + rot.M21 = -rot.M21; + rot.M22 = -rot.M22; + rot.M23 = -rot.M23; + + rot.M31 = -rot.M31; + rot.M32 = -rot.M32; + rot.M33 = -rot.M33; +} + +/// +/// Rotate a vector with the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The Vector3 to rotate. +/// Rotation matrix. +Vector3 RotateVector(const Vector3 &vec, const Matrix4 & rot) +{ + // we only use the rotation component here + Vector3 result; + + result.x = (rot.M11 * vec.x) + (rot.M21 * vec.y) + (rot.M31 * vec.z); + result.y = (rot.M12 * vec.x) + (rot.M22 * vec.y) + (rot.M32 * vec.z); + result.z = (rot.M13 * vec.x) + (rot.M23 * vec.y) + (rot.M33 * vec.z); + + return result; +} +/// +/// Invert Matrix4 Pose either from WorldToCameraTransform (view) matrix to CameraToWorldTransform camera pose matrix (world/SE3) or vice versa +/// +/// The camera pose transform matrix. +/// Returns a Matrix4 containing the inverted camera pose. +Matrix4 InvertMatrix4Pose(const Matrix4 &transform) +{ + // Given the SE3 world transform transform T = [R|t], the inverse view transform matrix is simply: + // T^-1 = [R^T | -R^T . t ] + // This also works the opposite way to get the world transform, given the view transform matrix. + Matrix4 rotation = Extract3x3Rotation(transform); + + Matrix4 invRotation = rotation; + InvertRotation(invRotation); // invert(transpose) 3x3 rotation + + Matrix4 negRotation = invRotation; + NegateRotation(negRotation); // negate 3x3 rotation + + Vector3 translation = ExtractVector3Translation(transform); + Vector3 invTranslation = RotateVector(translation, negRotation); + + // Add the translation back in + invRotation.M41 = invTranslation.x; + invRotation.M42 = invTranslation.y; + invRotation.M43 = invTranslation.z; + + return invRotation; +} + +/// +/// Write Binary .STL file +/// see http://en.wikipedia.org/wiki/STL_(file_format) for STL format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// indicates success or failure +HRESULT WriteBinarySTLMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ) +{ + HRESULT hr = S_OK; + + if (NULL == mesh) + { + return E_INVALIDARG; + } + + unsigned int numVertices = mesh->VertexCount(); + unsigned int numTriangleIndices = mesh->TriangleVertexIndexCount(); + unsigned int numTriangles = numVertices / 3; + + if (0 == numVertices || 0 == numTriangleIndices || 0 != numVertices % 3 || numVertices != numTriangleIndices) + { + return E_INVALIDARG; + } + + const Vector3 *vertices = NULL; + hr = mesh->GetVertices(&vertices); + if (FAILED(hr)) + { + return hr; + } + + const Vector3 *normals = NULL; + hr = mesh->GetNormals(&normals); + if (FAILED(hr)) + { + return hr; + } + + const int *triangleIndices = NULL; + hr = mesh->GetTriangleIndices(&triangleIndices); + if (FAILED(hr)) + { + return hr; + } + + // Open File + std::string filename = std::wstring_convert>().to_bytes(lpOleFileName); + FILE *meshFile = NULL; + errno_t err = fopen_s(&meshFile, filename.c_str(), "wb"); + + // Could not open file for writing - return + if (0 != err || NULL == meshFile) + { + return E_ACCESSDENIED; + } + + // Write the header line + const unsigned char header[80] = {0}; // initialize all values to 0 + fwrite(&header, sizeof(unsigned char), ARRAYSIZE(header), meshFile); + + // Write number of triangles + fwrite(&numTriangles, sizeof(int), 1, meshFile); + + // Sequentially write the normal, 3 vertices of the triangle and attribute, for each triangle + for (unsigned int t=0; t < numTriangles; ++t) + { + Vector3 normal = normals[t*3]; + + if (flipYZ) + { + normal.y = -normal.y; + normal.z = -normal.z; + } + + // Write normal + fwrite(&normal, sizeof(float), 3, meshFile); + + // Write vertices + for (unsigned int v=0; v<3; v++) + { + Vector3 vertex = vertices[(t*3) + v]; + + if (flipYZ) + { + vertex.y = -vertex.y; + vertex.z = -vertex.z; + } + + fwrite(&vertex, sizeof(float), 3, meshFile); + } + + unsigned short attribute = 0; + fwrite(&attribute, sizeof(unsigned short), 1, meshFile); + } + + fflush(meshFile); + fclose(meshFile); + + return hr; +} + +/// +/// Write ASCII Wavefront .OBJ file +/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// indicates success or failure +HRESULT WriteAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ) +{ + HRESULT hr = S_OK; + + if (NULL == mesh) + { + return E_INVALIDARG; + } + + unsigned int numVertices = mesh->VertexCount(); + unsigned int numTriangleIndices = mesh->TriangleVertexIndexCount(); + unsigned int numTriangles = numVertices / 3; + + if (0 == numVertices || 0 == numTriangleIndices || 0 != numVertices % 3 || numVertices != numTriangleIndices) + { + return E_INVALIDARG; + } + + const Vector3 *vertices = NULL; + hr = mesh->GetVertices(&vertices); + if (FAILED(hr)) + { + return hr; + } + + const Vector3 *normals = NULL; + hr = mesh->GetNormals(&normals); + if (FAILED(hr)) + { + return hr; + } + + const int *triangleIndices = NULL; + hr = mesh->GetTriangleIndices(&triangleIndices); + if (FAILED(hr)) + { + return hr; + } + + // Open File + std::string filename = std::wstring_convert>().to_bytes(lpOleFileName); + FILE *meshFile = NULL; + errno_t err = fopen_s(&meshFile, filename.c_str(), "wt"); + + // Could not open file for writing - return + if (0 != err || NULL == meshFile) + { + return E_ACCESSDENIED; + } + + // Write the header line + std::string header = "#\n# OBJ file created by Microsoft Kinect Fusion\n#\n"; + fwrite(header.c_str(), sizeof(char), header.length(), meshFile); + + const unsigned int bufSize = MAX_PATH*3; + char outStr[bufSize]; + int written = 0; + + if (flipYZ) + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "v %f %f %f\nv %f %f %f\nv %f %f %f\n", + vertices[vertexIndex].x, -vertices[vertexIndex].y, -vertices[vertexIndex].z, + vertices[vertexIndex+1].x, -vertices[vertexIndex+1].y, -vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, -vertices[vertexIndex+2].y, -vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Sequentially write the 3 normals of the triangle, for each triangle + for (unsigned int t=0, normalIndex=0; t < numTriangles; ++t, normalIndex += 3) + { + written = sprintf_s(outStr, bufSize, "n %f %f %f\nn %f %f %f\nn %f %f %f\n", + normals[normalIndex].x, -normals[normalIndex].y, -normals[normalIndex].z, + normals[normalIndex+1].x, -normals[normalIndex+1].y, -normals[normalIndex+1].z, + normals[normalIndex+2].x, -normals[normalIndex+2].y, -normals[normalIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + else + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "v %f %f %f\nv %f %f %f\nv %f %f %f\n", + vertices[vertexIndex].x, vertices[vertexIndex].y, vertices[vertexIndex].z, + vertices[vertexIndex+1].x, vertices[vertexIndex+1].y, vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, vertices[vertexIndex+2].y, vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Sequentially write the 3 normals of the triangle, for each triangle + for (unsigned int t=0, normalIndex=0; t < numTriangles; ++t, normalIndex += 3) + { + written = sprintf_s(outStr, bufSize, "n %f %f %f\nn %f %f %f\nn %f %f %f\n", + normals[normalIndex].x, normals[normalIndex].y, normals[normalIndex].z, + normals[normalIndex+1].x, normals[normalIndex+1].y, normals[normalIndex+1].z, + normals[normalIndex+2].x, normals[normalIndex+2].y, normals[normalIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + + // Sequentially write the 3 vertex indices of the triangle face, for each triangle + // Note this is typically 1-indexed in an OBJ file when using absolute referencing! + for (unsigned int t=0, baseIndex=1; t < numTriangles; ++t, baseIndex += 3) // Start at baseIndex=1 for the 1-based indexing. + { + written = sprintf_s(outStr, bufSize, "f %u//%u %u//%u %u//%u\n", + baseIndex, baseIndex, baseIndex+1, baseIndex+1, baseIndex+2, baseIndex+2); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Note: we do not have texcoords to store, if we did, we would put the index of the texcoords between the vertex and normal indices (i.e. between the two slashes //) in the string above + fflush(meshFile); + fclose(meshFile); + + return hr; +} + +/// +/// Write ASCII .PLY file +/// See http://paulbourke.net/dataformats/ply/ for .PLY format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// Set this true to write out the surface color to the file when it has been captured. +/// indicates success or failure +HRESULT WriteAsciiPlyMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ, bool outputColor) +{ + HRESULT hr = S_OK; + + if (NULL == mesh) + { + return E_INVALIDARG; + } + + unsigned int numVertices = mesh->VertexCount(); + unsigned int numTriangleIndices = mesh->TriangleVertexIndexCount(); + unsigned int numTriangles = numVertices / 3; + unsigned int numColors = mesh->ColorCount(); + + if (0 == numVertices || 0 == numTriangleIndices || 0 != numVertices % 3 + || numVertices != numTriangleIndices || (outputColor && numVertices != numColors)) + { + return E_INVALIDARG; + } + + const Vector3 *vertices = NULL; + hr = mesh->GetVertices(&vertices); + if (FAILED(hr)) + { + return hr; + } + + const int *triangleIndices = NULL; + hr = mesh->GetTriangleIndices(&triangleIndices); + if (FAILED(hr)) + { + return hr; + } + + const int *colors = NULL; + if (outputColor) + { + hr = mesh->GetColors(&colors); + if (FAILED(hr)) + { + return hr; + } + } + + // Open File + std::string filename = std::wstring_convert>().to_bytes(lpOleFileName); + FILE *meshFile = NULL; + errno_t err = fopen_s(&meshFile, filename.c_str(), "wt"); + + // Could not open file for writing - return + if (0 != err || NULL == meshFile) + { + return E_ACCESSDENIED; + } + + // Write the header line + std::string header = "ply\nformat ascii 1.0\ncomment file created by Microsoft Kinect Fusion\n"; + fwrite(header.c_str(), sizeof(char), header.length(), meshFile); + + const unsigned int bufSize = MAX_PATH*3; + char outStr[bufSize]; + int written = 0; + + if (outputColor) + { + // Elements are: x,y,z, r,g,b + written = sprintf_s(outStr, bufSize, "element vertex %u\nproperty float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\n", numVertices); + fwrite(outStr, sizeof(char), written, meshFile); + } + else + { + // Elements are: x,y,z + written = sprintf_s(outStr, bufSize, "element vertex %u\nproperty float x\nproperty float y\nproperty float z\n", numVertices); + fwrite(outStr, sizeof(char), written, meshFile); + } + + written = sprintf_s(outStr, bufSize, "element face %u\nproperty list uchar int vertex_index\nend_header\n", numTriangles); + fwrite(outStr, sizeof(char), written, meshFile); + + if (flipYZ) + { + if (outputColor) + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + unsigned int color0 = colors[vertexIndex]; + unsigned int color1 = colors[vertexIndex+1]; + unsigned int color2 = colors[vertexIndex+2]; + + written = sprintf_s(outStr, bufSize, "%f %f %f %u %u %u\n%f %f %f %u %u %u\n%f %f %f %u %u %u\n", + vertices[vertexIndex].x, -vertices[vertexIndex].y, -vertices[vertexIndex].z, + ((color0 >> 16) & 255), ((color0 >> 8) & 255), (color0 & 255), + vertices[vertexIndex+1].x, -vertices[vertexIndex+1].y, -vertices[vertexIndex+1].z, + ((color1 >> 16) & 255), ((color1 >> 8) & 255), (color1 & 255), + vertices[vertexIndex+2].x, -vertices[vertexIndex+2].y, -vertices[vertexIndex+2].z, + ((color2 >> 16) & 255), ((color2 >> 8) & 255), (color2 & 255)); + + fwrite(outStr, sizeof(char), written, meshFile); + } + } + else + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "%f %f %f\n%f %f %f\n%f %f %f\n", + vertices[vertexIndex].x, -vertices[vertexIndex].y, -vertices[vertexIndex].z, + vertices[vertexIndex+1].x, -vertices[vertexIndex+1].y, -vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, -vertices[vertexIndex+2].y, -vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + } + else + { + if (outputColor) + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + unsigned int color0 = colors[vertexIndex]; + unsigned int color1 = colors[vertexIndex+1]; + unsigned int color2 = colors[vertexIndex+2]; + + written = sprintf_s(outStr, bufSize, "%f %f %f %u %u %u\n%f %f %f %u %u %u\n%f %f %f %u %u %u\n", + vertices[vertexIndex].x, vertices[vertexIndex].y, vertices[vertexIndex].z, + ((color0 >> 16) & 255), ((color0 >> 8) & 255), (color0 & 255), + vertices[vertexIndex+1].x, vertices[vertexIndex+1].y, vertices[vertexIndex+1].z, + ((color1 >> 16) & 255), ((color1 >> 8) & 255), (color1 & 255), + vertices[vertexIndex+2].x, vertices[vertexIndex+2].y, vertices[vertexIndex+2].z, + ((color2 >> 16) & 255), ((color2 >> 8) & 255), (color2 & 255)); + + fwrite(outStr, sizeof(char), written, meshFile); + } + } + else + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "%f %f %f\n%f %f %f\n%f %f %f\n", + vertices[vertexIndex].x, vertices[vertexIndex].y, vertices[vertexIndex].z, + vertices[vertexIndex+1].x, vertices[vertexIndex+1].y, vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, vertices[vertexIndex+2].y, vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + } + + // Sequentially write the 3 vertex indices of the triangle face, for each triangle (0-referenced in PLY) + for (unsigned int t=0, baseIndex=0; t < numTriangles; ++t, baseIndex += 3) + { + written = sprintf_s(outStr, bufSize, "3 %u %u %u\n", baseIndex, baseIndex+1, baseIndex+2); + fwrite(outStr, sizeof(char), written, meshFile); + } + + fflush(meshFile); + fclose(meshFile); + + return hr; +} + +/// +/// Write ASCII Wavefront .OBJ file with bitmap texture and material file +/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// The Kinect Fusion color texture image. +/// Three Vector3 texture coordinates per mesh triangle, normalized by the image size. +/// S_OK on success, otherwise failure code +HRESULT WriteTexturedeAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ, NUI_FUSION_IMAGE_FRAME *pTexture, const std::vector &texcoords) +{ + HRESULT hr = S_OK; + + if (nullptr == mesh || nullptr == pTexture) + { + return E_INVALIDARG; + } + + unsigned int numVertices = mesh->VertexCount(); + unsigned int numTriangleIndices = mesh->TriangleVertexIndexCount(); + unsigned int numTriangles = numVertices / 3; + + if (0 == numVertices || 0 == numTriangleIndices || 0 != numVertices % 3 || numVertices != numTriangleIndices) + { + return E_INVALIDARG; + } + + const Vector3 *vertices = NULL; + hr = mesh->GetVertices(&vertices); + if (FAILED(hr)) + { + return hr; + } + + const Vector3 *normals = NULL; + hr = mesh->GetNormals(&normals); + if (FAILED(hr)) + { + return hr; + } + + const int *triangleIndices = NULL; + hr = mesh->GetTriangleIndices(&triangleIndices); + if (FAILED(hr)) + { + return hr; + } + + // Open File + std::string filename = std::wstring_convert>().to_bytes(lpOleFileName); + FILE *meshFile = NULL; + errno_t err = fopen_s(&meshFile, filename.c_str(), "wt"); + + // Could not open file for writing - return + if (0 != err || NULL == meshFile) + { + return E_ACCESSDENIED; + } + + // Split the name and extension + std::string mtlfilename = filename + ".mtl"; + + // Open the material file + FILE *mtlFile = NULL; + err = fopen_s(&mtlFile, mtlfilename.c_str(), "wt"); + + // Could not open file for writing - return + if (0 != err || NULL == mtlFile) + { + if (meshFile) + { + fclose(meshFile); + } + return E_ACCESSDENIED; + } + + // Write the header line + std::string header = "#\n# OBJ file created by Microsoft Kinect Fusion\n#\n"; + fwrite(header.c_str(), sizeof(char), header.length(), meshFile); + + // Split to extract path + std::string::size_type pos = filename.find_last_of("\\", filename.length()); + std::string filenamePath = filename.substr(0,pos+1); + std::string filenameRelative = filename.substr(pos+1); + + // Write that we have an accompanying material file + std::string mtlfile = "mtllib " + filenameRelative + ".mtl\n"; + fwrite(mtlfile.c_str(), sizeof(char), mtlfile.length(), meshFile); + + const unsigned int bufSize = MAX_PATH*3; + char outStr[bufSize]; + int written = 0; + + if (flipYZ) + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "v %f %f %f\nv %f %f %f\nv %f %f %f\n", + vertices[vertexIndex].x, -vertices[vertexIndex].y, -vertices[vertexIndex].z, + vertices[vertexIndex+1].x, -vertices[vertexIndex+1].y, -vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, -vertices[vertexIndex+2].y, -vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Sequentially write the 3 normals of the triangle, for each triangle + for (unsigned int t=0, normalIndex=0; t < numTriangles; ++t, normalIndex += 3) + { + written = sprintf_s(outStr, bufSize, "n %f %f %f\nn %f %f %f\nn %f %f %f\n", + normals[normalIndex].x, -normals[normalIndex].y, -normals[normalIndex].z, + normals[normalIndex+1].x, -normals[normalIndex+1].y, -normals[normalIndex+1].z, + normals[normalIndex+2].x, -normals[normalIndex+2].y, -normals[normalIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + else + { + // Sequentially write the 3 vertices of the triangle, for each triangle + for (unsigned int t=0, vertexIndex=0; t < numTriangles; ++t, vertexIndex += 3) + { + written = sprintf_s(outStr, bufSize, "v %f %f %f\nv %f %f %f\nv %f %f %f\n", + vertices[vertexIndex].x, vertices[vertexIndex].y, vertices[vertexIndex].z, + vertices[vertexIndex+1].x, vertices[vertexIndex+1].y, vertices[vertexIndex+1].z, + vertices[vertexIndex+2].x, vertices[vertexIndex+2].y, vertices[vertexIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Sequentially write the 3 normals of the triangle, for each triangle + for (unsigned int t=0, normalIndex=0; t < numTriangles; ++t, normalIndex += 3) + { + written = sprintf_s(outStr, bufSize, "n %f %f %f\nn %f %f %f\nn %f %f %f\n", + normals[normalIndex].x, normals[normalIndex].y, normals[normalIndex].z, + normals[normalIndex+1].x, normals[normalIndex+1].y, normals[normalIndex+1].z, + normals[normalIndex+2].x, normals[normalIndex+2].y, normals[normalIndex+2].z); + fwrite(outStr, sizeof(char), written, meshFile); + } + } + + // Sequentially write the 3 texture coordinates of the triangle, for each triangle + for (unsigned int t=0, texcoordIndex=0; t < numTriangles; ++t, texcoordIndex += 3) + { + written = sprintf_s(outStr, bufSize, "vt %f %f\nvt %f %f\nvt %f %f\n", + texcoords[texcoordIndex].x, texcoords[texcoordIndex].y, + texcoords[texcoordIndex+1].x, texcoords[texcoordIndex+1].y, + texcoords[texcoordIndex+2].x, texcoords[texcoordIndex+2].y); + fwrite(outStr, sizeof(char), written, meshFile); + } + + // Write that we are using material0 (i.e. the texture) + std::string material = "usemtl material0\n"; + fwrite(material.c_str(), sizeof(char), material.length(), meshFile); + + + // Sequentially write the 3 vertex indices of the triangle face, for each triangle + // Note this is typically 1-indexed in an OBJ file when using absolute referencing! + for (unsigned int t=0, baseIndex=1; t < numTriangles; ++t, baseIndex += 3) // Start at baseIndex=1 for the 1-based indexing. + { + written = sprintf_s(outStr, bufSize, "f %u/%u/%u %u/%u/%u %u/%u/%u\n", + baseIndex, baseIndex, baseIndex, baseIndex+1, baseIndex+1, baseIndex+1, baseIndex+2, baseIndex+2, baseIndex+2); + fwrite(outStr, sizeof(char), written, meshFile); + } + + fflush(meshFile); + fclose(meshFile); + + // Write the material description file + header = "#\n# OBJ file created by Microsoft Kinect Fusion\n#\n"; + fwrite(header.c_str(), sizeof(char), header.length(), mtlFile); + + material = "newmtl material0\n"; + fwrite(material.c_str(), sizeof(char), material.length(), mtlFile); + + // Create the texture filename + std::string textureFilename = filenameRelative + ".bmp"; + + // Write the generic materials definition together with the texture filename. + std::string mtldescription ="Ka 1.000000 1.000000 1.000000\n" + "Kd 1.000000 1.000000 1.000000\n" + "Ks 0.000000 0.000000 0.000000\n" + "Tr 1.000000\n" + "illum 1\n" + "Ns 0.000000\n" + "map_Kd " + textureFilename + "\n"; + fwrite(mtldescription.c_str(), sizeof(char), mtldescription.length(), mtlFile); + + fflush(mtlFile); + fclose(mtlFile); + + std::string textureFilenamePath = filenamePath + textureFilename; + CA2W pszW( textureFilenamePath.c_str() ); + + // Write out the texture + NUI_FUSION_BUFFER *fusionColorBuffer = pTexture->pFrameBuffer; + + if (fusionColorBuffer->Pitch == 0) + { + return E_FAIL; + } + + // Save the texture + hr = SaveBMPFile(pszW, fusionColorBuffer->pBits, pTexture->width, pTexture->height); + + return hr; +} + +/// +/// Returns whether this is running as a 32 or 64bit application. +/// +/// TRUE indicates a 64bit app. +BOOL Is64BitApp() +{ +#if defined(_WIN64) + // If _WIN64 is defined, we are a 64-bit version as + // this will only be defined on Win64 + return TRUE; +#else + // 32-bit programs run on both 32-bit and 64-bit Windows with WOW64, + // however the restrictions are the same for our application. + return FALSE; +#endif +} + +/// +/// Write 32bit BMP image file +/// +/// The full path and filename of the file to save. +/// A pointer to the image bytes to save. +/// The width of the image to save. +/// The width of the image to save. +/// indicates success or failure +HRESULT SaveBMPFile(LPCWSTR pszFile, const byte *pImageBytes, unsigned int width, unsigned int height) +{ + // Each pixel is 8 bits per color, 4 values interleaved (R,G,B,A) = 32 bits total + const WORD cBitsPerColor = 8; + const WORD cColorValues = 4; + WORD cColorBits = cBitsPerColor * cColorValues; + + // No need to pad the array as we already have 32bit pixels. + DWORD imageByteSize = static_cast(width) * static_cast(height) * static_cast(cColorBits/8); + + // However, we may need to swap R and B byte ordering. + + // Set headers + BITMAPFILEHEADER bmfh; + BITMAPINFOHEADER info; + memset (&bmfh, 0, sizeof(BITMAPFILEHEADER)); + memset (&info, 0, sizeof(BITMAPINFOHEADER)); + + bmfh.bfType = 0x4d42; // Magic number "BM" + bmfh.bfReserved1 = 0; + bmfh.bfReserved2 = 0; + bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + imageByteSize; + bmfh.bfOffBits = 0x36; + + info.biSize = sizeof(BITMAPINFOHEADER); + info.biWidth = width; + info.biHeight = height; + info.biPlanes = 1; + info.biBitCount = cColorBits; + info.biCompression = BI_RGB; + info.biSizeImage = 0; + info.biXPelsPerMeter = 0x0ec4; + info.biYPelsPerMeter = 0x0ec4; + info.biClrUsed = 0; + info.biClrImportant = 0; + + // Open file and write + HANDLE file = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == file) + { + return E_INVALIDARG; + } + + unsigned long bytesWritten = 0; + + if (FALSE == WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bytesWritten, NULL)) + { + CloseHandle(file); + return E_FAIL; + } + + if (FALSE == WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bytesWritten, NULL)) + { + CloseHandle(file); + return E_FAIL; + } + + if (FALSE == WriteFile(file, pImageBytes, imageByteSize, &bytesWritten, NULL)) + { + CloseHandle(file); + return E_FAIL; + } + + CloseHandle(file); + + return S_OK; +} + +/// +/// Copy an image with identical sizes and parameters. +/// +/// A pointer to the source image. +/// A pointer to the destination image. +/// indicates success or failure +HRESULT CopyImageFrame(const NUI_FUSION_IMAGE_FRAME *pSrc, const NUI_FUSION_IMAGE_FRAME *pDest) +{ + HRESULT hr = S_OK; + + if (nullptr == pSrc || nullptr == pSrc->pFrameBuffer || nullptr == pDest || nullptr == pDest->pFrameBuffer) + { + return E_INVALIDARG; + } + + if (pSrc->imageType != pDest->imageType) + { + return E_INVALIDARG; + } + + if (0 == pSrc->width || 0 == pSrc->height || pSrc->width != pDest->width || pSrc->height != pDest->height) + { + return E_NOINTERFACE; + } + + NUI_FUSION_BUFFER *srcImageFrameBuffer = pSrc->pFrameBuffer; + + // Make sure we've received valid data + if (srcImageFrameBuffer->Pitch != 0) + { + NUI_FUSION_BUFFER *destImageFrameBuffer = pDest->pFrameBuffer; + + // Make sure we've received valid data + if (destImageFrameBuffer->Pitch != 0) + { + // Copy + errno_t err = memcpy_s( + destImageFrameBuffer->pBits, + destImageFrameBuffer->Pitch * pDest->height, + srcImageFrameBuffer->pBits, + srcImageFrameBuffer->Pitch * pSrc->height); + + if (0 != err) + { + hr = E_FAIL; + } + } + } + + return hr; +} + +/// +/// Color the residual/delta image from the AlignDepthFloatToReconstruction call +/// +/// A pointer to the source FloatDeltaFromReference image. +/// A pointer to the destination color ShadedDeltaFromReference image. +/// S_OK on success, otherwise failure code +HRESULT ColorResiduals(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, const NUI_FUSION_IMAGE_FRAME *pShadedDeltaFromReference) +{ + if (nullptr == pShadedDeltaFromReference || + nullptr == pFloatDeltaFromReference) + { + return E_FAIL; + } + + if (nullptr == pShadedDeltaFromReference->pFrameBuffer || + nullptr == pFloatDeltaFromReference->pFrameBuffer) + { + return E_NOINTERFACE; + } + + if (pFloatDeltaFromReference->imageType != NUI_FUSION_IMAGE_TYPE_FLOAT || pShadedDeltaFromReference->imageType != NUI_FUSION_IMAGE_TYPE_COLOR) + { + return E_INVALIDARG; + } + + unsigned int width = pShadedDeltaFromReference->width; + unsigned int height = pShadedDeltaFromReference->height; + + if (width != pFloatDeltaFromReference->width + || height != pFloatDeltaFromReference->height) + { + return E_INVALIDARG; + } + + if (pShadedDeltaFromReference->pFrameBuffer->Pitch == 0 + || pFloatDeltaFromReference->pFrameBuffer->Pitch == 0) + { + return E_INVALIDARG; + } + + unsigned int *pColorBuffer = reinterpret_cast(pShadedDeltaFromReference->pFrameBuffer->pBits); + const float *pFloatBuffer = reinterpret_cast(pFloatDeltaFromReference->pFrameBuffer->pBits); + + Concurrency::parallel_for(0u, height, [&](unsigned int y) + { + unsigned int* pColorRow = reinterpret_cast(reinterpret_cast(pColorBuffer) + (y * pShadedDeltaFromReference->pFrameBuffer->Pitch)); + const float* pFloatRow = reinterpret_cast(reinterpret_cast(pFloatBuffer) + (y * pFloatDeltaFromReference->pFrameBuffer->Pitch)); + + for (unsigned int x = 0; x < width; ++x) + { + float residue = pFloatRow[x]; + unsigned int color = 0; + + if (residue <= 1.0f) // Pixel byte ordering: ARGB + { + color |= (255 << 24); // a + color |= (static_cast(255.0f * clamp(1.0f + residue, 0.0f, 1.0f)) << 16); // r + color |= (static_cast(255.0f * clamp(1.0f - std::abs(residue), 0.0f, 1.0f)) << 8); // g + color |= (static_cast(255.0f * clamp(1.0f - residue, 0.0f, 1.0f))); // b + } + + pColorRow[x] = color; + } + }); + + return S_OK; +} + +/// +/// Calculate statistics on the residual/delta image from the AlignDepthFloatToReconstruction call. +/// +/// A pointer to the source FloatDeltaFromReference image. +/// S_OK on success, otherwise failure code +HRESULT CalculateResidualStatistics(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, DeltaFromReferenceImageStatistics *stats) +{ + if (nullptr == pFloatDeltaFromReference || nullptr == stats) + { + return E_INVALIDARG; + } + + if (nullptr == pFloatDeltaFromReference->pFrameBuffer) + { + return E_NOINTERFACE; + } + + unsigned int width = pFloatDeltaFromReference->width; + unsigned int height = pFloatDeltaFromReference->height; + + if (0 == width || 0 == height || pFloatDeltaFromReference->pFrameBuffer->Pitch == 0) + { + return E_INVALIDARG; + } + + const float *pFloatBuffer = reinterpret_cast(pFloatDeltaFromReference->pFrameBuffer->pBits); + + // Measurement stats + std::vector zeroPixelsRow; + std::vector validPixelsRow; + std::vector invalidDepthOutsideVolumePixelsRow; + std::vector validPixelDistanceRow; + + zeroPixelsRow.resize(height, 0); + validPixelsRow.resize(height, 0); + invalidDepthOutsideVolumePixelsRow.resize(height, 0); + validPixelDistanceRow.resize(height, 0); + + Concurrency::parallel_for(0u, height, [&](unsigned int y) + { + const float* pFloatRow = reinterpret_cast(reinterpret_cast(pFloatBuffer) + (y * pFloatDeltaFromReference->pFrameBuffer->Pitch)); + + for (unsigned int x = 0; x < width; ++x) + { + float residue = pFloatRow[x]; + + // If the depth was invalid or the depth back-projected outside the volume, the residual is set to 2.0f + // However, if the voxel contents are 0 the residual will also return 0 here. + if (residue == 0.0f) + { + ++zeroPixelsRow[y]; + } + else if (residue == 2.0f) + { + ++invalidDepthOutsideVolumePixelsRow[y]; + } + else if (residue <= 1.0f) // Pixel byte ordering: ARGB + { + ++validPixelsRow[y]; + validPixelDistanceRow[y] += residue; + } + } + }); + + stats->validPixels = stats->zeroPixels = stats->invalidDepthOutsideVolumePixels = 0; + stats->totalValidPixelsDistance = 0; + stats->totalPixels = width * height; + + for (unsigned int y=0; yzeroPixels += zeroPixelsRow[y]; + stats->validPixels += validPixelsRow[y]; + stats->invalidDepthOutsideVolumePixels += invalidDepthOutsideVolumePixelsRow[y]; + + stats->totalValidPixelsDistance += validPixelDistanceRow[y]; + } + + return S_OK; +} + +/// +/// Horizontally mirror a 32bit (color/float) image in-place. +/// +/// A pointer to the image to mirror. +/// S_OK on success, otherwise failure code +HRESULT HorizontalMirror32bitImageInPlace(const NUI_FUSION_IMAGE_FRAME *pImage) +{ + if (nullptr == pImage || !(pImage->imageType == NUI_FUSION_IMAGE_TYPE_COLOR || pImage->imageType == NUI_FUSION_IMAGE_TYPE_FLOAT)) + { + return E_INVALIDARG; + } + + if (nullptr == pImage->pFrameBuffer) + { + return E_NOINTERFACE; + } + + unsigned int width = pImage->width; + unsigned int height = pImage->height; + + if (0 == width || 0 == height || pImage->pFrameBuffer->Pitch == 0) + { + return E_INVALIDARG; + } + + unsigned int *rawPixels = reinterpret_cast(pImage->pFrameBuffer->pBits); + + Concurrency::parallel_for(0u, height, [&](unsigned int y) + { + unsigned int index = y * width; + unsigned int mirrorIndex = index + width - 1; + + for (unsigned int x = 0; x < (width / 2); ++x, ++index, --mirrorIndex) + { + // In-place swap to mirror + unsigned int temp = rawPixels[index]; + rawPixels[index] = rawPixels[mirrorIndex]; + rawPixels[mirrorIndex] = temp; + } + }); + + return S_OK; +} + +/// +/// Horizontally mirror a 32bit (color/float) image. +/// +/// A pointer to the image to mirror. +/// A pointer to the destination mirrored image. +/// S_OK on success, otherwise failure code +HRESULT HorizontalMirror32bitImage(const NUI_FUSION_IMAGE_FRAME *pSrcImage, const NUI_FUSION_IMAGE_FRAME *pDestImage) +{ + if (nullptr == pSrcImage || nullptr == pDestImage) + { + return E_INVALIDARG; + } + + if (nullptr == pSrcImage->pFrameBuffer || nullptr == pDestImage->pFrameBuffer) + { + return E_NOINTERFACE; + } + + if (!(pSrcImage->imageType == NUI_FUSION_IMAGE_TYPE_FLOAT || pSrcImage->imageType == NUI_FUSION_IMAGE_TYPE_COLOR) + || pSrcImage->imageType != pDestImage->imageType) + { + return E_INVALIDARG; + } + + unsigned int width = pSrcImage->width; + unsigned int height = pSrcImage->height; + + if (width != pDestImage->width || height != pDestImage->height) + { + return E_INVALIDARG; + } + + if (pSrcImage->pFrameBuffer->Pitch == 0 || pDestImage->pFrameBuffer->Pitch == 0) + { + return E_INVALIDARG; + } + + const unsigned int *pSrcBuffer = reinterpret_cast(pSrcImage->pFrameBuffer->pBits); + unsigned int *pDestBuffer = reinterpret_cast(pDestImage->pFrameBuffer->pBits); + + Concurrency::parallel_for(0u, height, [&](unsigned int y) + { + const unsigned int *pSrcRow = reinterpret_cast(reinterpret_cast(pSrcBuffer) + (y * pSrcImage->pFrameBuffer->Pitch)); + unsigned int *pDestRow = reinterpret_cast(reinterpret_cast(pDestBuffer) + (y * pDestImage->pFrameBuffer->Pitch)); + + for (unsigned int x = 0, flippedX = width-1; x < width; ++x, --flippedX) + { + pDestRow[flippedX] = pSrcRow[x]; + } + }); + + return S_OK; +} + +/// +/// Tests whether a resampling factor is valid. +/// +/// The resampling factor. +/// true if a valid resampling factor, otherwise false. +/// +/// Valid resampling factors are powers of two between 1 and 16, inclusive. +/// +static inline bool IsValidResampleFactor(unsigned int factor) +{ + return (1 == factor || 2 == factor || 4 == factor || 8 == factor || 16 == factor); +} + +/// +/// Down sample color frame with nearest neighbor to the depth frame resolution +/// +/// The source color image. +/// The destination down sampled image. +/// S_OK on success, otherwise failure code +HRESULT DownsampleColorFrameToDepthResolution(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest) +{ + if (nullptr == src || nullptr == dest) + { + return E_INVALIDARG; + } + + if (src->imageType != NUI_FUSION_IMAGE_TYPE_COLOR || src->imageType != dest->imageType + || src->width != 1920 || src->height != 1080 || dest->width != NUI_DEPTH_RAW_WIDTH || dest->height != NUI_DEPTH_RAW_HEIGHT) + { + return E_INVALIDARG; + } + + NUI_FUSION_BUFFER *srcFrameBuffer = src->pFrameBuffer; + NUI_FUSION_BUFFER *downsampledFloatFrameBuffer = dest->pFrameBuffer; + + float factor = 1080.0f / NUI_DEPTH_RAW_HEIGHT; + + // Make sure we've received valid data + if (srcFrameBuffer->Pitch == 0 || downsampledFloatFrameBuffer->Pitch == 0) + { + return E_NOINTERFACE; + } + + HRESULT hr = S_OK; + float *srcValues = (float *)srcFrameBuffer->pBits; + float *downsampledDestValues = (float *)downsampledFloatFrameBuffer->pBits; + + const unsigned int filledZeroMargin = 0; + const unsigned int downsampledWidth = dest->width; + const unsigned int srcImageWidth = src->width; + + ZeroMemory(downsampledDestValues, downsampledFloatFrameBuffer->Pitch * dest->height); + Concurrency::parallel_for(filledZeroMargin, dest->height - filledZeroMargin, [=, &downsampledDestValues, &srcValues](unsigned int y) + { + unsigned int index = dest->width * y; + for (unsigned int x=0; x < downsampledWidth; ++x, ++index) + { + int srcX = (int)(x * factor); + int srcY = (int)(y * factor); + int srcIndex = srcY * srcImageWidth + srcX; + downsampledDestValues[index] = srcValues[srcIndex]; + } + }); + + return hr; +} + +/// +/// Down sample color, depth float or point cloud frame with nearest neighbor +/// +/// The source depth float or pointcloud image. +/// The destination down sampled depth float or pointcloud image. +/// The down sample factor (1=just copy, 2=x/2,y/2, 4=x/4,y/4). +/// S_OK on success, otherwise failure code +HRESULT DownsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor) +{ + if (nullptr == src || nullptr == dest) + { + return E_INVALIDARG; + } + + if (!(src->imageType == NUI_FUSION_IMAGE_TYPE_COLOR || src->imageType == NUI_FUSION_IMAGE_TYPE_FLOAT || src->imageType == NUI_FUSION_IMAGE_TYPE_POINT_CLOUD) + || src->imageType != dest->imageType) + { + return E_INVALIDARG; + } + + if (!IsValidResampleFactor(factor)) + { + return E_INVALIDARG; + } + + NUI_FUSION_BUFFER *srcFrameBuffer = src->pFrameBuffer; + NUI_FUSION_BUFFER *downsampledFloatFrameBuffer = dest->pFrameBuffer; + + unsigned int downsampledWidth = src->width / factor; + unsigned int downsampleHeight = src->height / factor; + + if (1 == factor && srcFrameBuffer->Pitch * src->height != downsampledFloatFrameBuffer->Pitch * dest->height) + { + return E_INVALIDARG; + } + else if (dest->width != downsampledWidth || dest->height != downsampleHeight) + { + return E_INVALIDARG; + } + + // Make sure we've received valid data + if (srcFrameBuffer->Pitch == 0 || downsampledFloatFrameBuffer->Pitch == 0) + { + return E_NOINTERFACE; + } + + HRESULT hr = S_OK; + float *srcValues = (float *)srcFrameBuffer->pBits; + float *downsampledDestValues = (float *)downsampledFloatFrameBuffer->pBits; + + const unsigned int srcImageWidth = src->width; + + if (1 == factor) + { + errno_t err = memcpy_s(downsampledDestValues, downsampledFloatFrameBuffer->Pitch * dest->height, srcValues, srcFrameBuffer->Pitch * src->height); + if (0 != err) + { + hr = E_FAIL; + } + } + else + { + // Adjust for point cloud image size (6 floats per pixel) + unsigned int step = (src->imageType == NUI_FUSION_IMAGE_TYPE_POINT_CLOUD) ? 6 : 1; + unsigned int factorStep = factor * step; + + Concurrency::parallel_for(0u, downsampleHeight, [=, &downsampledDestValues, &srcValues](unsigned int y) + { + unsigned int index = downsampledWidth * y * step; + unsigned int srcIndex = srcImageWidth * y * factorStep; + + for (unsigned int x=0; x +/// Up sample color or depth float (32bits/pixel) frame with nearest neighbor - replicates pixels +/// +/// The source color image. +/// The destination up-sampled color image. +/// The up sample factor (1=just copy, 2=x*2,y*2, 4=x*4,y*4). +/// S_OK on success, otherwise failure code +HRESULT UpsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor) +{ + if (nullptr == src || nullptr == dest) + { + return E_INVALIDARG; + } + + if (src->imageType != dest->imageType || !(src->imageType == NUI_FUSION_IMAGE_TYPE_COLOR || src->imageType == NUI_FUSION_IMAGE_TYPE_FLOAT)) + { + return E_INVALIDARG; + } + + if (!IsValidResampleFactor(factor)) + { + return E_INVALIDARG; + } + + NUI_FUSION_BUFFER *srcFrameBuffer = src->pFrameBuffer; + NUI_FUSION_BUFFER *upsampledDestFrameBuffer = dest->pFrameBuffer; + + unsigned int upsampledWidth = src->width * factor; + unsigned int upsampleHeight = src->height * factor; + + if (1 == factor && srcFrameBuffer->Pitch * src->height != upsampledDestFrameBuffer->Pitch * dest->height) + { + return E_INVALIDARG; + } + else if (dest->width != upsampledWidth || dest->height != upsampleHeight) + { + return E_INVALIDARG; + } + + // Make sure we've received valid data + if (srcFrameBuffer->Pitch == 0 || upsampledDestFrameBuffer->Pitch == 0) + { + return E_NOINTERFACE; + } + + HRESULT hr = S_OK; + unsigned int *srcValues = (unsigned int *)srcFrameBuffer->pBits; + unsigned int *upsampledDestValues = (unsigned int *)upsampledDestFrameBuffer->pBits; + + const unsigned int srcImageWidth = src->width; + const unsigned int srcImageHeight = src->height; + + if (1 == factor) + { + errno_t err = memcpy_s(upsampledDestValues, upsampledDestFrameBuffer->Pitch * dest->height, srcValues, srcFrameBuffer->Pitch * src->height); + if (0 != err) + { + hr = E_FAIL; + } + } + else + { + unsigned int upsampleRowMultiplier = upsampledWidth * factor; + + // Note we run this only for the source image height pixels to sparsely fill the destination with rows + Concurrency::parallel_for(0u, srcImageHeight, [=, &upsampledDestValues, &srcValues](unsigned int y) + { + unsigned int index = upsampleRowMultiplier * y; + unsigned int srcIndex = srcImageWidth * y; + + // Fill row + for (unsigned int x=0; x +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +#pragma once + +#include "NuiKinectFusionApi.h" +#include +#include + +/// +/// Set Identity in a Matrix4 +/// +/// The matrix to set to identity +void SetIdentityMatrix(Matrix4 &mat); + +/// +/// Extract translation values from the 4x4 Matrix4 transformation in M41,M42,M43 +/// +/// The transform matrix. +/// Array of 3 floating point values for translation. +void ExtractVector3Translation(const Matrix4 &transform, _Out_cap_c_(3) float *translation); + +/// +/// Extract translation Vector3 from the 4x4 Matrix transformation in M41,M42,M43 +/// +/// The transform matrix. +/// Returns a Vector3 containing the translation. +Vector3 ExtractVector3Translation(const Matrix4 &transform); + +/// +/// Extract 3x3 rotation from the 4x4 Matrix and return in new Matrix4 +/// +/// The transform matrix. +/// Returns a Matrix4 containing the rotation. +Matrix4 Extract3x3Rotation(const Matrix4 &transform); + +/// +/// Extract 3x3 rotation matrix from the Matrix4 4x4 transformation: +/// Then convert to Euler angles. +/// +/// The transform matrix. +/// Array of 3 floating point values for euler angles. +void ExtractRot2Euler(const Matrix4 &transform, _Out_cap_c_(3) float *rotation); + +/// +/// 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. +/// +/// The transform matrix from the previous frame. +/// The transform matrix from the current frame. +/// The maximum translation in meters we expect per x,y,z component between frames under normal motion. +/// The maximum rotation in degrees we expect about the x,y,z axes between frames under normal motion. +/// true if camera transformation is greater than the threshold, otherwise false +bool CameraTransformFailed(const Matrix4 &T_initial, const Matrix4 &T_final, float maxTrans, float maxRotDegrees); + +/// +/// Invert the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The rotation matrix to invert. +void InvertRotation(Matrix4 &rot); + +/// +/// Negate the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The rotation matrix to negate. +void NegateRotation(Matrix4 &rot); + +/// +/// Rotate a vector with the 3x3 Rotation Matrix Component of a 4x4 matrix +/// +/// The Vector3 to rotate. +/// Rotation matrix. +Vector3 RotateVector(const Vector3 &vec, const Matrix4 &rot); + +/// +/// Invert Matrix4 Pose either from WorldToCameraTransform (view) matrix to CameraToWorldTransform pose matrix (world/SE3) or vice versa +/// +/// The camera pose transform matrix. +/// Returns a Matrix4 containing the inverted camera pose. +Matrix4 InvertMatrix4Pose(const Matrix4 &transform); + +/// +/// Write Binary .STL mesh file +/// see http://en.wikipedia.org/wiki/STL_(file_format) for STL format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// indicates success or failure +HRESULT WriteBinarySTLMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true); + +/// +/// Write ASCII Wavefront .OBJ mesh file +/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// indicates success or failure +HRESULT WriteAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true); + +/// +/// Write ASCII .PLY file +/// See http://paulbourke.net/dataformats/ply/ for .PLY format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// Set this true to write out the surface color to the file when it has been captured. +/// indicates success or failure +HRESULT WriteAsciiPlyMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ = true, bool outputColor = false); + +/// +/// Write ASCII Wavefront .OBJ file with bitmap texture and material file +/// See http://en.wikipedia.org/wiki/Wavefront_.obj_file for .OBJ format +/// +/// The Kinect Fusion mesh object. +/// The full path and filename of the file to save. +/// Flag to determine whether the Y and Z values are flipped on save. +/// The Kinect Fusion color texture image. +/// Three Vector3 texture coordinates per mesh triangle, normalized by the image size. +/// S_OK on success, otherwise failure code +HRESULT WriteTexturedeAsciiObjMeshFile(INuiFusionColorMesh *mesh, LPOLESTR lpOleFileName, bool flipYZ, NUI_FUSION_IMAGE_FRAME *pTexture, const std::vector &texcoords); + +/// +/// Returns whether this is running as a 32 or 64bit application. +/// +/// TRUE indicates a 64bit app. +BOOL Is64BitApp(); + +/// +/// Write 32bit BMP image file +/// +/// The full path and filename of the file to save. +/// A pointer to the image bytes to save. +/// The width of the image to save. +/// The width of the image to save. +/// indicates success or failure +HRESULT SaveBMPFile(LPCWSTR pszFile, const byte *pImageBytes, unsigned int width, unsigned int height); + +/// +/// Copy an image with identical sizes and parameters. +/// +/// A pointer to the source image. +/// A pointer to the destination image. +/// indicates success or failure +HRESULT CopyImageFrame(const NUI_FUSION_IMAGE_FRAME *pSrc, const NUI_FUSION_IMAGE_FRAME *pDest); + +/// +/// Horizontally mirror a 32bit (color/float) image in-place. +/// +/// A pointer to the image to mirror. +/// S_OK on success, otherwise failure code +HRESULT HorizontalMirror32bitImageInPlace(const NUI_FUSION_IMAGE_FRAME *pImage); + +/// +/// Horizontally mirror a 32bit (color/float) image. +/// +/// A pointer to the image to mirror. +/// A pointer to the destination mirrored image. +/// S_OK on success, otherwise failure code +HRESULT HorizontalMirror32bitImage(const NUI_FUSION_IMAGE_FRAME *pSrcImage, const NUI_FUSION_IMAGE_FRAME *pDestImage); + +/// +/// Color the residual/delta image from the AlignDepthFloatToReconstruction call +/// +/// A pointer to the source pFloatDeltaFromReference image. +/// A pointer to the destination ShadedDeltaFromReference image. +/// S_OK on success, otherwise failure code +HRESULT ColorResiduals(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, const NUI_FUSION_IMAGE_FRAME *pShadedDeltaFromReference); + +/// +/// Statistics calculated for a FloatDeltaFromReference Image after the +/// AlignDepthFloatToReconstruction and CalculateResidualStatistics calls. +/// +struct DeltaFromReferenceImageStatistics +{ + unsigned int totalPixels; + unsigned int zeroPixels; + unsigned int validPixels; + unsigned int invalidDepthOutsideVolumePixels; + float totalValidPixelsDistance; +}; + +/// +/// Calculate statistics on the residual/delta image from the AlignDepthFloatToReconstruction call. +/// +/// A pointer to the source FloatDeltaFromReference image. +/// A pointer to a DeltaFromReferenceImageStatistics struct to fill with the statistics. +/// S_OK on success, otherwise failure code +HRESULT CalculateResidualStatistics(const NUI_FUSION_IMAGE_FRAME *pFloatDeltaFromReference, DeltaFromReferenceImageStatistics *stats); + +/// +/// Down sample color, depth float or point cloud frame with nearest neighbor +/// +/// The source color, depth float or pointcloud image. +/// The destination down sampled color, depth float or pointcloud image. +/// The down sample factor (1=just copy, 2=x/2,y/2, 4=x/4,y/4). +/// S_OK on success, otherwise failure code +HRESULT DownsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor); + +/// +/// Up sample color or depth float (32 bits/pixel) frame with nearest neighbor - replicates pixels +/// +/// The source color image. +/// The destination up-sampled color image. +/// The up sample factor (1=just copy, 2=x*2,y*2, 4=x*4,y*4). +/// S_OK on success, otherwise failure code +HRESULT UpsampleFrameNearestNeighbor(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest, unsigned int factor); + +/// +/// Down sample color frame with nearest neighbor to the depth frame resolution +/// +/// The source color image. +/// The destination down sampled image. +/// S_OK on success, otherwise failure code +HRESULT DownsampleColorFrameToDepthResolution(NUI_FUSION_IMAGE_FRAME *src, NUI_FUSION_IMAGE_FRAME *dest); + +/// +/// Convert int to string +/// +/// The int value to convert. +/// Returns a string containing the int value. +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); +} + +/// +/// Convert float to string +/// +/// The float value to convert. +/// Returns a string containing the float value. +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); +} + +/// +/// Clamp a value if outside two given thresholds +/// +/// The value to clamp. +/// The minimum inclusive threshold. +/// The maximum inclusive threshold. +/// Returns the clamped value. +template +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; +} + +/// +/// Load an 24bit RGB color from a packed int pixel image and return as float values +/// +/// The int image array. +/// The x coordinate of the pixel to return. +/// The y coordinate of the pixel to return. +/// The width of the image in pixels. +/// Returns a Vector3 containing the rgb color components. +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(packedValue & 255); // r + rgb.y = static_cast((packedValue >> 8) & 255); // g + rgb.z = static_cast((packedValue >> 16) & 255); // b + + return rgb; +} + +/// +/// Linearly interpolate (Lerp) between two values. +/// +/// The first value. +/// The second value. +/// The amount to interpolate between the values. +/// Returns the interpolated value. +template +inline auto lerp(const T& a, const T& b, Tf f) -> decltype(a + f * (b - a)) +{ + return a + f * (b - a); +} + +/// +/// Linearly interpolate (Lerp) between two Vector3-based RGB color pixels. +/// +/// The first color pixel. +/// The second color pixel. +/// The amount to interpolate between the values. +/// Returns the interpolated value. +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; +} + +/// +/// Bilinear sample an RGB int image +/// +/// The int image array. +/// The x coordinate of the pixel to return. +/// The y coordinate of the pixel to return. +/// The width of the image in pixels. +/// The height of the image in pixels. +/// Returns a packed int containing the rgb color components. +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(x - half); + const unsigned int yi = static_cast(y - half); + + const float xf = x - half - static_cast(xi); + const float yf = y - half - static_cast(yi); + + const unsigned int posax = clamp(xi, 0, imageWidth - 1); + const unsigned int posay = clamp(yi, 0, imageHeight - 1); + + const unsigned int posbx = clamp(xi+1, 0, imageWidth - 1); + const unsigned int posby = clamp(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(dxy.z) << 16 | static_cast(dxy.y) << 8 | static_cast(dxy.x) ); // always full alpha +} + +/// +/// Calculate the squared difference between two Vector3 vertices +/// +/// The first vertex. +/// The second vertex. +/// Returns the squared difference. +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); +} + +/// +/// Calculate the distance between two Vector3 vertices +/// +/// The first vertex. +/// The second vertex. +/// Returns the distance. +inline float distance(const Vector3 &v1, const Vector3 &v2) +{ + return sqrtf(squared_difference(v1, v2)); +} + +/// +/// 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 +/// +/// The first vector. +/// The second vector. +/// Returns the dot product. +inline float dot_normalized(const Vector3 &v1, const Vector3 &v2) +{ + return (v1.x*v2.x) + (v1.y*v2.y) + (v1.z*v2.z); +} + +/// +/// Transform a vertex in the world coordinate system by the worldToCamera pose, +/// into the camera coordinate system. +/// +/// The vertex to transform. +/// The worldToCamera pose. +/// Returns the transformed vertex. +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; +} + +/// +/// Project a 3D vertex in the world coordinate system into a 2D camera image, +/// given its known intrinsic parameters and camera pose. +/// +/// The vertex to transform. +/// The focal length in the x axis, in pixels. +/// The focal length in the y axis, in pixels. +/// The principal point of the image in the x axis, in pixels. +/// The principal point of the image in the y axis, in pixels. +/// The worldToCamera pose. +/// Returns the 3D vertex transformed into a pixel in the 2D camera image. +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; +} diff --git a/Kinect2Sample-master/sample/Fusion/app.cpp b/Kinect2Sample-master/sample/Fusion/app.cpp new file mode 100644 index 0000000..9334d63 --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/app.cpp @@ -0,0 +1,365 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth() +{ + // Retrieve Depth Frame + ComPtr depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( 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( 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 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( &colorBuffer[0] ); + RGBQUAD* dst = reinterpret_cast( 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( point.X + 0.5f ); + int colorY = static_cast( 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 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 ) ); + */ +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/app.h b/Kinect2Sample-master/sample/Fusion/app.h new file mode 100644 index 0000000..afaa476 --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/app.h @@ -0,0 +1,118 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +// 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 + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr depthFrameReader; + + // Fusion + ComPtr reconstruction; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + + // Depth Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/main.cpp b/Kinect2Sample-master/sample/Fusion/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Fusion/util.h b/Kinect2Sample-master/sample/Fusion/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Fusion/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/CMakeLists.txt b/Kinect2Sample-master/sample/Gesture/CMakeLists.txt new file mode 100644 index 0000000..dc9e778 --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Gesture/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/SampleDatabase.gbd b/Kinect2Sample-master/sample/Gesture/SampleDatabase.gbd new file mode 100644 index 0000000..81b224e Binary files /dev/null and b/Kinect2Sample-master/sample/Gesture/SampleDatabase.gbd differ diff --git a/Kinect2Sample-master/sample/Gesture/app.cpp b/Kinect2Sample-master/sample/Gesture/app.cpp new file mode 100644 index 0000000..8432279 --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/app.cpp @@ -0,0 +1,431 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 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 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 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& 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr bodyFrame; + const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Body Data + std::array, BODY_COUNT> bodies = { nullptr }; + ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast( bodies.size() ), &bodies[0] ) ); + + Concurrency::parallel_for( 0, BODY_COUNT, [&]( const int count ){ + const ComPtr 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 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& result = results[count]; + result.clear(); + + // Retrieve Gesture Frame + ComPtr 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& 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& gestureFrame, const ComPtr& gesture ) +{ + // Retrieve Discrete Gesture Result + ComPtr 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& gestureFrame, const ComPtr& gesture ) +{ + // Retrieve Continuous Gesture Result + ComPtr 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& 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& 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& 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/app.h b/Kinect2Sample-master/sample/Gesture/app.h new file mode 100644 index 0000000..2dc2559 --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/app.h @@ -0,0 +1,114 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + std::array, BODY_COUNT> gestureFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Gesture Buffer + std::vector> gestures; + std::array, BODY_COUNT> results; + + std::array 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& gestureFrame, const ComPtr& gesture ); + + // Retrieve Continuous Gesture Result + inline std::string retrieveContinuousGestureResult( const ComPtr& gestureFrame, const ComPtr& gesture ); + + // Retrive Gesture Name + inline std::string gesture2string( const ComPtr& 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& 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/main.cpp b/Kinect2Sample-master/sample/Gesture/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Gesture/util.h b/Kinect2Sample-master/sample/Gesture/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Gesture/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/CMakeLists.txt b/Kinect2Sample-master/sample/HDFace/CMakeLists.txt new file mode 100644 index 0000000..648baff --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/HDFace/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/app.cpp b/Kinect2Sample-master/sample/HDFace/app.cpp new file mode 100644 index 0000000..50f9ba2 --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/app.cpp @@ -0,0 +1,478 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include +#define _USE_MATH_DEFINES +#include + +#include + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 bodyFrameSource; + ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) ); + ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) ); +} + +// Initialize HDFace +inline void Kinect::initializeHDFace() +{ + // Create HDFace Sources + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr bodyFrame; + const HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Body Data + std::array, BODY_COUNT> bodies; + ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( static_cast( bodies.size() ), &bodies[0] ) ); + + // Find Closest Body + findClosestBody( bodies ); +} + +// Find Closest Body +inline void Kinect::findClosestBody( const std::array, BODY_COUNT>& bodies ) +{ + float closestDistance = std::numeric_limits::max(); + for( int count = 0; count < BODY_COUNT; count++ ){ + const ComPtr body = bodies[count]; + BOOLEAN tracked; + ERROR_CHECK( body->get_IsTracked( &tracked ) ); + if( !tracked ){ + continue; + } + + // Retrieve Joint (Head) + std::array joints; + ERROR_CHECK( body->GetJoints( static_cast( joints.size() ), &joints[0] ) ); + const Joint joint = joints[JointType::JointType_Head]; + if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){ + continue; + } + + // Calculate Distance from Sensor ( ��( 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 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 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 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 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 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 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( point.X + 0.5f ); + const int y = static_cast( 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/app.h b/Kinect2Sample-master/sample/HDFace/app.h new file mode 100644 index 0000000..3d8d68a --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/app.h @@ -0,0 +1,122 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +#include + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + ComPtr hdFaceFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // HDFace Buffer + ComPtr faceModelBuilder; + ComPtr faceAlignment; + ComPtr faceModel; + std::array faceShapeUnits = { 0.0f }; + UINT32 vertexCount; + UINT64 trackingId; + int trackingCount = 0; + bool produced = false; + + std::array 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, 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 vertexes, const int radius, const cv::Vec3b& color, const int thickness = -1 ); + + // Show Data + void show(); + + // Show HDFace + inline void showHDFace(); +}; + +#endif // __APP__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/main.cpp b/Kinect2Sample-master/sample/HDFace/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/HDFace/util.h b/Kinect2Sample-master/sample/HDFace/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/HDFace/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/CMakeLists.txt b/Kinect2Sample-master/sample/Infrared/CMakeLists.txt new file mode 100644 index 0000000..51c45b6 --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Infrared/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/app.cpp b/Kinect2Sample-master/sample/Infrared/app.cpp new file mode 100644 index 0000000..845e4d6 --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/app.cpp @@ -0,0 +1,161 @@ +#include "app.h" +#include "util.h" + +#include +#include + +// 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 infraredFrameSource; + ERROR_CHECK( kinect->get_InfraredFrameSource( &infraredFrameSource ) ); + ERROR_CHECK( infraredFrameSource->OpenReader( &infraredFrameReader ) ); + + // Retrieve Infrared Description + ComPtr 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 infraredFrame; + const HRESULT ret = infraredFrameReader->AcquireLatestFrame( &infraredFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Infrared Data + ERROR_CHECK( infraredFrame->CopyFrameDataToArray( static_cast( 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 &p, const int* position ){ + p = infraredMat.at( position[0], position[1] ) >> 8; + }); + + // Show Image + cv::imshow( "Infrared", scaleMat ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/app.h b/Kinect2Sample-master/sample/Infrared/app.h new file mode 100644 index 0000000..262c94d --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/app.h @@ -0,0 +1,71 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr infraredFrameReader; + + // Infrared Buffer + std::vector 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/main.cpp b/Kinect2Sample-master/sample/Infrared/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Infrared/util.h b/Kinect2Sample-master/sample/Infrared/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Infrared/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/CMakeLists.txt b/Kinect2Sample-master/sample/Inpaint/CMakeLists.txt new file mode 100644 index 0000000..61336af --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Inpaint/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/app.cpp b/Kinect2Sample-master/sample/Inpaint/app.cpp new file mode 100644 index 0000000..49d8ec6 --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/app.cpp @@ -0,0 +1,377 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include + +// 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(); + + // Inpaint Depth + inpaintDepth(); + + // 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth() +{ + // Retrieve Depth Frame + ComPtr depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( 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 colorSpacePoints( depthWidth * depthHeight ); + ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) ); + + // Mapping Color to Depth Resolution + std::vector 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( colorSpacePoints[depthIndex].X + 0.5f ); + const int colorY = static_cast( 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 depthSpacePoints( colorWidth * colorHeight ); + ERROR_CHECK( coordinateMapper->MapColorFrameToDepthSpace( depthBuffer.size(), &depthBuffer[0], depthSpacePoints.size(), &depthSpacePoints[0] ) ); + + // Mapping Depth to Color Resolution + std::vector 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( depthSpacePoints[colorIndex].X + 0.5f ); + const int depthY = static_cast( 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 +} + +// Inpaint Depth +void Kinect::inpaintDepth() +{ + if( depthMat.empty() ){ + return; + } + + // Create Inpaint Mask ( This mask is area where depth couldn't be retrieved becauses shadow, noise, or outside of range. ) + cv::Mat maskMat; + cv::threshold( depthMat, maskMat, 500, std::numeric_limits::max(), cv::THRESH_BINARY_INV ); + maskMat.convertTo( maskMat, CV_8U, 255.0 / std::numeric_limits::max() ); + +#ifdef COLOR + // Scale Down + const double scale = 0.3; + cv::Mat resizeDepthMat; + cv::Mat resizeMaskMat; + cv::resize( depthMat, resizeDepthMat, cv::Size(), scale, scale ); + cv::resize( maskMat, resizeMaskMat, cv::Size(), scale, scale ); + + // Inpaint Depth + const double radius = 5.0; + cv::inpaint( resizeDepthMat, resizeMaskMat, inpaintMat, radius, cv::INPAINT_NS ); + + // Scale Up + cv::resize( inpaintMat, inpaintMat, depthMat.size() ); + + // Add Copy + cv::Mat tmpMat = depthMat.clone(); + inpaintMat.copyTo( tmpMat, maskMat ); + inpaintMat = tmpMat.clone(); +#else + // Inpaint Depth + const double radius = 5.0; + cv::inpaint( depthMat, maskMat, inpaintMat, radius, cv::INPAINT_NS ); +#endif +} + +// Show Data +void Kinect::show() +{ + // Show Color + showColor(); + + // Show Depth + showDepth(); + + // Show Inpaint + showInpaint(); +} + +// 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 +} + +// Show Inpaint +inline void Kinect::showInpaint() +{ + if( inpaintMat.empty() ){ + return; + } + + // Scaling ( 0-8000 -> 255-0 ) + cv::Mat scaleMat; + inpaintMat.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( "Inpaint", resizeMat ); +#else + // Show Image + cv::imshow( "Inpaint", scaleMat ); +#endif +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/app.h b/Kinect2Sample-master/sample/Inpaint/app.h new file mode 100644 index 0000000..8cc58e2 --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/app.h @@ -0,0 +1,103 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr depthFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Depth Buffer + std::vector depthBuffer; + int depthWidth; + int depthHeight; + unsigned int depthBytesPerPixel; + cv::Mat depthMat; + + // Inpaint Buffer + cv::Mat inpaintMat; + +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(); + + // Inpaint Depth + void inpaintDepth(); + + // Show Data + void show(); + + // Show Color + inline void showColor(); + + // Show Depth + inline void showDepth(); + + // Show Inpaint + inline void showInpaint(); +}; + +#endif // __APP__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/main.cpp b/Kinect2Sample-master/sample/Inpaint/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Inpaint/util.h b/Kinect2Sample-master/sample/Inpaint/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Inpaint/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/CMakeLists.txt b/Kinect2Sample-master/sample/JointSmooth/CMakeLists.txt new file mode 100644 index 0000000..d3b1916 --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required( VERSION 3.6 ) + +# Create Project +project( Sample ) +add_executable( JointSmooth app.h app.cpp main.cpp util.h KinectJointFilter.h KinectJointFilter.cpp ) + +# Set StartUp Project +set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "JointSmooth" ) + +# 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( JointSmooth ${KinectSDK2_LIBRARIES} ) + target_link_libraries( JointSmooth ${OpenCV_LIBS} ) +endif() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/JointSmooth/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.cpp b/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.cpp new file mode 100644 index 0000000..5b081f7 --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.cpp @@ -0,0 +1,189 @@ +//-------------------------------------------------------------------------------------- +// KinectJointFilter.cpp +// +// This file contains Holt Double Exponential Smoothing filter for filtering Joints +// +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +//#include "stdafx.h" +#include "KinectJointFilter.h" + +using namespace Sample; +using namespace DirectX; + +//------------------------------------------------------------------------------------- +// Name: Lerp() +// Desc: Linear interpolation between two floats +//------------------------------------------------------------------------------------- +inline FLOAT Lerp( FLOAT f1, FLOAT f2, FLOAT fBlend ) +{ + return f1 + ( f2 - f1 ) * fBlend; +} + +//-------------------------------------------------------------------------------------- +// if joint is 0 it is not valid. +//-------------------------------------------------------------------------------------- +inline BOOL JointPositionIsValid( XMVECTOR vJointPosition ) +{ + return ( XMVectorGetX( vJointPosition ) != 0.0f || + XMVectorGetY( vJointPosition ) != 0.0f || + XMVectorGetZ( vJointPosition ) != 0.0f ); +} + +//-------------------------------------------------------------------------------------- +// Implementation of a Holt Double Exponential Smoothing filter. The double exponential +// smooths the curve and predicts. There is also noise jitter removal. And maximum +// prediction bounds. The paramaters are commented in the init function. +//-------------------------------------------------------------------------------------- +void FilterDoubleExponential::Update( IBody* const pBody ) +{ + assert( pBody ); + + // Check for divide by zero. Use an epsilon of a 10th of a millimeter + m_fJitterRadius = XMMax( 0.0001f, m_fJitterRadius ); + + TRANSFORM_SMOOTH_PARAMETERS SmoothingParams; + + UINT jointCapacity = 0; + Joint joints[JointType_Count]; + + pBody->GetJoints( jointCapacity, joints ); + for( INT i = 0; i < JointType_Count; i++ ) + { + SmoothingParams.fSmoothing = m_fSmoothing; + SmoothingParams.fCorrection = m_fCorrection; + SmoothingParams.fPrediction = m_fPrediction; + SmoothingParams.fJitterRadius = m_fJitterRadius; + SmoothingParams.fMaxDeviationRadius = m_fMaxDeviationRadius; + + // If inferred, we smooth a bit more by using a bigger jitter radius + Joint joint = joints[i]; + if( joint.TrackingState == TrackingState::TrackingState_Inferred ) + { + SmoothingParams.fJitterRadius *= 2.0f; + SmoothingParams.fMaxDeviationRadius *= 2.0f; + } + + Update( joints, i, SmoothingParams ); + } +} + +void FilterDoubleExponential::Update( Joint joints[] ) +{ + // Check for divide by zero. Use an epsilon of a 10th of a millimeter + m_fJitterRadius = XMMax( 0.0001f, m_fJitterRadius ); + + TRANSFORM_SMOOTH_PARAMETERS SmoothingParams; + for( INT i = 0; i < JointType_Count; i++ ) + { + SmoothingParams.fSmoothing = m_fSmoothing; + SmoothingParams.fCorrection = m_fCorrection; + SmoothingParams.fPrediction = m_fPrediction; + SmoothingParams.fJitterRadius = m_fJitterRadius; + SmoothingParams.fMaxDeviationRadius = m_fMaxDeviationRadius; + + // If inferred, we smooth a bit more by using a bigger jitter radius + Joint joint = joints[i]; + if( joint.TrackingState == TrackingState::TrackingState_Inferred ) + { + SmoothingParams.fJitterRadius *= 2.0f; + SmoothingParams.fMaxDeviationRadius *= 2.0f; + } + + Update( joints, i, SmoothingParams ); + } + +} + +void FilterDoubleExponential::Update( Joint joints[], UINT JointID, TRANSFORM_SMOOTH_PARAMETERS smoothingParams ) +{ + XMVECTOR vPrevRawPosition; + XMVECTOR vPrevFilteredPosition; + XMVECTOR vPrevTrend; + XMVECTOR vRawPosition; + XMVECTOR vFilteredPosition; + XMVECTOR vPredictedPosition; + XMVECTOR vDiff; + XMVECTOR vTrend; + XMVECTOR vLength; + FLOAT fDiff; + BOOL bJointIsValid; + + const Joint joint = joints[JointID]; + + vRawPosition = XMVectorSet( joint.Position.X, joint.Position.Y, joint.Position.Z, 0.0f ); + vPrevFilteredPosition = m_pHistory[JointID].m_vFilteredPosition; + vPrevTrend = m_pHistory[JointID].m_vTrend; + vPrevRawPosition = m_pHistory[JointID].m_vRawPosition; + bJointIsValid = JointPositionIsValid( vRawPosition ); + + // If joint is invalid, reset the filter + if( !bJointIsValid ) + { + m_pHistory[JointID].m_dwFrameCount = 0; + } + + // Initial start values + if( m_pHistory[JointID].m_dwFrameCount == 0 ) + { + vFilteredPosition = vRawPosition; + vTrend = XMVectorZero(); + m_pHistory[JointID].m_dwFrameCount++; + } + else if( m_pHistory[JointID].m_dwFrameCount == 1 ) + { + vFilteredPosition = XMVectorScale( XMVectorAdd( vRawPosition, vPrevRawPosition ), 0.5f ); + vDiff = XMVectorSubtract( vFilteredPosition, vPrevFilteredPosition ); + vTrend = XMVectorAdd( XMVectorScale( vDiff, smoothingParams.fCorrection ), XMVectorScale( vPrevTrend, 1.0f - smoothingParams.fCorrection ) ); + m_pHistory[JointID].m_dwFrameCount++; + } + else + { + // First apply jitter filter + vDiff = XMVectorSubtract( vRawPosition, vPrevFilteredPosition ); + vLength = XMVector3Length( vDiff ); + fDiff = fabs( XMVectorGetX( vLength ) ); + + if( fDiff <= smoothingParams.fJitterRadius ) + { + vFilteredPosition = XMVectorAdd( XMVectorScale( vRawPosition, fDiff / smoothingParams.fJitterRadius ), + XMVectorScale( vPrevFilteredPosition, 1.0f - fDiff / smoothingParams.fJitterRadius ) ); + } + else + { + vFilteredPosition = vRawPosition; + } + + // Now the double exponential smoothing filter + vFilteredPosition = XMVectorAdd( XMVectorScale( vFilteredPosition, 1.0f - smoothingParams.fSmoothing ), + XMVectorScale( XMVectorAdd( vPrevFilteredPosition, vPrevTrend ), smoothingParams.fSmoothing ) ); + + + vDiff = XMVectorSubtract( vFilteredPosition, vPrevFilteredPosition ); + vTrend = XMVectorAdd( XMVectorScale( vDiff, smoothingParams.fCorrection ), XMVectorScale( vPrevTrend, 1.0f - smoothingParams.fCorrection ) ); + } + + // Predict into the future to reduce latency + vPredictedPosition = XMVectorAdd( vFilteredPosition, XMVectorScale( vTrend, smoothingParams.fPrediction ) ); + + // Check that we are not too far away from raw data + vDiff = XMVectorSubtract( vPredictedPosition, vRawPosition ); + vLength = XMVector3Length( vDiff ); + fDiff = fabs( XMVectorGetX( vLength ) ); + + if( fDiff > smoothingParams.fMaxDeviationRadius ) + { + vPredictedPosition = XMVectorAdd( XMVectorScale( vPredictedPosition, smoothingParams.fMaxDeviationRadius / fDiff ), + XMVectorScale( vRawPosition, 1.0f - smoothingParams.fMaxDeviationRadius / fDiff ) ); + } + + // Save the data from this frame + m_pHistory[JointID].m_vRawPosition = vRawPosition; + m_pHistory[JointID].m_vFilteredPosition = vFilteredPosition; + m_pHistory[JointID].m_vTrend = vTrend; + + // Output the data + m_pFilteredJoints[JointID] = vPredictedPosition; + m_pFilteredJoints[JointID] = XMVectorSetW( m_pFilteredJoints[JointID], 1.0f ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.h b/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.h new file mode 100644 index 0000000..a8f4c5c --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/KinectJointFilter.h @@ -0,0 +1,83 @@ +//-------------------------------------------------------------------------------------- +// KinectJointFilter.h +// +// This file contains Holt Double Exponential Smoothing filter for filtering Joints +// +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include +#include + +namespace Sample +{ + typedef struct _TRANSFORM_SMOOTH_PARAMETERS + { + FLOAT fSmoothing; // [0..1], lower values closer to raw data + FLOAT fCorrection; // [0..1], lower values slower to correct towards the raw data + FLOAT fPrediction; // [0..n], the number of frames to predict into the future + FLOAT fJitterRadius; // The radius in meters for jitter reduction + FLOAT fMaxDeviationRadius; // The maximum radius in meters that filtered positions are allowed to deviate from raw data + } TRANSFORM_SMOOTH_PARAMETERS; + + // Holt Double Exponential Smoothing filter + class FilterDoubleExponentialData + { + public: + DirectX::XMVECTOR m_vRawPosition; + DirectX::XMVECTOR m_vFilteredPosition; + DirectX::XMVECTOR m_vTrend; + DWORD m_dwFrameCount; + }; + + class FilterDoubleExponential + { + public: + FilterDoubleExponential() { Init(); } + ~FilterDoubleExponential() { Shutdown(); } + + void Init( FLOAT fSmoothing = 0.25f, FLOAT fCorrection = 0.25f, FLOAT fPrediction = 0.25f, FLOAT fJitterRadius = 0.03f, FLOAT fMaxDeviationRadius = 0.05f ) + { + Reset( fSmoothing, fCorrection, fPrediction, fJitterRadius, fMaxDeviationRadius ); + } + + void Shutdown() + { + } + + void Reset( FLOAT fSmoothing = 0.25f, FLOAT fCorrection = 0.25f, FLOAT fPrediction = 0.25f, FLOAT fJitterRadius = 0.03f, FLOAT fMaxDeviationRadius = 0.05f ) + { + assert( m_pFilteredJoints ); + assert( m_pHistory ); + + m_fMaxDeviationRadius = fMaxDeviationRadius; // Size of the max prediction radius Can snap back to noisy data when too high + m_fSmoothing = fSmoothing; // How much smothing will occur. Will lag when too high + m_fCorrection = fCorrection; // How much to correct back from prediction. Can make things springy + m_fPrediction = fPrediction; // Amount of prediction into the future to use. Can over shoot when too high + m_fJitterRadius = fJitterRadius; // Size of the radius where jitter is removed. Can do too much smoothing when too high + + memset( m_pFilteredJoints, 0, sizeof( DirectX::XMVECTOR ) * JointType_Count ); + memset( m_pHistory, 0, sizeof( FilterDoubleExponentialData ) * JointType_Count ); + } + + void Update( IBody* const pBody ); + void Update( Joint joints[] ); + + inline const DirectX::XMVECTOR* GetFilteredJoints() const { return &m_pFilteredJoints[0]; } + + private: + DirectX::XMVECTOR m_pFilteredJoints[JointType_Count]; + FilterDoubleExponentialData m_pHistory[JointType_Count]; + FLOAT m_fSmoothing; + FLOAT m_fCorrection; + FLOAT m_fPrediction; + FLOAT m_fJitterRadius; + FLOAT m_fMaxDeviationRadius; + + void Update( Joint joints[], UINT JointID, TRANSFORM_SMOOTH_PARAMETERS smoothingParams ); + }; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/app.cpp b/Kinect2Sample-master/sample/JointSmooth/app.cpp new file mode 100644 index 0000000..503647d --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/app.cpp @@ -0,0 +1,371 @@ +#include "app.h" +#include "util.h" + +#include +#include + +#include + +// Joint Smoothing +#define SMOOTH + +// 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 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 ); + } ); + +#ifdef SMOOTH + // Set Smoothing Fileter Parameters + Sample::TRANSFORM_SMOOTH_PARAMETERS smoothingParams; + smoothingParams.fSmoothing = 0.25f; // [0..1], lower values closer to raw data + smoothingParams.fCorrection = 0.25f; // [0..1], lower values slower to correct towards the raw data + smoothingParams.fPrediction = 0.25f; // [0..n], the number of frames to predict into the future + smoothingParams.fJitterRadius = 0.03f; // The radius in meters for jitter reduction + smoothingParams.fMaxDeviationRadius = 0.05f; // The maximum radius in meters that filtered positions are allowed to deviate from raw data + + // Create Holt Double Exponential Smoothing Filter + for( Sample::FilterDoubleExponential filter : filters ){ + filter.Init( smoothingParams.fSmoothing, smoothingParams.fCorrection, smoothingParams.fPrediction, smoothingParams.fJitterRadius, smoothingParams.fMaxDeviationRadius ); + } +#endif + + // 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Body +inline void Kinect::updateBody() +{ + // Retrieve Body Frame + ComPtr 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( BODY_COUNT, &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 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 joints; + ERROR_CHECK( body->GetJoints( JointType::JointType_Count, &joints[0] ) ); + +#ifdef SMOOTH + // Update Joints + Sample::FilterDoubleExponential filter = filters[count]; + filter.Update( &joints[0] ); + + // Retrive Filtered Joints + const DirectX::XMVECTOR* filteredJoints = filter.GetFilteredJoints(); +#endif + + Concurrency::parallel_for( 0, static_cast( JointType::JointType_Count ), [&]( const int type ){ + // Check Joint Tracked + Joint joint = joints[type]; + if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){ + return; + } + +#ifdef SMOOTH + // Retrive Filtered Joint + const DirectX::XMVECTOR filteredJoint = filteredJoints[type]; + DirectX::XMVectorGetXPtr( &joint.Position.X, filteredJoint ); + DirectX::XMVectorGetYPtr( &joint.Position.Y, filteredJoint ); + DirectX::XMVectorGetZPtr( &joint.Position.Z, filteredJoint ); +#endif + + // 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 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( colorSpacePoint.X + 0.5f ); + const int y = static_cast( 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( 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( "JointSmooth", resizeMat ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/app.h b/Kinect2Sample-master/sample/JointSmooth/app.h new file mode 100644 index 0000000..fee9d34 --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/app.h @@ -0,0 +1,105 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +// Quote from MSDN Forums - Joint Smoothing code, and Partial Modification +// KinectJointFilter is: Copyright (c) Microsoft Corporation. All rights reserved. +// https://social.msdn.microsoft.com/Forums/en-US/045b058a-ae3a-4d01-beb6-b756631b4b42 +#include "KinectJointFilter.h" +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr bodyFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Body Buffer + std::array bodies = { nullptr }; + std::array colors; + + // Smoothing Filter + std::array filters; + +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 Smooth + inline void drawSmooth(); + + // 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/main.cpp b/Kinect2Sample-master/sample/JointSmooth/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/JointSmooth/util.h b/Kinect2Sample-master/sample/JointSmooth/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/JointSmooth/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/CMakeLists.txt b/Kinect2Sample-master/sample/MultiSource/CMakeLists.txt new file mode 100644 index 0000000..d064bb0 --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required( VERSION 3.6 ) + +# Create Project +project( Sample ) +add_executable( MultiSource app.h app.cpp main.cpp util.h ) + +# Set StartUp Project +set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "MultiSource" ) + +# 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( MultiSource ${KinectSDK2_LIBRARIES} ) + target_link_libraries( MultiSource ${OpenCV_LIBS} ) +endif() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/MultiSource/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/app.cpp b/Kinect2Sample-master/sample/MultiSource/app.cpp new file mode 100644 index 0000000..e2945a9 --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/app.cpp @@ -0,0 +1,268 @@ +#include "app.h" +#include "util.h" + +#include +#include + +// 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 Multi Source + initializeMultiSource(); + + // 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 )" ); + } +} + +// Initialize Multi Source +inline void Kinect::initializeMultiSource() +{ + // Open Multi Source Reader + DWORD types = FrameSourceTypes::FrameSourceTypes_Color + | FrameSourceTypes::FrameSourceTypes_Depth; + + ERROR_CHECK( kinect->OpenMultiSourceFrameReader( types, &multiSourceFrameReader ) ); +} + +// Initialize Color +inline void Kinect::initializeColor() +{ + // Open Color Reader + ComPtr colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + + // Retrieve Depth Description + ComPtr 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() +{ + // Retrieve Multi Source Frame + ComPtr multiSourceFrame; + const HRESULT ret = multiSourceFrameReader->AcquireLatestFrame( &multiSourceFrame ); + if( FAILED( ret ) ){ + return; + } + + // Update Color + updateColor( multiSourceFrame ); + + // Update Depth + updateDepth( multiSourceFrame ); +} + +// Update Color +inline void Kinect::updateColor( const ComPtr& multiSourceFrame ) +{ + if( multiSourceFrame == nullptr ){ + return; + } + + // Retrieve Color Frame Reference + ComPtr colorFrameReference; + HRESULT ret = multiSourceFrame->get_ColorFrameReference( &colorFrameReference ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Color Frame + ComPtr colorFrame; + ret = colorFrameReference->AcquireFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth( const ComPtr& multiSourceFrame ) +{ + if( multiSourceFrame == nullptr ){ + return; + } + + // Retrieve Depth Frame Reference + ComPtr depthFrameReference; + HRESULT ret = multiSourceFrame->get_DepthFrameReference( &depthFrameReference ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Frame + ComPtr depthFrame; + ret = depthFrameReference->AcquireFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( depthBuffer.size() ), &depthBuffer[0] ) ); +} + +// Draw Data +void Kinect::draw() +{ + // Draw Color + drawColor(); + + // Draw Depth + drawDepth(); +} + +// Draw Color +inline void Kinect::drawColor() +{ + // Create cv::Mat from Color Buffer + colorMat = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] ); +} + +// 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 Color + showColor(); + + // Show Depth + showDepth(); +} + +// 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 ); +} + +// 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 ); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/app.h b/Kinect2Sample-master/sample/MultiSource/app.h new file mode 100644 index 0000000..f38a66d --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/app.h @@ -0,0 +1,93 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Reader + ComPtr multiSourceFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Depth Buffer + std::vector 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 Multi Source + inline void initializeMultiSource(); + + // Initialize Color + inline void initializeColor(); + + // Initialize Depth + inline void initializeDepth(); + + // Finalize + void finalize(); + + // Update Data + void update(); + + // Update Color + inline void updateColor( const ComPtr& multiSourceFrame ); + + // Update Depth + inline void updateDepth( const ComPtr& multiSourceFrame ); + + // 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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/main.cpp b/Kinect2Sample-master/sample/MultiSource/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/MultiSource/util.h b/Kinect2Sample-master/sample/MultiSource/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/MultiSource/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/CMakeLists.txt b/Kinect2Sample-master/sample/PointCloud/CMakeLists.txt new file mode 100644 index 0000000..90f4d53 --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required( VERSION 3.6 ) + +# Create Project +project( Sample ) +add_executable( PointCloud app.h app.cpp main.cpp util.h ) + +# Set StartUp Project +set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "PointCloud" ) + +# 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 ) + +# Required Viz Module +if( OpenCV_FOUND ) + if( NOT "opencv_viz" IN_LIST OpenCV_LIBS ) + message( FATAL_ERROR "not found opencv_viz 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( PointCloud ${KinectSDK2_LIBRARIES} ) + target_link_libraries( PointCloud ${OpenCV_LIBS} ) +endif() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/PointCloud/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/app.cpp b/Kinect2Sample-master/sample/PointCloud/app.cpp new file mode 100644 index 0000000..849bd71 --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/app.cpp @@ -0,0 +1,304 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include +#include +#include + +#include + +// Constructor +Kinect::Kinect() +{ + // Initialize + initialize(); +} + +// Destructor +Kinect::~Kinect() +{ + // Finalize + finalize(); +} + +// Processing +void Kinect::run() +{ + // Main Loop + while( !viewer.wasStopped() ){ + // Update Data + update(); + + // Draw Data + draw(); + + // Show Data + show(); + + // Wait a Few Time + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } +} + +// Initialize +void Kinect::initialize() +{ + cv::setUseOptimized( true ); + + // Initialize Sensor + initializeSensor(); + + // Initialize Color + initializeColor(); + + // Initialize Depth + initializeDepth(); + + // Initialize Point Cloud + initializePointCloud(); + + // 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 colorFrameSource; + ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) ); + ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) ); + + // Retrieve Color Description + ComPtr 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 depthFrameSource; + ERROR_CHECK( kinect->get_DepthFrameSource( &depthFrameSource ) ); + ERROR_CHECK( depthFrameSource->OpenReader( &depthFrameReader ) ); + + // Retrieve Depth Description + ComPtr 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 Point Cloud +inline void Kinect::initializePointCloud() +{ + // Create Window + viewer = cv::viz::Viz3d( "Point Cloud" ); + + // Register Keyboard Callback Function + viewer.registerKeyboardCallback( &keyboardCallback, this ); + + // Show Coordinate System + viewer.showWidget( "CoordinateSystem", cv::viz::WCameraPosition::WCameraPosition( 0.5 ) ); +} + +// Keyboard Callback Function +void Kinect::keyboardCallback( const cv::viz::KeyboardEvent& event, void* cookie ) +{ + // Exit Viewer when Pressed ESC key + if( event.code == VK_ESCAPE && event.action == cv::viz::KeyboardEvent::Action::KEY_DOWN ){ + // Retrieve Viewer + cv::viz::Viz3d viewer = static_cast( cookie )->viewer; + + // Close Viewer + viewer.close(); + } + // Save Point Cloud to File when Pressed 's' key + else if( event.code == 's' && event.action == cv::viz::KeyboardEvent::Action::KEY_DOWN ){ + // Retrieve Point Cloud and Color + cv::Mat cloud = static_cast( cookie )->cloudMat; + cv::Mat color = static_cast( cookie )->colorMat; + + // Generate File Name + static int i = 0; + std::ostringstream oss; + oss << std::setfill( '0' ) << std::setw( 3 ) << i++; + std::string file = oss.str() + ".ply"; + + // Write Point Cloud to File + cv::viz::writeCloud( file, cloud, color, cv::noArray(), false ); + } +}; + +// Finalize +void Kinect::finalize() +{ + cv::viz::unregisterAllWindows(); + + // 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 colorFrame; + const HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame ); + if( FAILED( ret ) ){ + return; + } + + // Convert Format ( YUY2 -> BGRA ) + ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast( colorBuffer.size() ), &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra ) ); +} + +// Update Depth +inline void Kinect::updateDepth() +{ + // Retrieve Depth Frame + ComPtr depthFrame; + const HRESULT ret = depthFrameReader->AcquireLatestFrame( &depthFrame ); + if( FAILED( ret ) ){ + return; + } + + // Retrieve Depth Data + ERROR_CHECK( depthFrame->CopyFrameDataToArray( static_cast( depthBuffer.size() ), &depthBuffer[0] ) ); +} + +// Draw Data +void Kinect::draw() +{ + // Draw Color + drawColor(); + + // Draw Point Cloud + drawPointCloud(); +} + +// Draw Color +inline void Kinect::drawColor() +{ + // Retrieve Mapped Coordinates + std::vector colorSpacePoints( depthWidth * depthHeight ); + ERROR_CHECK( coordinateMapper->MapDepthFrameToColorSpace( depthBuffer.size(), &depthBuffer[0], colorSpacePoints.size(), &colorSpacePoints[0] ) ); + + // Mapping Color to Depth Resolution + std::vector 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( colorSpacePoints[depthIndex].X + 0.5f ); + const int colorY = static_cast( 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(); +} + +// Draw Point Cloud +inline void Kinect::drawPointCloud() +{ + // Retrieve Mapped Coordinates + std::vector cameraSpacePoints( depthWidth * depthHeight ); + ERROR_CHECK( coordinateMapper->MapDepthFrameToCameraSpace( depthBuffer.size(), &depthBuffer[0], cameraSpacePoints.size(), &cameraSpacePoints[0] ) ); + + // Mapping Color to Depth Resolution + std::vector buffer( depthWidth * depthHeight, cv::Vec3f::all( std::numeric_limits::quiet_NaN() ) ); + + 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; + UINT16 depth = depthBuffer[depthIndex]; + if( 500 <= depth && depth < 8000 ){ + CameraSpacePoint cameraSpacePoint = cameraSpacePoints[depthIndex]; + buffer[depthIndex] = cv::Vec3f( cameraSpacePoint.X, cameraSpacePoint.Y, cameraSpacePoint.Z ); + } + } + } ); + + // Create cv::Mat from Coordinate Buffer + cloudMat = cv::Mat( depthHeight, depthWidth, CV_32FC3, &buffer[0] ).clone(); +} + +// Show Data +void Kinect::show() +{ + // Show Point Cloud + showPointCloud(); +} + +// Show Point Cloud +inline void Kinect::showPointCloud() +{ + if( colorMat.empty() ){ + return; + } + + if( cloudMat.empty() ){ + return; + } + + // Create Point Cloud + cv::viz::WCloud cloud( cloudMat, colorMat ); + + // Show Point Cloud + viewer.showWidget( "Cloud", cloud ); + viewer.spinOnce(); +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/app.h b/Kinect2Sample-master/sample/PointCloud/app.h new file mode 100644 index 0000000..74656a5 --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/app.h @@ -0,0 +1,101 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +#include +#include + +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Coordinate Mapper + ComPtr coordinateMapper; + + // Reader + ComPtr colorFrameReader; + ComPtr depthFrameReader; + + // Color Buffer + std::vector colorBuffer; + int colorWidth; + int colorHeight; + unsigned int colorBytesPerPixel; + cv::Mat colorMat; + + // Depth Buffer + std::vector depthBuffer; + int depthWidth; + int depthHeight; + unsigned int depthBytesPerPixel; + + // Point Cloud Buffer + cv::viz::Viz3d viewer; + cv::Mat cloudMat; + +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 Point Cloud + inline void initializePointCloud(); + + // Keyboard Callback Function + static void keyboardCallback( const cv::viz::KeyboardEvent& event, void* cookie ); + + // 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 Point Cloud + inline void drawPointCloud(); + + // Show Data + void show(); + + // Show Point Cloud + inline void showPointCloud(); +}; + +#endif // __APP__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/main.cpp b/Kinect2Sample-master/sample/PointCloud/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/PointCloud/util.h b/Kinect2Sample-master/sample/PointCloud/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/PointCloud/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/CMakeLists.txt b/Kinect2Sample-master/sample/Speech/CMakeLists.txt new file mode 100644 index 0000000..df17b1d --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required( VERSION 3.6 ) + +# Create Project +project( Sample ) +add_executable( Speech app.h app.cpp main.cpp util.h KinectAudioStream.h KinectAudioStream.cpp ) + +# Set StartUp Project +set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Speech" ) + +# Find Package +set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH} ) +find_package( KinectSDK2 REQUIRED ) + +find_package( SpeechPlatformSDK REQUIRED ) + +if( KinectSDK2_FOUND AND SpeechPlatformSDK_FOUND ) + # Additional Include Directories + include_directories( ${KinectSDK2_INCLUDE_DIRS} ) + include_directories( ${SpeechPlatformSDK_INCLUDE_DIRS} ) + + # Additional Library Directories + link_directories( ${KinectSDK2_LIBRARY_DIRS} ) + link_directories( ${SpeechPlatformSDK_LIBRARY_DIRS} ) + + # Additional Dependencies + target_link_libraries( Speech ${KinectSDK2_LIBRARIES} ) + target_link_libraries( Speech ${SpeechPlatformSDK_LIBRARIES} ) +endif() \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/FindKinectSDK2.cmake b/Kinect2Sample-master/sample/Speech/FindKinectSDK2.cmake new file mode 100644 index 0000000..00a2036 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/FindKinectSDK2.cmake @@ -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}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/FindSpeechPlatformSDK.cmake b/Kinect2Sample-master/sample/Speech/FindSpeechPlatformSDK.cmake new file mode 100644 index 0000000..8874de2 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/FindSpeechPlatformSDK.cmake @@ -0,0 +1,122 @@ +#.rst: +# FindSpeechPlatformSDK +# --------------------- +# +# Find Speech Platform SDK include dirs, library dirs, libraries +# +# Use this module by invoking find_package with the form:: +# +# find_package( SpeechPlatformSDK [REQUIRED] ) +# +# Results for users are reported in following variables:: +# +# SpeechPlatformSDK_FOUND - Return "TRUE" when Speech Platform SDK found. Otherwise, Return "FALSE". +# SpeechPlatformSDK_INCLUDE_DIRS - Speech Platform SDK include directories. ($(SpeechPlatformSDK_DIR)/Include) +# SpeechPlatformSDK_LIBRARY_DIRS - Speech Platform SDK library directories. ($(SpeechPlatformSDK_DIR)/Lib) +# SpeechPlatformSDK_LIBRARIES - Speech Platform SDK library files. ($(SpeechPlatformSDK_LIBRARY_DIRS)/sapi.lib) +# +# CMake entries:: +# +# SpeechPlatformSDK_DIR - Speech Platform SDK root directory. (Default $(ProgramFiles)/Microsoft SDKs/Speech/v11.0 or $(ProgramW6432)/Microsoft SDKs/Speech/v11.0) +# +# Example to find Speech Platform SDK:: +# +# cmake_minimum_required( VERSION 2.8 ) +# +# project( project ) +# add_executable( project main.cpp ) +# +# # Find package using this module. +# find_package( SpeechPlatformSDK REQUIRED ) +# +# if( SpeechPlatformSDK_FOUND ) +# # [C/C++]>[General]>[Additional Include Directories] +# include_directories( ${SpeechPlatformSDK_INCLUDE_DIRS} ) +# +# # [Linker]>[General]>[Additional Library Directories] +# link_directories( ${SpeechPlatformSDK_LIBRARY_DIRS} ) +# +# # [Linker]>[Input]>[Additional Dependencies] +# target_link_libraries( project ${SpeechPlatformSDK_LIBRARIES} ) +# 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(SpeechPlatformSDK_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(SpeechPlatformSDK_FOUND FALSE) + unset(_FILES) + endif() +endmacro() + +# Program Files +set(PROGRAMFILES) +if(NOT CMAKE_CL_64) + set(PROGRAMFILES $ENV{ProgramFiles}) +else() + set(PROGRAMFILES $ENV{ProgramW6432}) +endif() + +##### Find Speech Platform SDK ##### + +# Found +set(SpeechPlatformSDK_FOUND TRUE) + +# Root Directoty +set(SpeechPlatformSDK_DIR) +if(SpeechPlatformSDK_FOUND) + set(SpeechPlatformSDK_DIR ${PROGRAMFILES}/Microsoft\ SDKs/Speech/v11.0 CACHE PATH "Speech Platform SDK Install Path." FORCE) + check_dir(SpeechPlatformSDK_DIR) +endif() + +# Include Directories +set(SpeechPlatformSDK_INCLUDE_DIRS) +if(SpeechPlatformSDK_FOUND) + set(SpeechPlatformSDK_INCLUDE_DIRS ${SpeechPlatformSDK_DIR}/Include) + check_dir(SpeechPlatformSDK_INCLUDE_DIRS) +endif() + +# Library Directories +set(SpeechPlatformSDK_LIBRARY_DIRS) +if(SpeechPlatformSDK_FOUND) + set(SpeechPlatformSDK_LIBRARY_DIRS ${SpeechPlatformSDK_DIR}/Lib) + check_dir(SpeechPlatformSDK_LIBRARY_DIRS) +endif() + +# Dependencies +set(SpeechPlatformSDK_LIBRARIES) +if(SpeechPlatformSDK_FOUND) + set(SpeechPlatformSDK_LIBRARIES ${SpeechPlatformSDK_LIBRARY_DIRS}/sapi.lib) + check_files(SpeechPlatformSDK_LIBRARIES SpeechPlatformSDK_LIBRARY_DIRS) +endif() + +message(STATUS "SpeechPlatformSDK_FOUND : ${SpeechPlatformSDK_FOUND}") \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/Grammar_enUS.grxml b/Kinect2Sample-master/sample/Speech/Grammar_enUS.grxml new file mode 100644 index 0000000..efa2473 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/Grammar_enUS.grxml @@ -0,0 +1,32 @@ + + + + + RED + + Red + + + + GREEN + + Green + + + + BLUE + + Blue + + + + EXIT + + Exit + Quit + Stop + + + + + \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/Grammar_jaJP.grxml b/Kinect2Sample-master/sample/Speech/Grammar_jaJP.grxml new file mode 100644 index 0000000..333a587 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/Grammar_jaJP.grxml @@ -0,0 +1,34 @@ + + + + + RED + + + 赤色 + + + + GREEN + + + 緑色 + + + + BLUE + + + 青色 + + + + EXIT + + 終わり + 終了 + + + + + \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/KinectAudioStream.cpp b/Kinect2Sample-master/sample/Speech/KinectAudioStream.cpp new file mode 100644 index 0000000..a47a10e --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/KinectAudioStream.cpp @@ -0,0 +1,172 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implementation for KinectAudioStream methods. +// KinectAudioStream wraps the Kinect audio stream and does proper format +// conversion during read. +// +//------------------------------------------------------------------------------ + +//#include "stdafx.h" +#include "KinectAudioStream.h" + +#include + +/// +/// KinectAudioStream constructor. +/// +KinectAudioStream::KinectAudioStream(IStream *p32BitAudio) : + m_cRef(1), + m_p32BitAudio(p32BitAudio), + m_SpeechActive(false) + +{ +} + +/// +/// SetSpeechState method +/// +void KinectAudioStream::SetSpeechState(bool state) +{ + m_SpeechActive = state; +} + +///////////////////////////////////////////// +// IStream methods +__pragma(warning(push)) +__pragma(warning(disable:6101)) // Suppress warning about returning uninitialized memory *pBuffer. It is written correctly. +__pragma(warning(disable:6386)) // Suppress warning about buffer overrun while writing to 'pByteBuffer'. There are no overruns. +STDMETHODIMP KinectAudioStream::Read( + _Out_writes_bytes_to_(cbBuffer, *pcbRead) void *pBuffer, + _In_ ULONG cbBuffer, + _Out_opt_ ULONG *pcbRead) +{ + if (pBuffer == NULL || pcbRead == NULL || cbBuffer == 0) + { + return E_INVALIDARG; + } + + HRESULT hr = S_OK; + + // 32bit -> 16bit conversion support + INT16* p16Buffer = (INT16*)pBuffer; + int factor = sizeof(float)/sizeof(INT16); + + // 32 bit read support + float* p32Buffer = new float[cbBuffer/factor]; + byte* pByteBuffer = (byte*)p32Buffer; + ULONG bytesRead = 0; + ULONG bytesRemaining = cbBuffer * factor; + + // Speech reads at high frequency - this slows down the process + int sleepDuration = 50; + + // Speech Service isn't tolerant of partial reads + while (bytesRemaining > 0) + { + // Stop returning Audio data if Speech isn't active + if (!m_SpeechActive) + { + *pcbRead = 0; + hr = S_FALSE; + goto exit; + } + + // bytesRead will always be a multiple of 4 ( = sizeof(float)) + hr = m_p32BitAudio->Read(pByteBuffer, bytesRemaining, &bytesRead); + pByteBuffer += bytesRead; + bytesRemaining -= bytesRead; + + // All Audio buffers drained - wait for buffers to fill + if (bytesRemaining != 0) + { + Sleep(sleepDuration); + } + } + + // Convert float value [-1,1] to int16 [SHRT_MIN, SHRT_MAX] and copy to output butter + for (UINT i = 0; i < cbBuffer/factor; i++) + { + float sample = p32Buffer[i]; + + // Make sure it is in the range [-1, +1] + if (sample > 1.0f) + { + sample = 1.0f; + } + else if (sample < -1.0f) + { + sample = -1.0f; + } + + // Scale float to the range (SHRT_MIN, SHRT_MAX] and then + // convert to 16-bit signed with proper rounding + float sampleScaled = sample * (float)SHRT_MAX; + p16Buffer[i] = (sampleScaled > 0.f) ? (INT16)(sampleScaled + 0.5f) : (INT16)(sampleScaled - 0.5f); + } + + *pcbRead = cbBuffer; + +exit: + delete[] p32Buffer; + return hr; +} +__pragma(warning(pop)) + +STDMETHODIMP KinectAudioStream::Write(_In_reads_bytes_(cb) const void *pv, _In_ ULONG cb, _Out_opt_ ULONG *pcbWritten) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::Seek(LARGE_INTEGER /* dlibMove */, DWORD /* dwOrigin */, _Out_opt_ ULARGE_INTEGER *plibNewPosition) +{ + // Speech seeks and expects a seek implementation - but the NUIAudio stream doesn't support seeking + if (plibNewPosition != NULL) + { + plibNewPosition->QuadPart = 0; + } + + return S_OK; +} + +STDMETHODIMP KinectAudioStream::SetSize(ULARGE_INTEGER) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::CopyTo(_In_ IStream *, ULARGE_INTEGER, _Out_opt_ ULARGE_INTEGER *, _Out_opt_ ULARGE_INTEGER *) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::Commit(DWORD) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::Revert() +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::Stat(__RPC__out STATSTG *, DWORD) +{ + return E_NOTIMPL; +} + +STDMETHODIMP KinectAudioStream::Clone(__RPC__deref_out_opt IStream **) +{ + return E_NOTIMPL; +} diff --git a/Kinect2Sample-master/sample/Speech/KinectAudioStream.h b/Kinect2Sample-master/sample/Speech/KinectAudioStream.h new file mode 100644 index 0000000..7a9d318 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/KinectAudioStream.h @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Includes common headers and defines following classes: +// - KinectAudioStream: IStream implementation to convert 32Bit Kinect Stream to 16Bit for Speech. +// +//------------------------------------------------------------------------------ +#pragma once + +// For WAVEFORMATEX +#include +#include +#include + +/// +/// Asynchronous IStream implementation that captures audio data from Kinect audio sensor in a background thread +/// and lets clients read captured audio from any thread. +/// +class KinectAudioStream : public IStream +{ +public: + ///////////////////////////////////////////// + // KinectAudioStream methods + + /// + /// KinectAudioStream constructor. + /// + KinectAudioStream(IStream *p32BitAudioStream); + + /// + /// SetSpeechState method + /// + void SetSpeechState(bool state); + + ///////////////////////////////////////////// + // IUnknown methods + STDMETHODIMP_(ULONG) AddRef() { return InterlockedIncrement(&m_cRef); } + STDMETHODIMP_(ULONG) Release() + { + UINT ref = InterlockedDecrement(&m_cRef); + if (ref == 0) + { + delete this; + } + return ref; + } + STDMETHODIMP QueryInterface(REFIID riid, void **ppv) + { + if (riid == IID_IUnknown) + { + AddRef(); + *ppv = (IUnknown*)this; + return S_OK; + } + else if (riid == IID_IStream) + { + AddRef(); + *ppv = (IStream*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + + ///////////////////////////////////////////// + // IStream methods + STDMETHODIMP Read(_Out_writes_bytes_to_(cbBuffer, *pcbRead) void *pBuffer , _In_ ULONG cbBuffer, _Out_opt_ ULONG *pcbRead); + STDMETHODIMP Write(_In_reads_bytes_(cb) const void *pv, _In_ ULONG cb, _Out_opt_ ULONG *pcbWritten); + STDMETHODIMP Seek(LARGE_INTEGER, DWORD, _Out_opt_ ULARGE_INTEGER *); + STDMETHODIMP SetSize(ULARGE_INTEGER); + STDMETHODIMP CopyTo(_In_ IStream *, ULARGE_INTEGER, _Out_opt_ ULARGE_INTEGER *, _Out_opt_ ULARGE_INTEGER *); + STDMETHODIMP Commit(DWORD); + STDMETHODIMP Revert(); + STDMETHODIMP LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD); + STDMETHODIMP UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD); + STDMETHODIMP Stat(__RPC__out STATSTG *, DWORD); + STDMETHODIMP Clone(__RPC__deref_out_opt IStream **); + +private: + + // Number of references to this object + UINT m_cRef; + IStream* m_p32BitAudio; + bool m_SpeechActive; +}; \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/app.cpp b/Kinect2Sample-master/sample/Speech/app.cpp new file mode 100644 index 0000000..e041e27 --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/app.cpp @@ -0,0 +1,388 @@ +#include "app.h" +#include "util.h" + +#include +#include +#include + +#pragma warning(disable: 4996) // for error GetVersionExW() of sphelper.h +#include // for SpFindBestToken() +#include + +// Constructor +Kinect::Kinect() +{ + // Initialize + initialize(); +} + +// Destructor +Kinect::~Kinect() +{ + // Finalize + finalize(); +} + +// Processing +void Kinect::run() +{ + // Start Speech Recognition + start(); + + // Main Loop + while( true ){ + // Update Data + update(); + + // Draw Data + draw(); + + // Show Data + show(); + + // Key Check + if( GetKeyState( VK_ESCAPE ) < 0 || exit ){ + break; + } + } + + // Stop Speech Recognition + stop(); +} + +// Initialize +void Kinect::initialize() +{ + // Initialize Sensor + initializeSensor(); + + // Initialize Audio + initializeAudio(); + + // Initialize Speech Recognition + initializeSpeech(); + + // 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 audioSource; + ERROR_CHECK( kinect->get_AudioSource( &audioSource ) ); + + // Retrieve Audio Beam List + ComPtr audioBeamList; + ERROR_CHECK( audioSource->get_AudioBeams( &audioBeamList ) ); + + // Open Audio Beam + ERROR_CHECK( audioBeamList->OpenAudioBeam( 0, &audioBeam ) ); + + // Open Audio Input Stream and Create Audio Stream + ERROR_CHECK( audioBeam->OpenInputStream( &inputStream ) ); + audioStream = new KinectAudioStream( inputStream.Get() ); +} + +// Initialize Speech Recognition +inline void Kinect::initializeSpeech() +{ + CoInitialize( NULL ); + + // Initialize Speech Stream + initializeSpeechStream(); + + // Create Speech Recognizer + // "en-US" ... English, "ja-JP" ... Japanese + createSpeechRecognizer( "en-US" ); + + // Load Speech Recognition Grammar from Grammar File (*.grxml) + // Grammar ID, Grammar File Name + loadSpeechGrammar( 0, L"../Grammar_enUS.grxml" ); + /*loadSpeechGrammar( 1, L"../Grammar_Additional.grxml" );*/ + + CoUninitialize(); +} + +// Initialize Speech Stream +inline void Kinect::initializeSpeechStream() +{ + // Create Speech Stream Instance + CoCreateInstance( CLSID_SpStream, NULL, CLSCTX_INPROC_SERVER, __uuidof( ISpStream ), reinterpret_cast( speechStream.GetAddressOf() ) ); + + // Set Wave Format + WORD AudioFormat = WAVE_FORMAT_PCM; + WORD AudioChannels = 1; + DWORD AudioSamplesPerSecond = 16000; + DWORD AudioAverageBytesPerSecond = 32000; + WORD AudioBlockAlign = 2; + WORD AudioBitsPerSample = 16; + + WAVEFORMATEX waveFormat = { AudioFormat, AudioChannels, AudioSamplesPerSecond, AudioAverageBytesPerSecond, AudioBlockAlign, AudioBitsPerSample, 0 }; + + // Registration Base Stream + ERROR_CHECK( speechStream->SetBaseStream( audioStream.Get(), SPDFID_WaveFormatEx, &waveFormat ) ); +} + +// Create Speech Recognizer +inline void Kinect::createSpeechRecognizer( const std::string& language ) +{ + // Create Speech Recognizer Instance + ERROR_CHECK( CoCreateInstance( CLSID_SpInprocRecognizer, NULL, CLSCTX_INPROC_SERVER, __uuidof( ISpRecognizer ), reinterpret_cast( speechRecognizer.GetAddressOf() ) ) ); + + // Registration Input Stream + ERROR_CHECK( speechRecognizer->SetInput( speechStream.Get(), TRUE ) ); + + // Retrieve Language Attribute (Hexadecimal Value;Kinect Support) + // Kinect for Windows SDK 2.0 Language Packs http://www.microsoft.com/en-us/download/details.aspx?id=43662 + // L"Language=409;Kinect=True" ... English | United States (MSKinectLangPack_enUS.msi) + // L"Language=411;Kinect=True" ... Japanese | Japan (MSKinectLangPack_jaJP.msi) + // Other Languages Hexadecimal Value, Please see here https://msdn.microsoft.com/en-us/library/hh378476(v=office.14).aspx + std::wstring attribute; + if( language == "de-DE" ){ + attribute = L"Language=C07;Kinect=True"; + } + else if( language == "en-AU" ){ + attribute = L"Language=C09;Kinect=True"; + } + else if( language == "en-CA" ){ + attribute = L"Language=1009;Kinect=True"; + } + else if( language == "en-GB" ){ + attribute = L"Language=809;Kinect=True"; + } + else if( language == "en-IE" ){ + attribute = L"Language=1809;Kinect=True"; + } + else if( language == "en-NZ" ){ + attribute = L"Language=1409;Kinect=True"; + } + else if( language == "en-US" ){ + attribute = L"Language=409;Kinect=True"; + } + else if( language == "es-ES" ){ + attribute = L"Language=2C0A;Kinect=True"; + } + else if( language == "es-MX" ){ + attribute = L"Language=80A;Kinect=True"; + } + else if( language == "fr-CA" ){ + attribute = L"Language=C0C;Kinect=True"; + } + else if( language == "fr-FR" ){ + attribute = L"Language=40c;Kinect=True"; + } + else if( language == "it-IT" ){ + attribute = L"Language=410;Kinect=True"; + } + else if( language == "ja-JP" ){ + attribute = L"Language=411;Kinect=True"; + } + else{ + throw std::runtime_error( "failed " __FUNCTION__ ); + } + + // Set Local + setlocale( LC_CTYPE, language.c_str() ); + + // Retrieve and Registration Speech Recognizer Engine + CComPtr engineToken; + ERROR_CHECK( SpFindBestToken( SPCAT_RECOGNIZERS, attribute.c_str(), NULL, &engineToken ) ); + ERROR_CHECK( speechRecognizer->SetRecognizer( engineToken ) ); + + // Create Speech Recognizer Context + ERROR_CHECK( speechRecognizer->CreateRecoContext( &speechContext ) ); + + // Set Adaptation of Acoustic Model to OFF (0) + // (For Long Time (few hours~) Running Program of Speech Recognition) + ERROR_CHECK( speechRecognizer->SetPropertyNum( L"AdaptationOn", 0 ) ); +} + +// Load Speech Recognition Grammar from Grammar File (*.grxml) +inline void Kinect::loadSpeechGrammar( const ULONGLONG id, const std::wstring& grammar ) +{ + // Load Speech Recognition Grammar from Grammar File (*.grxml) + speechGrammar.push_back( nullptr ); + ERROR_CHECK( speechContext->CreateGrammar( id, &speechGrammar.back() ) ); + ERROR_CHECK( speechGrammar.back()->LoadCmdFromFile( grammar.c_str(), SPLOADOPTIONS::SPLO_STATIC ) ); +} + +// Finalize +void Kinect::finalize() +{ + // Close Sensor + if( kinect != nullptr ){ + kinect->Close(); + } +} + +// Start Speech Recognition +void Kinect::start() +{ + std::cout << "start speech recognition..." << std::endl; + + // Set Audio Input Stream to Start + audioStream->SetSpeechState( true ); + + // Set Speech Recognition Grammar to Enable + for( const ComPtr grammar : speechGrammar ){ + ERROR_CHECK( grammar->SetRuleState( NULL, NULL, SPRULESTATE::SPRS_ACTIVE ) ); + } + + // Set Recognition Status to Active + ERROR_CHECK( speechRecognizer->SetRecoState( SPRECOSTATE::SPRST_ACTIVE_ALWAYS ) ); + + // Set Event Generation Timing to Complete Speech Recognition + ERROR_CHECK( speechContext->SetInterest( SPFEI( SPEVENTENUM::SPEI_RECOGNITION ), SPFEI( SPEVENTENUM::SPEI_RECOGNITION ) ) ); + + // Set Speech Recognition to Resume + ERROR_CHECK( speechContext->Resume( 0 ) ); + + // Retrieve Speech Recognition Event Handle + speechEvent = speechContext->GetNotifyEventHandle(); +} + +// Stop Speech Recognition +void Kinect::stop() +{ + // Set Audio Input Strem to Stop + audioStream->SetSpeechState( false ); + + // Set Recognition Status to Inactive + ERROR_CHECK( speechRecognizer->SetRecoState( SPRECOSTATE::SPRST_INACTIVE_WITH_PURGE ) ); + + // Set Speech Recognition to Pause + ERROR_CHECK( speechContext->Pause( 0 ) ); + + // Close Speech Recognition Event Handle + CloseHandle( speechEvent ); +} + +// Update Data +void Kinect::update() +{ + // Update Speech + updateSpeech(); +} + +// Update Speech +inline void Kinect::updateSpeech() +{ + // Wait Speech Recognition Event + ResetEvent( speechEvent ); + const HANDLE events[1] = { speechEvent }; + objects = MsgWaitForMultipleObjectsEx( ARRAYSIZE( events ), events, 50, QS_ALLINPUT, MWMO_INPUTAVAILABLE ); +} + +// Draw Data +void Kinect::draw() +{ + // Draw Speech + drawSpeech(); +} + +// Draw Speech +inline void Kinect::drawSpeech() +{ + // Clear Recognition Result Buffer + recognizeResult.clear(); + + switch( objects ){ + // Raising Speech Recognition Event + case WAIT_OBJECT_0: + // Retrive Speech Recognition Result + result(); + break; + default: + break; + } +} + +// Retrive Speech Recognition Result +inline void Kinect::result() +{ + // Retrive Speech Recognition Event Status + SPEVENT eventStatus; + ULONG eventFetch; + ERROR_CHECK( speechContext->GetEvents( 1, &eventStatus, &eventFetch ) ); + + // Retrive Results + while( eventFetch > 0 ){ + switch( eventStatus.eEventId ){ + // Speech Recognition Event Status + case SPEVENTENUM::SPEI_RECOGNITION: + if( eventStatus.elParamType == SPET_LPARAM_IS_OBJECT ){ + // Retrive Speech Recognition Results + ComPtr speechResult = reinterpret_cast( eventStatus.lParam ); + + // Retrive Phrase + // PHRASE + SPPHRASE* phrase; + ERROR_CHECK( speechResult->GetPhrase( &phrase ) ); + const SPPHRASEPROPERTY* semantic = phrase->pProperties->pFirstChild; + const std::wstring tag = semantic->pszValue; + + // Retrive Text + // TEXT + wchar_t* text; + ERROR_CHECK( speechResult->GetText( SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, FALSE, &text, NULL ) ); + + // Check Speech Recognition Confidence + if( semantic->SREngineConfidence > confidenceThreshold ){ + // Add Phrase and Text to Result Buffer + recognizeResult = L"Phrase : " + tag + L"\t Text : " + text; + + // If Tag is "EXIT" Set Exit Flag to True + if( tag == L"EXIT" ){ + exit = true; + } + } + + // Release Memory + CoTaskMemFree( phrase ); + CoTaskMemFree( text ); + } + break; + default: + break; + } + ERROR_CHECK( speechContext->GetEvents( 1, &eventStatus, &eventFetch ) ); + } +} + +// Show Data +void Kinect::show() +{ + // Show Speech + showSpeech(); +} + +// Show Speech +inline void Kinect::showSpeech() +{ + // Check Empty Result Buffer + if( !recognizeResult.size() ){ + return; + } + + // Show Result + std::wcout << recognizeResult << std::endl; + +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/app.h b/Kinect2Sample-master/sample/Speech/app.h new file mode 100644 index 0000000..a4831be --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/app.h @@ -0,0 +1,102 @@ +#ifndef __APP__ +#define __APP__ + +#include +#include +// Quote from Kinect for Windows SDK v2.0 - Sample/Native/SpeechBasics-D2D +// KinectAudioStream.h and .cpp : Copyright (c) Microsoft Corporation. All rights reserved. +#include "KinectAudioStream.h" +#include + +#include +#include + +#include +using namespace Microsoft::WRL; + +class Kinect +{ +private: + // Sensor + ComPtr kinect; + + // Speech + ComPtr audioBeam; + ComPtr inputStream; + ComPtr audioStream; + ComPtr speechStream; + ComPtr speechRecognizer; + ComPtr speechContext; + std::vector> speechGrammar; + HANDLE speechEvent; + DWORD objects = 0; + + // Speech Buffer + std::wstring recognizeResult; + const float confidenceThreshold = 0.3f; + bool exit = false; + +public: + // Constructor + Kinect(); + + // Destructor + ~Kinect(); + + // Processing + void run(); + +private: + // Initialize + void initialize(); + + // Initialize Sensor + inline void initializeSensor(); + + // Initialize Audio + inline void initializeAudio(); + + // Initialize Speech + inline void initializeSpeech(); + + // Initialize Speech Stream + inline void initializeSpeechStream(); + + // Create Speech Recognizer + inline void createSpeechRecognizer( const std::string& language = "en-US" ); + + // Load Speech Recognition Grammar from Grammar File (*.grxml) + inline void loadSpeechGrammar( const ULONGLONG id, const std::wstring& grammar ); + + // Finalize + void finalize(); + + // Start Speech Recognition + void start(); + + // Stop Speech Recognition + void stop(); + + // Update Data + void update(); + + // Update Speech + inline void updateSpeech(); + + // Draw Data + void draw(); + + // Draw Speech + inline void drawSpeech(); + + // Retrive Speech Recognition Result + inline void result(); + + // Show Data + void show(); + + // Show Speech + inline void showSpeech(); +}; + +#endif // __APP__ \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/main.cpp b/Kinect2Sample-master/sample/Speech/main.cpp new file mode 100644 index 0000000..d88643c --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/main.cpp @@ -0,0 +1,16 @@ +#include +#include + +#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; +} \ No newline at end of file diff --git a/Kinect2Sample-master/sample/Speech/util.h b/Kinect2Sample-master/sample/Speech/util.h new file mode 100644 index 0000000..0d9787f --- /dev/null +++ b/Kinect2Sample-master/sample/Speech/util.h @@ -0,0 +1,37 @@ +#ifndef __UTIL__ +#define __UTIL__ + +#include +#include + +// 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 +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__ \ No newline at end of file