我是一位研究人員,所以這個想法不一定對生產代碼有用,但在這種情況下,我的最佳解決方案是爲每種類型的相機創建一個服務器進程。每個服務器進程都知道如何加載其自己類型的相機流,然後將其引入其他進程可以讀取的共享內存空間。 顯然可以使用不同類型的鎖定機制,但我沒有任何鎖定而留下下面的代碼。
服務器進程將包括以下內容:
#define BOOST_ALL_NO_LIB
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
using namespace std;
using namespace boost::interprocess;
struct sharedImage
{
enum { width = 320 };
enum { height = 240 };
enum { dataLength = width*height*sizeof(unsigned short) };
sharedImage(){}
interprocess_mutex mutex;
unsigned short data[dataLength];
};
shared_memory_object shm;
sharedImage * sIm;
mapped_region region;
int setupSharedMemory(){
// Clear the object if it exists
shared_memory_object::remove("ImageMem");
shm = shared_memory_object(create_only /*only create*/,"ImageMem" /*name*/,read_write/*read-write mode*/);
printf("Size:%i\n",sizeof(sharedImage));
//Set size
shm.truncate(sizeof(sharedImage));
//Map the whole shared memory in this process
region = mapped_region(shm, read_write);
//Get the address of the mapped region
void * addr = region.get_address();
//Construct the shared structure in the preallocated memory of shm
sIm = new (addr) sharedImage;
return 0;
}
int shutdownSharedMemory(){
shared_memory_object::remove("ImageMem");
return 0;
}
啓動它的呼叫setupSharedMemory()
和關閉呼叫shutdownSharedMemory()
。
在這個簡單的例子中,所有的值都是硬編碼的,但它很容易想象使它更加靈活。
現在讓我們假設您正在使用SoftKinetic的DepthSense。那麼你可以爲深度節點編寫下面的回調函數。
void onNewDepthSample(DepthNode node, DepthNode::NewSampleReceivedData data) {
//scoped_lock<interprocess_mutex> lock(sIm->mutex);
memcpy(sIm->data, data.depthMap, sIm->dataLength);
}
這樣做只是將最新的深度圖複製到共享內存空間。 你也可以添加一個時間戳和一個鎖以及其他任何你需要的東西,但是這個基本代碼對我來說足夠好,所以我會保持原樣。
現在在其他一些過程中,您可以以非常相似的方式訪問數據。 下面的代碼是我用來將實時SoftKinetic DepthSense深度流轉換爲Matlab的實時處理。這種方法相對於試圖編寫我自己的專門用於SoftKinetic的mex包裝器具有巨大的優勢,因爲如果我爲它們編寫服務器,我可以爲所有其他相機使用相同的代碼。
#include <math.h>
#include <windows.h>
#include "mex.h"
#define BOOST_ALL_NO_LIB
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace boost::interprocess;
struct sharedImage
{
enum { width = 320 };
enum { height = 240 };
enum { dataLength = width*height*sizeof(short) };
sharedImage(): dirty(true){}
interprocess_mutex mutex;
uint8_t data[dataLength];
bool dirty;
};
void getFrame(unsigned short *D)
{
//Open the shared memory object.
shared_memory_object shm(open_only ,"ImageMem", read_write);
//Map the whole shared memory in this process
mapped_region region(shm ,read_write);
//Get the address of the mapped region
void * addr = region.get_address();
//Construct the shared structure in memory
sharedImage * sIm = static_cast<sharedImage*>(addr);
//scoped_lock<interprocess_mutex> lock(sIm->mutex);
memcpy((char*)D, (char*)sIm->data, sIm->dataLength);
}
void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ])
{
// Build outputs
mwSize dims[2] = {320, 240};
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
unsigned short *D = (unsigned short*)mxGetData(plhs[0]);
try
{
getFrame(D);
}
catch (interprocess_exception &ex)
{
mexPrintf("getFrame:%s\n", ex.what());
}
}
這在我的電腦上我在Matlab編譯:mex getSKFrame.cpp -IC:\Development\boost_1_48_0
然後終於在Matlab中使用它:D = getSKFrame()'; imagesc(D)
我假設你想要一個Matlab的解決方案嗎?你不提,但你的標籤暗示它。 –
不是特別的。我用Matlab對它進行了標記,因爲我寫的答案使用了Matlab客戶端示例,我無法弄清楚如何標記答案。 – twerdster