2017-04-19 62 views
2

什么是通过MPI发送OPENCV Mat的最佳方式?现在我已经完成了Matint**,但这是一个有点慢的解决方案。什么是通过MPI发送OPENCV Mat的最佳方式

A = alloc2d(n , m); 
for (int i = 0; i < n ; ++i) 
    for (int j = 0; j < m ; ++j) 
     A[i][j] = img.at<uchar>(i , j); 

///////////////////////////////////// 
int ** alloc2d(int rows, int cols) { 
    int * data = (int *)malloc(rows * cols * sizeof(int)); 
    int ** arr = (int **)malloc(rows * sizeof(int *)); 
    for (int i = 0; i < rows; ++i) 
     arr[i] = &(data[cols * i]); 
    return arr; 
} 
+0

请出示您已经使用转换为INT''**以及特定的测量,你认为是结果代码*慢*? – Zulan

+0

我发布了代码 – RicUfa

+0

我没有看到任何MPI或性能测量结果。 – Zulan

回答

2

检查原来的Mat首先是连续的,如果不是,则克隆它。

然后,只需获得:

  • 类型
  • 通道
原始 Mat

和保存的顺序,每一个如4个字节,在一个缓冲区的开始。然后从原始的Matdata指针中追加适当的字节数并发送整个批次。

在接收端执行相反的操作...从缓冲区中读取前四个整数并创建相应大小的Mat并将其余数据加载到其中。


@Miki提供了一个极好的,相关的答案here这表明大部分的上面建议的技术细节 - 在Mat2str()str2Mat()专门研究。

我不会做太多的C++或MPI,我相信任何使用MPI或C++的人都可以收紧它,但以下工作原理和工作速度也非常快!

#include <cstdlib> 
#include <iostream> 
#include <iomanip> 
#include <ctime> 
#include <iostream> 
#include <string> 
#include <chrono> 
#include <thread> 
#include <opencv2/opencv.hpp> 
#include "opencv2/highgui/highgui.hpp" 
#include "mpi.h" 

using namespace std; 
using namespace cv; 

const int MAXBYTES=8*1024*1024; 
uchar buffer[MAXBYTES]; 

void matsnd(const Mat& m,int dest){ 
     int rows = m.rows; 
     int cols = m.cols; 
     int type = m.type(); 
     int channels = m.channels(); 
     memcpy(&buffer[0 * sizeof(int)],(uchar*)&rows,sizeof(int)); 
     memcpy(&buffer[1 * sizeof(int)],(uchar*)&cols,sizeof(int)); 
     memcpy(&buffer[2 * sizeof(int)],(uchar*)&type,sizeof(int)); 

     // See note at end of answer about "bytes" variable below!!! 
     int bytespersample=1; // change if using shorts or floats 
     int bytes=m.rows*m.cols*channels*bytespersample; 
cout << "matsnd: rows=" << rows << endl; 
cout << "matsnd: cols=" << cols << endl; 
cout << "matsnd: type=" << type << endl; 
cout << "matsnd: channels=" << channels << endl; 
cout << "matsnd: bytes=" << bytes << endl; 

     if(!m.isContinuous()) 
     { 
     m = m.clone(); 
     } 
     memcpy(&buffer[3*sizeof(int)],m.data,bytes); 
     MPI_Send(&buffer,bytes+3*sizeof(int),MPI_UNSIGNED_CHAR,dest,0,MPI_COMM_WORLD); 
} 

Mat matrcv(int src){ 
     MPI_Status status; 
     int count,rows,cols,type,channels; 

     MPI_Recv(&buffer,sizeof(buffer),MPI_UNSIGNED_CHAR,src,0,MPI_COMM_WORLD,&status); 
     MPI_Get_count(&status,MPI_UNSIGNED_CHAR,&count); 
     memcpy((uchar*)&rows,&buffer[0 * sizeof(int)], sizeof(int)); 
     memcpy((uchar*)&cols,&buffer[1 * sizeof(int)], sizeof(int)); 
     memcpy((uchar*)&type,&buffer[2 * sizeof(int)], sizeof(int)); 

cout << "matrcv: Count=" << count << endl; 
cout << "matrcv: rows=" << rows << endl; 
cout << "matrcv: cols=" << cols << endl; 
cout << "matrcv: type=" << type << endl; 

     // Make the mat 
     Mat received= Mat(rows,cols,type,(uchar*)&buffer[3*sizeof(int)]); 
     return received; 
} 

int main (int argc, char *argv[]) 
{ 
    // Initialise MPI 
    MPI::Init (argc,argv); 

    // Get our rank 
    int id = MPI::COMM_WORLD.Get_rank(); 
    if(id==0) 
    { 
     // MASTER - wait to receive image from slave and write to disk for checking 
     Mat received=matrcv(1); 
     imwrite("received.jpg",received); 
    }else{ 
     // Slave - read Mat from disk and send to master 
     Mat image=imread("image.jpg",IMREAD_COLOR); 
     matsnd(image,0); 
    } 

    // Terminate MPI 
    MPI::Finalize(); 
} 

我把循环10,000次迭代左右:

  • matsnd()的奴隶,
  • 在主

matrcv(),并花了1.9秒为10,000次重复。我无法比较,因为你没有显示任何时间。

所有cout声明是硬左对齐的只是调试的东西,可以安全地删除。

注:

虽然我已经使用并测试上面,因为我已经了解到,字节数的我送的计算可能会在某些情况下(也许那里有对齐限制)不正确。如果您有兴趣,请检查this answer

关键词:MPI,MPI_SEND,MPI_RECV,OpenCV的,垫,图像

+0

我在@Miki(我认为)的那一天看到了相关的答案,但不能找到它的时刻,它已经晚了,所以我明天再打猎,如果可以的话,添加一个链接。 –

+1

如果矩阵很大,用多个元素注册一个MPI结构数据类型会更便宜,并且使用它可以直接发送描述符和数据,而无需将所有内容都打包到一个数组中。在接收端,'MPI_Probe'和'MPI_Get_count'可用于确定数据的大小并用于预分配矩阵。 –

+1

这是我为类似的问题写的一段代码http://stackoverflow.com/questions/28782951/segmentation-fault-while-using-mpi-and-opencv-together/28794709#28794709发送大小和缓冲区由'im.data'指出它可能会激励你... – francis

相关问题