在硬盘上写快速kinect数据

时间:2016-06-01 11:14:52

标签: multithreading visual-c++

我想构建一个face数据集。所以我用(Visual c ++)编写一个抓取程序,用60 fps从kinect中获取颜色/深度/红外和其他一些数据,然后将它们保存在硬盘上。它需要花费很多时间,因此我不能在一秒钟内保存超过10帧,并且丢弃了大量帧。我尝试使用fileStorage(opencv)将数据保存为yaml,但它也很慢。我正在考虑使用两个线程,一个用于获取数据,另一个用于保存。但两个独立线程之间的数据通信是主要问题。 在不丢失框架的情况下保存数据的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:-1)

通过mmap()缓存内存中的60个或更多帧,并使用sendfile保存文件。当然,在缓存和保存之间需要一些同步。

假设您使用具有预定义数量的元素的vector<JOB>,例如600(60 * number_of_sec_which_are_cached)。

struct JOB 
{
    int second_number; //second related to time 
    int frame_number; //frame number in second specified by "JOB::second_number"
    unsigned char *buf; //frame buffer
    unsigned int buf_length; //number of bytes in frame which would be a fixed number.
    int valid; 
};

Grabber将在获取框架时JOB::valid = 1

FileSavingThread将使用JOB::valid来确定框架是否已准备好保存JOB::valid==1,保存后将JOB::valid=0

现在,如果JOB::valid用于JOB::valid==0,那么您可以轻松避免使用互斥锁进行同步。

然后,Grabber必须在向量中找到一个元素(通过遍历所有元素),其中JOB::valid==1将该帧存储在该特定元素中。

类似地,FileSavingThread必须在向量中找到一个具有//-------------------------------------------------------------------------的元素,并将该元素中指定的帧存储到文件中。

根据性能,您可以尝试增加向量中的元素数量或增加FileSavingThread的数量或两者。

{{1}}

在这里,如果我们知道有多少帧或者与保存的时间秒数相对应的数据,那么我们可以在手和内存映射该文件之前创建一个这么大的文件。然后,保存帧将像以连续方式写入存储器一样简单。操作系统将以最佳方式自动管理缓存和I / O.

这是可能的,因为计算中涉及的所有参数w.r.t都是固定的。

也可以通过Memory Mapping保存文件来读取帧。如果再次需要单个帧,则从保存文件的开始计算偏移量很容易计算,因为计算特定帧的偏移量所需的所有参数都是固定的。

现在可以在这里阅读以这种方式阅读/写作的好处Memory Mapped File

答案 1 :(得分:-1)

感谢您的帮助。 我通过定义两个线程,共享内存(队列)和互斥锁来解决问题。

//I have a passenger class that store all data including images in it
#include "passenger.h"
//I define a queue from passenger class
queue<passenger> passengerQueue;
//and a mutex 
std::mutex myMutex;
void GrabberThreadFunc()
{
     //get the data and store it in a passenger object
     if (nearPassenger.valid)
    {
        std::lock_guard<std::mutex> guard(myMutex);
        passengerQueue.push(nearPassenger);
     }
}
void SavetThreadFunc()
{
     if (!passengerQueue.empty())
    {
        std::lock_guard<std::mutex> guard(myMutex);
        passengerQueue.front().SaveData();
        passengerQueue.pop();
   }
}

int _tmain(int argc,_TCHAR * argv []) {

thread GrabberThread(GrabberThreadFunc);
thread SaverThread(SaverThreadFunc);

if (GrabberThread.joinable())
    GrabberThread.join();

if (SaverThread.joinable())
    SaverThread.join();

return 0;

}