After struggling several days with all stuff related to OpenKinect (libfreenect) and Microsoft Visual Studio 2008, finally I could execute the experiment on getting the Kinect RGB-Depth image wrapped with the OpenCV2.1 library functions.
Special thanks to Tisham Dhar who wrote a very nice article on his blog :
http://whatnicklife.blogspot.com
You can access the source code from his google code page : freenectopencv.cpp
Or, the below code is taken from Tisham’s page which then combined with Canny Filter operation :
(comment out all the glview.c code and replace with the below source code)
/* freenectopencv.cpp Copyright (C) 2010 Arne Bernin This code is licensed to you under the terms of the GNU GPL, version 2 or version 3; see: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt http://www.gnu.org/licenses/gpl-3.0.txt */ /* * Makefile for ubuntu, assumes that libfreenect.a is in /usr/lib, and libfreenect.h is in /usr/include * * make sure you have the latest version of freenect from git! *************************************************************************************************************************** * Makefile *************************************************************************************************************************** CXXFLAGS = -O2 -g -Wall -fmessage-length=0 `pkg-config opencv --cflags ` -I /usr/include/libusb-1.0 OBJS = freenectopencv.o LIBS = `pkg-config opencv --libs` -lfreenect TARGET = kinectopencv $(TARGET): $(OBJS) $(CXX) -o $(TARGET) $(OBJS) $(LIBS) all: $(TARGET) clean: rm -f $(OBJS) $(TARGET) *************************************************************************************************** * End of Makefile *************************************************************************************************** */ #include <stdio.h> #include <string.h> #include <math.h> #include <libfreenect.h> #include <pthread.h> #define CV_NO_BACKWARD_COMPATIBILITY #include <cv.h> #include <highgui.h> #define FREENECTOPENCV_WINDOW_D "Depthimage" #define FREENECTOPENCV_WINDOW_N "Normalimage" #define FREENECTOPENCV_RGB_DEPTH 3 #define FREENECTOPENCV_DEPTH_DEPTH 1 #define FREENECTOPENCV_RGB_WIDTH 640 #define FREENECTOPENCV_RGB_HEIGHT 480 #define FREENECTOPENCV_DEPTH_WIDTH 640 #define FREENECTOPENCV_DEPTH_HEIGHT 480 IplImage* depthimg = 0; IplImage* rgbimg = 0; IplImage* tempimg = 0; IplImage* canny_img = 0; IplImage* canny_temp = 0; pthread_mutex_t mutex_depth = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex_rgb = PTHREAD_MUTEX_INITIALIZER; pthread_t cv_thread; // callback for depthimage, called by libfreenect void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp) { cv::Mat depth8; cv::Mat mydepth = cv::Mat( FREENECTOPENCV_DEPTH_WIDTH,FREENECTOPENCV_DEPTH_HEIGHT, CV_16UC1, depth); mydepth.convertTo(depth8, CV_8UC1, 1.0/4.0); pthread_mutex_lock( &mutex_depth ); memcpy(depthimg->imageData, depth8.data, 640*480); // unlock mutex pthread_mutex_unlock( &mutex_depth ); } // callback for rgbimage, called by libfreenect void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp) { // lock mutex for opencv rgb image pthread_mutex_lock( &mutex_rgb ); memcpy(rgbimg->imageData, rgb, FREENECT_VIDEO_RGB_SIZE); // unlock mutex pthread_mutex_unlock( &mutex_rgb ); } /* * thread for displaying the opencv content */ void *cv_threadfunc (void *ptr) { cvNamedWindow( FREENECTOPENCV_WINDOW_D, CV_WINDOW_AUTOSIZE ); cvNamedWindow( FREENECTOPENCV_WINDOW_N, CV_WINDOW_AUTOSIZE ); cvNamedWindow( "Canny Image", CV_WINDOW_AUTOSIZE ); cvNamedWindow( "Depth Canny", CV_WINDOW_AUTOSIZE ); depthimg = cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH); rgbimg = cvCreateImage(cvSize(FREENECTOPENCV_RGB_WIDTH, FREENECTOPENCV_RGB_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_RGB_DEPTH); tempimg = cvCreateImage(cvSize(FREENECTOPENCV_RGB_WIDTH, FREENECTOPENCV_RGB_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_RGB_DEPTH); canny_img = cvCreateImage(cvSize(FREENECTOPENCV_RGB_WIDTH, FREENECTOPENCV_RGB_HEIGHT), IPL_DEPTH_8U, 1); canny_temp = cvCreateImage(cvSize(FREENECTOPENCV_DEPTH_WIDTH, FREENECTOPENCV_DEPTH_HEIGHT), IPL_DEPTH_8U, FREENECTOPENCV_DEPTH_DEPTH); // use image polling while (1) { //lock mutex for depth image pthread_mutex_lock( &mutex_depth ); // show image to window cvCanny(depthimg, canny_temp, 50.0, 200.0, 3); cvCvtColor(depthimg,tempimg,CV_GRAY2BGR); cvCvtColor(tempimg,tempimg,CV_HSV2BGR); cvShowImage(FREENECTOPENCV_WINDOW_D,tempimg); cvShowImage("Depth Canny", canny_temp); //unlock mutex for depth image pthread_mutex_unlock( &mutex_depth ); //lock mutex for rgb image pthread_mutex_lock( &mutex_rgb ); // show image to window cvCvtColor(rgbimg,tempimg,CV_BGR2RGB); cvCvtColor(tempimg, canny_img, CV_BGR2GRAY); cvShowImage(FREENECTOPENCV_WINDOW_N, tempimg); // Canny filter cvCanny(canny_img, canny_img, 50.0, 200.0, 3); cvShowImage("Canny Image", canny_img); //unlock mutex pthread_mutex_unlock( &mutex_rgb ); // wait for quit key if( cvWaitKey( 15 )==27 ) break; } pthread_exit(NULL); return NULL; } int main(int argc, char **argv) { freenect_context *f_ctx; freenect_device *f_dev; int res = 0; int die = 0; printf("Kinect camera test\n"); if (freenect_init(&f_ctx, NULL) < 0) { printf("freenect_init() failed\n"); return 1; } if (freenect_open_device(f_ctx, &f_dev, 0) < 0) { printf("Could not open device\n"); return 1; } freenect_set_depth_callback(f_dev, depth_cb); freenect_set_video_callback(f_dev, rgb_cb); freenect_set_video_format(f_dev, FREENECT_VIDEO_RGB); // create opencv display thread res = pthread_create(&cv_thread, NULL, cv_threadfunc, (void*) depthimg); if (res) { printf("pthread_create failed\n"); return 1; } printf("init done\n"); freenect_start_depth(f_dev); freenect_start_video(f_dev); while(!die && freenect_process_events(f_ctx) >= 0 ); }
Please notice that I am using : libfreenect for Windows + Microsoft Visual Studio 9 (2008) + OpenCV 2.1
Recent Comments