Notice: MediaWiki has been updated. Report any rough edges to marcan@marcan.st
Difference between revisions of "C++OpenCvExample"
From OpenKinect
(Fixed Mutex name collision and formatting) |
|||
(6 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
+ | == test.cpp == | ||
+ | |||
<pre> | <pre> | ||
#include "libfreenect.hpp" | #include "libfreenect.hpp" | ||
Line 8: | Line 10: | ||
#include <cxcore.h> | #include <cxcore.h> | ||
#include <highgui.h> | #include <highgui.h> | ||
+ | |||
using namespace cv; | using namespace cv; | ||
using namespace std; | using namespace std; | ||
− | class | + | |
− | public: | + | class myMutex { |
− | + | public: | |
− | + | myMutex() { | |
− | + | pthread_mutex_init( &m_mutex, NULL ); | |
− | + | } | |
− | + | void lock() { | |
− | + | pthread_mutex_lock( &m_mutex ); | |
− | + | } | |
− | + | void unlock() { | |
− | + | pthread_mutex_unlock( &m_mutex ); | |
− | private: | + | } |
− | + | private: | |
+ | pthread_mutex_t m_mutex; | ||
}; | }; | ||
+ | |||
class MyFreenectDevice : public Freenect::FreenectDevice { | class MyFreenectDevice : public Freenect::FreenectDevice { | ||
− | + | public: | |
− | + | MyFreenectDevice(freenect_context *_ctx, int _index) | |
− | + | : Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_DEPTH_11BIT), | |
− | + | m_buffer_rgb(FREENECT_VIDEO_RGB), m_gamma(2048), m_new_rgb_frame(false), | |
− | + | m_new_depth_frame(false), depthMat(Size(640,480),CV_16UC1), | |
− | + | rgbMat(Size(640,480), CV_8UC3, Scalar(0)), | |
− | + | ownMat(Size(640,480),CV_8UC3,Scalar(0)) { | |
− | + | ||
− | + | for( unsigned int i = 0 ; i < 2048 ; i++) { | |
+ | float v = i/2048.0; | ||
+ | v = std::pow(v, 3)* 6; | ||
+ | m_gamma[i] = v*6*256; | ||
+ | } | ||
} | } | ||
− | + | ||
− | + | // Do not call directly even in child | |
− | + | void VideoCallback(void* _rgb, uint32_t timestamp) { | |
− | + | std::cout << "RGB callback" << std::endl; | |
− | + | m_rgb_mutex.lock(); | |
− | + | uint8_t* rgb = static_cast<uint8_t*>(_rgb); | |
− | + | rgbMat.data = rgb; | |
− | + | m_new_rgb_frame = true; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
m_rgb_mutex.unlock(); | m_rgb_mutex.unlock(); | ||
− | + | }; | |
− | + | ||
− | + | // Do not call directly even in child | |
− | + | void DepthCallback(void* _depth, uint32_t timestamp) { | |
+ | std::cout << "Depth callback" << std::endl; | ||
+ | m_depth_mutex.lock(); | ||
+ | uint16_t* depth = static_cast<uint16_t*>(_depth); | ||
+ | depthMat.data = (uchar*) depth; | ||
+ | m_new_depth_frame = true; | ||
+ | m_depth_mutex.unlock(); | ||
} | } | ||
− | + | ||
− | + | bool getVideo(Mat& output) { | |
− | + | m_rgb_mutex.lock(); | |
− | + | if(m_new_rgb_frame) { | |
− | if( | + | cv::cvtColor(rgbMat, output, CV_RGB2BGR); |
− | + | m_new_rgb_frame = false; | |
− | + | m_rgb_mutex.unlock(); | |
− | |||
return true; | return true; | ||
} else { | } else { | ||
− | + | m_rgb_mutex.unlock(); | |
return false; | return false; | ||
} | } | ||
} | } | ||
− | + | ||
− | + | bool getDepth(Mat& output) { | |
− | + | m_depth_mutex.lock(); | |
− | + | if(m_new_depth_frame) { | |
− | + | depthMat.copyTo(output); | |
− | + | m_new_depth_frame = false; | |
− | + | m_depth_mutex.unlock(); | |
− | + | return true; | |
− | + | } else { | |
− | + | m_depth_mutex.unlock(); | |
− | + | return false; | |
− | + | } | |
+ | } | ||
+ | private: | ||
+ | std::vector<uint8_t> m_buffer_depth; | ||
+ | std::vector<uint8_t> m_buffer_rgb; | ||
+ | std::vector<uint16_t> m_gamma; | ||
+ | Mat depthMat; | ||
+ | Mat rgbMat; | ||
+ | Mat ownMat; | ||
+ | myMutex m_rgb_mutex; | ||
+ | myMutex m_depth_mutex; | ||
+ | bool m_new_rgb_frame; | ||
+ | bool m_new_depth_frame; | ||
}; | }; | ||
− | |||
Line 104: | Line 112: | ||
string suffix(".png"); | string suffix(".png"); | ||
int i_snap(0),iter(0); | int i_snap(0),iter(0); | ||
− | + | ||
Mat depthMat(Size(640,480),CV_16UC1); | Mat depthMat(Size(640,480),CV_16UC1); | ||
− | Mat depthf | + | Mat depthf (Size(640,480),CV_8UC1); |
Mat rgbMat(Size(640,480),CV_8UC3,Scalar(0)); | Mat rgbMat(Size(640,480),CV_8UC3,Scalar(0)); | ||
Mat ownMat(Size(640,480),CV_8UC3,Scalar(0)); | Mat ownMat(Size(640,480),CV_8UC3,Scalar(0)); | ||
− | + | ||
− | Freenect::Freenect<MyFreenectDevice> freenect; | + | // The next two lines must be changed as Freenect::Freenect |
− | MyFreenectDevice& device = freenect.createDevice(0); | + | // isn't a template but the method createDevice: |
− | + | // Freenect::Freenect<MyFreenectDevice> freenect; | |
+ | // MyFreenectDevice& device = freenect.createDevice(0); | ||
+ | // by these two lines: | ||
+ | |||
+ | Freenect::Freenect freenect; | ||
+ | MyFreenectDevice& device = freenect.createDevice<MyFreenectDevice>(0); | ||
+ | |||
namedWindow("rgb",CV_WINDOW_AUTOSIZE); | namedWindow("rgb",CV_WINDOW_AUTOSIZE); | ||
namedWindow("depth",CV_WINDOW_AUTOSIZE); | namedWindow("depth",CV_WINDOW_AUTOSIZE); | ||
device.startVideo(); | device.startVideo(); | ||
device.startDepth(); | device.startDepth(); | ||
− | + | while (!die) { | |
− | + | device.getVideo(rgbMat); | |
− | + | device.getDepth(depthMat); | |
− | + | cv::imshow("rgb", rgbMat); | |
− | + | depthMat.convertTo(depthf, CV_8UC1, 255.0/2048.0); | |
− | + | cv::imshow("depth",depthf); | |
char k = cvWaitKey(5); | char k = cvWaitKey(5); | ||
if( k == 27 ){ | if( k == 27 ){ | ||
− | + | cvDestroyWindow("rgb"); | |
− | + | cvDestroyWindow("depth"); | |
break; | break; | ||
} | } | ||
Line 137: | Line 151: | ||
if(iter >= 1000) break; | if(iter >= 1000) break; | ||
iter++; | iter++; | ||
− | + | } | |
− | + | ||
− | + | device.stopVideo(); | |
device.stopDepth(); | device.stopDepth(); | ||
return 0; | return 0; | ||
} | } | ||
+ | </pre> | ||
+ | |||
+ | == Makefile == | ||
+ | |||
+ | <pre> | ||
+ | all: test | ||
+ | |||
+ | CFLAGS=-fPIC -g -Wall `pkg-config --cflags opencv` | ||
+ | LIBS = `pkg-config --libs opencv` | ||
+ | INCLUDE = -I/usr/local/include/libfreenect | ||
+ | FREE_LIBS = -L/usr/local/lib -lfreenect | ||
+ | |||
+ | test: test.cpp | ||
+ | $(CXX) $(INCLUDE) $(CFLAGS) $? -o $@ $(LIBS) $(FREE_LIBS) | ||
+ | |||
+ | %.o: %.cpp | ||
+ | $(CXX) -c $(CFLAGS) $< -o $@ | ||
+ | |||
+ | clean: | ||
+ | rm -rf *.o test | ||
</pre> | </pre> |
Latest revision as of 10:22, 29 April 2014
test.cpp
#include "libfreenect.hpp" #include <iostream> #include <vector> #include <cmath> #include <pthread.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> using namespace cv; using namespace std; class myMutex { public: myMutex() { pthread_mutex_init( &m_mutex, NULL ); } void lock() { pthread_mutex_lock( &m_mutex ); } void unlock() { pthread_mutex_unlock( &m_mutex ); } private: pthread_mutex_t m_mutex; }; class MyFreenectDevice : public Freenect::FreenectDevice { public: MyFreenectDevice(freenect_context *_ctx, int _index) : Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_DEPTH_11BIT), m_buffer_rgb(FREENECT_VIDEO_RGB), m_gamma(2048), m_new_rgb_frame(false), m_new_depth_frame(false), depthMat(Size(640,480),CV_16UC1), rgbMat(Size(640,480), CV_8UC3, Scalar(0)), ownMat(Size(640,480),CV_8UC3,Scalar(0)) { for( unsigned int i = 0 ; i < 2048 ; i++) { float v = i/2048.0; v = std::pow(v, 3)* 6; m_gamma[i] = v*6*256; } } // Do not call directly even in child void VideoCallback(void* _rgb, uint32_t timestamp) { std::cout << "RGB callback" << std::endl; m_rgb_mutex.lock(); uint8_t* rgb = static_cast<uint8_t*>(_rgb); rgbMat.data = rgb; m_new_rgb_frame = true; m_rgb_mutex.unlock(); }; // Do not call directly even in child void DepthCallback(void* _depth, uint32_t timestamp) { std::cout << "Depth callback" << std::endl; m_depth_mutex.lock(); uint16_t* depth = static_cast<uint16_t*>(_depth); depthMat.data = (uchar*) depth; m_new_depth_frame = true; m_depth_mutex.unlock(); } bool getVideo(Mat& output) { m_rgb_mutex.lock(); if(m_new_rgb_frame) { cv::cvtColor(rgbMat, output, CV_RGB2BGR); m_new_rgb_frame = false; m_rgb_mutex.unlock(); return true; } else { m_rgb_mutex.unlock(); return false; } } bool getDepth(Mat& output) { m_depth_mutex.lock(); if(m_new_depth_frame) { depthMat.copyTo(output); m_new_depth_frame = false; m_depth_mutex.unlock(); return true; } else { m_depth_mutex.unlock(); return false; } } private: std::vector<uint8_t> m_buffer_depth; std::vector<uint8_t> m_buffer_rgb; std::vector<uint16_t> m_gamma; Mat depthMat; Mat rgbMat; Mat ownMat; myMutex m_rgb_mutex; myMutex m_depth_mutex; bool m_new_rgb_frame; bool m_new_depth_frame; }; int main(int argc, char **argv) { bool die(false); string filename("snapshot"); string suffix(".png"); int i_snap(0),iter(0); Mat depthMat(Size(640,480),CV_16UC1); Mat depthf (Size(640,480),CV_8UC1); Mat rgbMat(Size(640,480),CV_8UC3,Scalar(0)); Mat ownMat(Size(640,480),CV_8UC3,Scalar(0)); // The next two lines must be changed as Freenect::Freenect // isn't a template but the method createDevice: // Freenect::Freenect<MyFreenectDevice> freenect; // MyFreenectDevice& device = freenect.createDevice(0); // by these two lines: Freenect::Freenect freenect; MyFreenectDevice& device = freenect.createDevice<MyFreenectDevice>(0); namedWindow("rgb",CV_WINDOW_AUTOSIZE); namedWindow("depth",CV_WINDOW_AUTOSIZE); device.startVideo(); device.startDepth(); while (!die) { device.getVideo(rgbMat); device.getDepth(depthMat); cv::imshow("rgb", rgbMat); depthMat.convertTo(depthf, CV_8UC1, 255.0/2048.0); cv::imshow("depth",depthf); char k = cvWaitKey(5); if( k == 27 ){ cvDestroyWindow("rgb"); cvDestroyWindow("depth"); break; } if( k == 8 ) { std::ostringstream file; file << filename << i_snap << suffix; cv::imwrite(file.str(),rgbMat); i_snap++; } if(iter >= 1000) break; iter++; } device.stopVideo(); device.stopDepth(); return 0; }
Makefile
all: test CFLAGS=-fPIC -g -Wall `pkg-config --cflags opencv` LIBS = `pkg-config --libs opencv` INCLUDE = -I/usr/local/include/libfreenect FREE_LIBS = -L/usr/local/lib -lfreenect test: test.cpp $(CXX) $(INCLUDE) $(CFLAGS) $? -o $@ $(LIBS) $(FREE_LIBS) %.o: %.cpp $(CXX) -c $(CFLAGS) $< -o $@ clean: rm -rf *.o test