[kinect] 编写多线程启动
2017-09-17 本文已影响0人
ericdejavu
- 多线程启动kinect可以方便的提取图像和深度数据
调用的方式如下,是不是非常简洁
#include "imgStream.h"
int main() {
DataStream data;
//后面放你的图像处理类
}
需要查看的主要类
class DataStream {
private:
Freenect::Freenect freenect;
MyFreenectDevice& device;
static void* getPthreadImg(void*);
public:
Mutex imgLock;//---------线程锁,图像处理时要调用他来防止访问冲突-----
cv::Mat color;//----------可供外部调用--------
cv::Mat depth;//---------可供外部调用--------
bool getImg();
void run_thread();
DataStream() : device(freenect.createDevice<MyFreenectDevice>(0)) {
device.startVideo();
device.startDepth();
run_thread();
}
~DataStream() {
device.stopVideo();
device.stopDepth();
}
};
- 码源
imgStream.h
#ifndef _IMGSTREAM_H
#define _IMGSTREAM_H
#include "libfreenect.hpp"
#include <iostream>
#include <vector>
#include <cmath>
#include <pthread.h>
#include <opencv2/opencv.hpp>
using namespace std;
typedef unsigned short US;
class Mutex {
private:
pthread_mutex_t m_mutex;
public:
Mutex() {pthread_mutex_init(&m_mutex, NULL);}
void lock() {pthread_mutex_lock(&m_mutex);}
void unlock() {pthread_mutex_unlock(&m_mutex);}
class ScopedLock
{
private:
Mutex &_mutex;
public:
ScopedLock(Mutex &mutex) : _mutex(mutex) {_mutex.lock();}
~ScopedLock() {_mutex.unlock();}
};
};
class MyFreenectDevice : public Freenect::FreenectDevice {
private:
Mutex m_rgb_mutex;
Mutex m_depth_mutex;
cv::Mat rgbMat;
cv::Mat depthMat;
bool m_new_rgb_frame;
bool m_new_depth_frame;
public:
MyFreenectDevice(freenect_context *_ctx, int _index)
: Freenect::FreenectDevice(_ctx, _index),
rgbMat(cv::Size(640,480),CV_8UC3,cv::Scalar::all(0)),
depthMat(cv::Size(640,480),CV_16UC1),
m_new_rgb_frame(false), m_new_depth_frame(false)
{setDepthFormat(FREENECT_DEPTH_REGISTERED);}
void VideoCallback(void *_rgb, uint32_t timestamp);
void DepthCallback(void *_depth, uint32_t timestamp);
bool getRGB(cv::Mat &buffer);
bool getDepth(cv::Mat &buffer);
};
class DataStream {
private:
Freenect::Freenect freenect;
MyFreenectDevice& device;
static void* getPthreadImg(void*);
public:
Mutex imgLock;
cv::Mat color;
cv::Mat depth;
bool getImg();
void run_thread();
DataStream() : device(freenect.createDevice<MyFreenectDevice>(0)) {
device.startVideo();
device.startDepth();
run_thread();
}
~DataStream() {
device.stopVideo();
device.stopDepth();
}
};
#endif
kinect_lib.cpp
#include "imgStream.h"
void MyFreenectDevice::VideoCallback(void *_rgb, uint32_t timestamp) {
Mutex::ScopedLock lock(m_rgb_mutex);
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
rgbMat.data = rgb;
m_new_rgb_frame = true;
}
// Do not call directly, even in child
void MyFreenectDevice::DepthCallback(void *_depth, uint32_t timestamp) {
Mutex::ScopedLock lock(m_depth_mutex);
uint16_t* depth = static_cast<uint16_t*>(_depth);
depthMat.data = (uchar*) depth;
m_new_depth_frame = true;
}
bool MyFreenectDevice::getRGB(cv::Mat &buffer) {
Mutex::ScopedLock lock(m_rgb_mutex);
if (!m_new_rgb_frame)
return false;
cv::cvtColor(rgbMat, buffer, CV_RGB2BGR);
m_new_rgb_frame = false;
return true;
}
bool MyFreenectDevice::getDepth(cv::Mat &buffer) {
Mutex::ScopedLock lock(m_depth_mutex);
if (!m_new_depth_frame)
return false;
buffer = depthMat.clone();
m_new_depth_frame = false;
return true;
}
bool DataStream::getImg() {
Mutex::ScopedLock lock(imgLock);
device.getRGB(color);
device.getDepth(depth);
cv::imshow("src",color);
if(char(cv::waitKey(1)) == 27) return false;
return true;
}
void* DataStream::getPthreadImg( void* __this ) {
DataStream* _this = (DataStream*) __this;
while(true) {
if(!_this->getImg()) pthread_exit(NULL);
}
}
void DataStream::run_thread() {
pthread_t id;
pthread_create(&id,NULL,getPthreadImg,(void*)this);
}