首先,通过“实时”,图像的图像处理在此应用程序中应该花费 0.1 秒或更短的时间。
在我们的应用程序中,除了主线程之外,还有三个线程正在运行。一个用于图像采集,第二个用于图像处理,第三个用于机器人。在两个线程之间,有一个图像队列要共享,因此当相机将图像入队和机器人将处理后的图像出队时,成像处理器将图像出队并将处理后的图像入队。您可能已经注意到的一个限制是,处理后的图像应该按顺序排列,这意味着图像的顺序与图像采集中的顺序相同。
是否有任何设计模式或最佳实践可应用于此架构。
首先,通过“实时”,图像的图像处理在此应用程序中应该花费 0.1 秒或更短的时间。
在我们的应用程序中,除了主线程之外,还有三个线程正在运行。一个用于图像采集,第二个用于图像处理,第三个用于机器人。在两个线程之间,有一个图像队列要共享,因此当相机将图像入队和机器人将处理后的图像出队时,成像处理器将图像出队并将处理后的图像入队。您可能已经注意到的一个限制是,处理后的图像应该按顺序排列,这意味着图像的顺序与图像采集中的顺序相同。
是否有任何设计模式或最佳实践可应用于此架构。
管道和过滤器模式非常适合此。
为了使用现有技术实现这一点,我看到处理大量数据的实时应用程序使用英特尔的线程构建块(TBB)。在 Thread Building Blocks Tutorial中,“在装配线上工作:管道”部分描述了一个类似的问题:
将使用一个简单的文本处理示例来演示使用管道和过滤器执行并行格式化。该示例读取一个文本文件,对文本中的每个十进制数字求平方,然后将修改后的文本写入一个新文件。[...] 假设原始文件 I/O 是连续的。平方滤波器可以并行完成。也就是说,如果您可以
n
非常快速地串行读取块,则可以并行转换每个n
块,只要它们以正确的顺序写入输出文件即可。
以及随附的代码:
void RunPipeline( int ntoken, FILE* input_file, FILE* output_file ) {
tbb::parallel_pipeline(
ntoken,
tbb::make_filter<void,TextSlice*>(
tbb::filter::serial_in_order, MyInputFunc(input_file) )
& tbb::make_filter<TextSlice*,TextSlice*>(
tbb::filter::parallel, MyTransformFunc() )
& tbb::make_filter<TextSlice*,void>(
tbb::filter::serial_in_order, MyOutputFunc(output_file) ) );
}
无论是否使用 TBB,它都可以作为管道和过滤器模式的一个很好的实现参考,将模式与算法分离,同时提供控制过滤器的数据顺序/线程的能力。
我认为你的方法是正确的。
可能的改进可能是线程池的使用,例如用于图像处理(特别是如果它需要比采集更多的时间)。您可以考虑 OpenMP 或 boost 线程池,或 boost::asio::io_service