我试图将一对cv :: Mat对象从一个程序传递到另一个程序,这两个程序都是用C ++实现的,最好是并行运行。 cv :: Mat中没有图像,因此imread和imwrite在这里没用(我们不能用传统的图像压缩方法压缩数据)。一种解决方案是将矩阵写入文件(例如CSV文件),但由于程序处理的信息太多,磁盘将成为瓶颈,此外,我很快就会耗尽磁盘空间。
经过一番挖掘后,我发现管道(名称或未命名)是一种有用的解决方案。我写了两个试点项目: 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;
}
令人惊讶的是,第二个程序无法编译。
不匹配的类型'_CharT2 *'和'cv :: Mat' cin&gt;&gt;图像;
这意味着(我猜)“&gt;&gt;” cv :: Mat没有重载运算符。即使我们可以覆盖&gt;&gt;运算符,因为矩阵很大,而stdin和stdout是基于文本的,所以它不是最简单的方法。
那么,回到主要问题:将cv :: Mat对象(或可能是任何其他二进制对象)从一个程序传递到另一个程序的最佳方法是什么?
答案 0 :(得分:2)
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”是存储数据的文件名。在不使用fileSystem的情况下并行运行这些程序的最佳方法是在并行运行程序之前,在适当的位置定义命名管道“temp”:
>mkfifo temp
>./producer testFile.jpg | ./consumer
这样就不会使用磁盘,程序可以并行运行。
fileStorage将Mat的二进制内容更改为ascii,这非常耗时。可以决定按照here解释的二进制序列化内容,并使用命名管道。
答案 1 :(得分:0)
将文件写入磁盘,并记得在完成后立即将其删除。文件缓存会延迟物理写入,快速删除会阻止物理写入。
或者,存储数据是共享内存。