美文网首页
[kinect] 编写多线程启动

[kinect] 编写多线程启动

作者: ericdejavu | 来源:发表于2017-09-17 14:38 被阅读0次

    参考
    created by Dejavu


    • 多线程启动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);
    }
    

    相关文章

      网友评论

          本文标题:[kinect] 编写多线程启动

          本文链接:https://www.haomeiwen.com/subject/jtapsxtx.html