diff --git a/cmake/modules/FindNITE.cmake b/cmake/modules/FindNITE.cmake new file mode 100644 index 0000000000..301ed651ee --- /dev/null +++ b/cmake/modules/FindNITE.cmake @@ -0,0 +1,44 @@ +# Find the NITE library +# +# You must provide an NITE_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# NITE_FOUND - system found NITE +# NITE_INCLUDE_DIRS - the NITE include directory +# NITE_LIBRARIES - Link this to use NITE +# +# Created on 6/28/2013 by Andrzej Kapolka +# Copyright (c) 2013 High Fidelity +# + +if (NITE_LIBRARIES AND NITE_INCLUDE_DIRS) + # in cache already + set(NITE_FOUND TRUE) +else (NITE_LIBRARIES AND NITE_INCLUDE_DIRS) + find_path(NITE_INCLUDE_DIRS XnVNite.h /usr/include/nite) + + if (APPLE) + find_library(NITE_LIBRARIES libXnVNite_1_5_2.dylib /usr/lib) + elseif (UNIX) + find_library(NITE_LIBRARIES libXnVNite_1_5_2.so /usr/lib) + endif () + + if (NITE_INCLUDE_DIRS AND NITE_LIBRARIES) + set(NITE_FOUND TRUE) + endif (NITE_INCLUDE_DIRS AND NITE_LIBRARIES) + + if (NITE_FOUND) + if (NOT NITE_FIND_QUIETLY) + message(STATUS "Found NITE: ${NITE_LIBRARIES}") + endif (NOT NITE_FIND_QUIETLY) + else (NITE_FOUND) + if (NITE_FIND_REQUIRED) + message(FATAL_ERROR "Could not find NITE") + endif (NITE_FIND_REQUIRED) + endif (NITE_FOUND) + + # show the NITE_INCLUDE_DIRS and NITE_LIBRARIES variables only in the advanced view + mark_as_advanced(NITE_INCLUDE_DIRS NITE_LIBRARIES) + +endif (NITE_LIBRARIES AND NITE_INCLUDE_DIRS) diff --git a/cmake/modules/FindOpenNI.cmake b/cmake/modules/FindOpenNI.cmake new file mode 100644 index 0000000000..111a33dfbe --- /dev/null +++ b/cmake/modules/FindOpenNI.cmake @@ -0,0 +1,44 @@ +# Find the OpenNI library +# +# You must provide an OPENNI_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# OPENNI_FOUND - system found OpenNI +# OPENNI_INCLUDE_DIRS - the OpenNI include directory +# OPENNI_LIBRARIES - Link this to use OpenNI +# +# Created on 6/28/2013 by Andrzej Kapolka +# Copyright (c) 2013 High Fidelity +# + +if (OPENNI_LIBRARIES AND OPENNI_INCLUDE_DIRS) + # in cache already + set(OPENNI_FOUND TRUE) +else (OPENNI_LIBRARIES AND OPENNI_INCLUDE_DIRS) + find_path(OPENNI_INCLUDE_DIRS XnOpenNI.h /usr/include/ni) + + if (APPLE) + find_library(OPENNI_LIBRARIES libOpenNI.dylib /usr/lib) + elseif (UNIX) + find_library(OPENNI_LIBRARIES libOpenNI.so /usr/lib) + endif () + + if (OPENNI_INCLUDE_DIRS AND OPENNI_LIBRARIES) + set(OPENNI_FOUND TRUE) + endif (OPENNI_INCLUDE_DIRS AND OPENNI_LIBRARIES) + + if (OPENNI_FOUND) + if (NOT OPENNI_FIND_QUIETLY) + message(STATUS "Found OpenNI: ${OPENNI_LIBRARIES}") + endif (NOT OPENNI_FIND_QUIETLY) + else (OPENNI_FOUND) + if (OPENNI_FIND_REQUIRED) + message(FATAL_ERROR "Could not find OpenNI") + endif (OPENNI_FIND_REQUIRED) + endif (OPENNI_FOUND) + + # show the OPENNI_INCLUDE_DIRS and OPENNI_LIBRARIES variables only in the advanced view + mark_as_advanced(OPENNI_INCLUDE_DIRS OPENNI_LIBRARIES) + +endif (OPENNI_LIBRARIES AND OPENNI_INCLUDE_DIRS) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index c840bd980d..941a321c22 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -91,6 +91,15 @@ find_package(Leap) find_package(OpenCV) find_package(ZLIB) find_package(UVCCameraControl) +find_package(OpenNI) +find_package(NITE) + +# let the source know that we have OpenNI/NITE for Kinect +if (OPENNI_FOUND AND NITE_FOUND) + add_definitions(-DHAVE_NITE) + include_directories(SYSTEM ${OPENNI_INCLUDE_DIRS} ${NITE_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${OPENNI_LIBRARIES} ${NITE_LIBRARIES}) +endif (OPENNI_FOUND AND NITE_FOUND) # include headers for interface and InterfaceConfig. include_directories( diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 9438a18c3d..e18c2c5aa8 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -210,17 +210,11 @@ void Webcam::setFrame(const Mat& frame, int format, const Mat& depth, const Rota QTimer::singleShot(qMax((int)remaining / 1000, 0), _grabber, SLOT(grabFrame())); } -FrameGrabber::FrameGrabber() : _capture(0), _searchWindow(0, 0, 0, 0), _freenectContext(0) { +FrameGrabber::FrameGrabber() : _capture(0), _searchWindow(0, 0, 0, 0) { } FrameGrabber::~FrameGrabber() { - if (_freenectContext != 0) { - freenect_stop_depth(_freenectDevice); - freenect_stop_video(_freenectDevice); - freenect_close_device(_freenectDevice); - freenect_shutdown(_freenectContext); - - } else if (_capture != 0) { + if (_capture != 0) { cvReleaseCapture(&_capture); } } @@ -229,51 +223,36 @@ void FrameGrabber::reset() { _searchWindow = Rect(0, 0, 0, 0); } -static Mat videoFrame, depthFrame; -static bool gotVideoFrame, gotDepthFrame; - void FrameGrabber::grabFrame() { - if (_capture == 0 && _freenectContext == 0 && !init()) { + if (_capture == 0 && !init()) { return; } int format = GL_BGR; - ::gotVideoFrame = ::gotDepthFrame = false; - if (_freenectContext != 0) { - freenect_process_events(_freenectContext); - if (::gotDepthFrame) { - ::depthFrame.convertTo(_grayDepth, CV_8UC1, 255.0 / 2047.0); - } - format = GL_RGB; - - } else { - IplImage* image = cvQueryFrame(_capture); - if (image != 0) { - // make sure it's in the format we expect - if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U || image->dataOrder != IPL_DATA_ORDER_PIXEL || - image->origin != 0) { - printLog("Invalid webcam image format.\n"); - return; - } - ::videoFrame = image; - ::gotVideoFrame = true; - } - } - if (!::gotVideoFrame) { + IplImage* image = cvQueryFrame(_capture); + if (image == 0) { // try again later QMetaObject::invokeMethod(this, "grabFrame", Qt::QueuedConnection); return; } + // make sure it's in the format we expect + if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U || image->dataOrder != IPL_DATA_ORDER_PIXEL || + image->origin != 0) { + printLog("Invalid webcam image format.\n"); + return; + } + Mat frame = image; + // if we don't have a search window (yet), try using the face cascade int channels = 0; float ranges[] = { 0, 180 }; const float* range = ranges; if (_searchWindow.area() == 0) { vector faces; - _faceCascade.detectMultiScale(::videoFrame, faces, 1.1, 6); + _faceCascade.detectMultiScale(frame, faces, 1.1, 6); if (!faces.empty()) { _searchWindow = faces.front(); - updateHSVFrame(::videoFrame, format); + updateHSVFrame(frame, format); Mat faceHsv(_hsvFrame, _searchWindow); Mat faceMask(_mask, _searchWindow); @@ -286,7 +265,7 @@ void FrameGrabber::grabFrame() { } RotatedRect faceRect; if (_searchWindow.area() > 0) { - updateHSVFrame(::videoFrame, format); + updateHSVFrame(frame, format); calcBackProject(&_hsvFrame, 1, &channels, _histogram, _backProject, &range); bitwise_and(_backProject, _mask, _backProject); @@ -295,25 +274,7 @@ void FrameGrabber::grabFrame() { _searchWindow = faceRect.boundingRect(); } QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame", - Q_ARG(cv::Mat, ::videoFrame), Q_ARG(int, format), Q_ARG(cv::Mat, _grayDepth), Q_ARG(cv::RotatedRect, faceRect)); -} - -const char* FREENECT_LOG_LEVEL_NAMES[] = { "fatal", "error", "warning", "notice", "info", "debug", "spew", "flood" }; - -static void logCallback(freenect_context* freenectDevice, freenect_loglevel level, const char *msg) { - printLog("Freenect %s: %s\n", FREENECT_LOG_LEVEL_NAMES[level], msg); -} - -static freenect_frame_mode freenectVideoMode, freenectDepthMode; - -static void depthCallback(freenect_device* freenectDevice, void* depth, uint32_t timestamp) { - ::depthFrame = Mat(::freenectDepthMode.height, ::freenectDepthMode.width, CV_16UC1, depth); - ::gotDepthFrame = true; -} - -static void videoCallback(freenect_device* freenectDevice, void* video, uint32_t timestamp) { - ::videoFrame = Mat(::freenectVideoMode.height, ::freenectVideoMode.width, CV_8UC3, video); - ::gotVideoFrame = true; + Q_ARG(cv::Mat, frame), Q_ARG(int, format), Q_ARG(cv::Mat, Mat()), Q_ARG(cv::RotatedRect, faceRect)); } bool FrameGrabber::init() { @@ -325,28 +286,10 @@ bool FrameGrabber::init() { } // first try for a Kinect - if (freenect_init(&_freenectContext, 0) >= 0) { - freenect_set_log_level(_freenectContext, FREENECT_LOG_WARNING); - freenect_set_log_callback(_freenectContext, logCallback); - freenect_select_subdevices(_freenectContext, FREENECT_DEVICE_CAMERA); - - if (freenect_num_devices(_freenectContext) > 0) { - if (freenect_open_device(_freenectContext, &_freenectDevice, 0) >= 0) { - freenect_set_depth_callback(_freenectDevice, depthCallback); - freenect_set_video_callback(_freenectDevice, videoCallback); - ::freenectVideoMode = freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB); - freenect_set_video_mode(_freenectDevice, ::freenectVideoMode); - ::freenectDepthMode = freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_11BIT); - freenect_set_depth_mode(_freenectDevice, ::freenectDepthMode); - - freenect_start_depth(_freenectDevice); - freenect_start_video(_freenectDevice); - return true; - } - } - freenect_shutdown(_freenectContext); - _freenectContext = 0; - } +#ifdef HAVE_NITE + _xnContext.Init(); + +#endif // next, an ordinary webcam if ((_capture = cvCaptureFromCAM(-1)) == 0) { diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 27e54caada..b9a2f0e6fe 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -15,10 +15,12 @@ #include -#include - #include +#ifdef HAVE_NITE + #include +#endif + #include "InterfaceConfig.h" class QImage; @@ -97,10 +99,10 @@ private: cv::SparseMat _histogram; cv::Mat _backProject; cv::Rect _searchWindow; - cv::Mat _grayDepth; - - freenect_context* _freenectContext; - freenect_device* _freenectDevice; + +#ifdef HAVE_NITE + xn::Context _xnContext; +#endif }; Q_DECLARE_METATYPE(cv::Mat)