Notice: MediaWiki has been updated. Report any rough edges to marcan@marcan.st

Difference between revisions of "C++OpenCvExample"

From OpenKinect
Jump to: navigation, search
(Fixed Mutex name collision and formatting)
 
(10 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{#include "libfreenect.hpp"
+
== test.cpp ==
 +
 
 +
<pre>
 +
#include "libfreenect.hpp"
 
#include <iostream>
 
#include <iostream>
 
#include <vector>
 
#include <vector>
Line 7: 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 Mutex {
+
 
public:
+
class myMutex {
Mutex() {
+
public:
pthread_mutex_init( &m_mutex, NULL );
+
myMutex() {
}
+
pthread_mutex_init( &m_mutex, NULL );
void lock() {
+
}
pthread_mutex_lock( &m_mutex );
+
void lock() {
}
+
pthread_mutex_lock( &m_mutex );
void unlock() {
+
}
pthread_mutex_unlock( &m_mutex );
+
void unlock() {
}
+
pthread_mutex_unlock( &m_mutex );
private:
+
}
pthread_mutex_t m_mutex;
+
private:
 +
pthread_mutex_t m_mutex;
 
};
 
};
 +
  
 
class MyFreenectDevice : public Freenect::FreenectDevice {
 
class MyFreenectDevice : public Freenect::FreenectDevice {
  public:
+
public:
MyFreenectDevice(freenect_context *_ctx, int _index)
+
MyFreenectDevice(freenect_context *_ctx, int _index)
: Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_DEPTH_11BIT_SIZE),m_buffer_rgb(FREENECT_VIDEO_RGB_SIZE), m_gamma(2048), m_new_rgb_frame(false), m_new_depth_frame(false),
+
: Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_DEPTH_11BIT),
  depthMat(Size(640,480),CV_16UC1), rgbMat(Size(640,480),CV_8UC3,Scalar(0)), ownMat(Size(640,480),CV_8UC3,Scalar(0))
+
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),
for( unsigned int i = 0 ; i < 2048 ; i++) {
+
rgbMat(Size(640,480), CV_8UC3, Scalar(0)),
float v = i/2048.0;
+
ownMat(Size(640,480),CV_8UC3,Scalar(0)) {
v = std::pow(v, 3)* 6;
+
m_gamma[i] = v*6*256;
+
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
+
// Do not call directly even in child
void VideoCallback(void* _rgb, uint32_t timestamp) {
+
void VideoCallback(void* _rgb, uint32_t timestamp) {
std::cout << "RGB callback" << std::endl;
+
std::cout << "RGB callback" << std::endl;
m_rgb_mutex.lock();
+
m_rgb_mutex.lock();
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
+
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
rgbMat.data = rgb;
+
rgbMat.data = rgb;
m_new_rgb_frame = true;
+
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();
 
m_rgb_mutex.unlock();
return true;
+
};
} else {
+
m_rgb_mutex.unlock();
+
// Do not call directly even in child
return false;
+
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) {
bool getDepth(Mat& output) {
+
m_rgb_mutex.lock();
m_depth_mutex.lock();
+
if(m_new_rgb_frame) {
if(m_new_depth_frame) {
+
cv::cvtColor(rgbMat, output, CV_RGB2BGR);
depthMat.copyTo(output);
+
m_new_rgb_frame = false;
m_new_depth_frame = false;
+
m_rgb_mutex.unlock();
m_depth_mutex.unlock();
 
 
return true;
 
return true;
 
} else {
 
} else {
m_depth_mutex.unlock();
+
m_rgb_mutex.unlock();
 
return false;
 
return false;
 
}
 
}
 
}
 
}
 
+
  private:
+
bool getDepth(Mat& output) {
std::vector<uint8_t> m_buffer_depth;
+
m_depth_mutex.lock();
std::vector<uint8_t> m_buffer_rgb;
+
if(m_new_depth_frame) {
std::vector<uint16_t> m_gamma;
+
depthMat.copyTo(output);
Mat depthMat;
+
m_new_depth_frame = false;
Mat rgbMat;
+
m_depth_mutex.unlock();
Mat ownMat;
+
return true;
Mutex m_rgb_mutex;
+
} else {
Mutex m_depth_mutex;
+
m_depth_mutex.unlock();
bool m_new_rgb_frame;
+
return false;
bool m_new_depth_frame;
+
}
 +
}
 +
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 103: 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 (Size(640,480),CV_8UC1);
+
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);
namedWindow("own",CV_WINDOW_AUTOSIZE);
 
 
device.startVideo();
 
device.startVideo();
 
device.startDepth();
 
device.startDepth();
    while (!die) {
+
while (!die) {
    device.getVideo(rgbMat);
+
device.getVideo(rgbMat);
    device.getDepth(depthMat);
+
device.getDepth(depthMat);
        cv::imshow("rgb", rgbMat);
+
cv::imshow("rgb", rgbMat);
    depthMat.convertTo(depthf, CV_8UC1, 255.0/2048.0);
+
depthMat.convertTo(depthf, CV_8UC1, 255.0/2048.0);
        cv::imshow("depth",depthf);
+
cv::imshow("depth",depthf);
        cv::imshow("own",ownMat);
 
 
char k = cvWaitKey(5);
 
char k = cvWaitKey(5);
 
if( k == 27 ){
 
if( k == 27 ){
    cvDestroyWindow("rgb");
+
cvDestroyWindow("rgb");
    cvDestroyWindow("depth");
+
cvDestroyWindow("depth");
    cvDestroyWindow("own");
 
 
break;
 
break;
 
}
 
}
Line 139: Line 151:
 
if(iter >= 1000) break;
 
if(iter >= 1000) break;
 
iter++;
 
iter++;
    }
+
}
 
+
  device.stopVideo();
+
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>

Latest revision as of 09: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