在不同进程之间传输 cv::Mat 对象的最佳方法是什么?

What is the best way to transfer a cv::Mat object between different processes?

我正在尝试将几个 cv::Mat 对象从一个程序传递到另一个程序,两者都是用 C++ 实现的,最好是 运行 并行。 cv::Mat 里面没有图片,所以 imread 和 imwrite 在这里没有用(我们不能用传统的图片压缩方法来压缩数据)。一种解决方案是将矩阵写入文件(例如CSV文件),但由于程序处理的信息太多,磁盘将成为瓶颈,此外,我很快就会运行 out disk space.

经过一番挖掘,我发现管道(名称或未命名)是一个有用的解决方案。我写了两个试验程序: Producer.cpp:

int main(int argc, char* argv[])
{       
        Mat image;
        image = imread(argv[1]);
        cout << image;
        cout.flush();
        return 0;
}

Consumer.cpp:

int main(int argc, char* argv[])
{       
        Mat image;
        cin >> image;
        imshow("Image", image);
        waitKey();
        return 0;
}

令人惊讶的是,第二个程序无法编译。

mismatched types ‘_CharT2*’ and ‘cv::Mat’ cin >> image;

这意味着(我猜)“>>”运算符没有为 cv::Mat 超载。尽管我们可以覆盖 >> 运算符,但由于矩阵很大,而且 stdin 和 stdout 是基于文本的,所以这不是最好的方法,也不是最简单的方法。

那么,回到主要问题:将 cv::Mat 对象(或可能的任何其他二进制对象)从一个程序传递到另一个程序的最佳方式是什么?

将文件写入磁盘,并记得在完成后立即将其删除。文件缓存会延迟物理写入,快速删除会阻止物理写入。

或者,存储数据是共享内存。

Mat(或任何其他对象)应该以某种方式序列化。在 opencv 中序列化的简单方法是使用 FileStorage。这是示例代码:

制作人:

int main(int argc, char* argv[])
{
    Mat image;
    image = imread(argv[1]);
    FileStorage fs("temp", FileStorage::WRITE);
    fs << "MyImage" << image;
    return 0;
}

消费者:

int main(int argc, char* argv[])
{
    Mat image;
    FileStorage fs("temp", FileStorage::READ);
    fs["MyImage"] >> image;
    imshow("Image", image);
    waitKey();
    return 0;
}

其中 "temp" 是存储数据的文件名。在不使用文件系统的情况下并行 运行 这些程序的最佳方法是在适当的位置定义命名管道 "temp",然后 运行 并行执行程序:

>mkfifo temp
>./producer testFile.jpg | ./consumer

这样不使用磁盘,程序可以运行并行。

fileStorage将Mat的二进制内容改为ascii,比较耗时。人们可能决定按照解释 以二进制形式序列化内容,并使用命名管道。