几个月前,我开始了一个项目,开发一种算法来处理从linescan相机设备获取的数据(例如,每300us一条384像素的线)。因为我是工程师而不是程序员,所以我开始使用Python来最小化学习曲线。在SX的帮助下,我成功地构建了一个Python应用程序(最终有2000多行代码),并成功地创建了一个图像处理算法来处理数据。我给客户留下了深刻的印象,他们希望能更上一层楼。现在,我需要它是实时的。这就意味着C++。我拿到了Koenig和Moo的加速C++并开始阅读。所以,请对我手下留情。我喜欢学习编程,但我没有接受过正式的培训。我已经尽我所能了!
现在,我有了一个C++原型图形用户界面(使用Qt),其中包含了通过CameraLink接口与相机通信所需的所有库。采集代码驻留在它自己的线程中,并向GUI发出信号。所以,我已经掌握了基础知识。我可以使用我当前的代码获取任意多行数据,但我现在正在尝试找出如何围绕这些构建应用程序。甚至编写了一个与Qt一起工作的自定义makefile (MOCing等)
无论如何,对于应用程序,我想要两种模式(以下是问题):
(1)“实时”视图...其中,行扫描数据由GUI实时显示。我在考虑使用循环缓冲区(例如,Boost::circular_buffer)来实时保存数据,并简单地传递缓冲区的副本(memcpy?)通过发射的信号发送到GUI。这能站得住脚吗?我觉得缓冲区的副本是必要的,因为循环缓冲区大约每300us就会改变一次,我不知道主事件循环是否能跟上。同样,数据采集存在于它自己的线程中。有必要比这更复杂吗?是否必须在读取数据时从缓冲区中弹出数据,而不是使用循环缓冲区?我觉得循环缓冲区是最好的选择,因为这正是我想要显示的图像类型。
(2)数据处理模式。其中行扫描数据以块(即,384×384)像素为单位发出。在300us (~3333 Hz)的扫描速率下,即每100ms左右为一个块或帧。在100ms内,我将需要对数据进行标准化、对象检测、阈值处理等。我计划在运行实时内核补丁Linux机器上运行这些操作。我认为它应该跟上。我需要在数据采集和数据处理线程之间进行通信...我需要套接字来做这个吗?
我在这里寻找关于如何开始使用这两个部分的建议。第二个更关键,但第一个将帮助我可视化正在发生的事情。最终,我希望同时运行这两种模式。我花了大半个星期才走到这一步...但需要确保我的计划走在正确的道路上。
发布于 2013-09-22 03:36:35
至(1):
对我来说很有意义。当从GUI代码访问相同的缓冲区时,您必须小心同步问题,否则,您的接收器代码。一种可能的改进是稍微限制GUI更新的数量。屏幕刷新率通常为50或60‘t,大多数GUI库都假定更新不会比这更频繁。
您还可以通过只复制屏幕上实际显示的内容来减少复制的数据量。因此,我建议稍微颠倒一下: GUI获得一个更新计时器(任何看起来足够好的计时器),它会根据需要从循环缓冲区中提取新的显示内容。这样就减少了许多不必要的(即不可见的)屏幕更新和缓冲区副本。
根据您的需要,您也可以只使用为问题的第2部分创建的块来进行屏幕更新。
To (2):首先,在使用多线程时,通常不需要套接字或类似的东西。
我建议使用类似线程池的方式进行处理:当新块可用时,将它们复制到任务对象(您定义的类,该类包含处理代码并实现线程池可以理解的接口),然后将其提供给线程池。
由于您使用的是Qt,因此我将在这一部分中使用QThreadPool和QRunnable。如果您需要以特定的顺序完成对块的处理,事情就会变得更加有趣。基本上,您将拥有一个阻塞队列数据结构,您还将向它提供QRunnable对象,然后另一个线程将它们从那里抓取,并等待每个对象按照它们启动的顺序完成。
这里的通信将仅限于数据采集线程,将输入分成块并启动任务。如果您还需要从数据处理任务控制数据采集线程,那么您可能需要一些不同的设计。
您也可能不使用实时内核补丁。如果你用来访问你的行扫描相机的库缓冲了它的输入,如果你错过了一个更新,你只会一个接一个地得到多行。同样,这取决于您需要反应的速度,但您正在对多行高的块进行图像处理,所以我认为您已经可以处理一些延迟。
埃塔:我刚刚重读了你的问题。因此,基本上每100ms只有384x384像素的块。我正要建议使用Qt信号,但您可能会遇到问题: Qt信号在线程之间通信时在内部使用阻塞队列数据结构。不幸的是,它们的实现不允许您设置大小限制,因此如果您的GUI线程或处理线程不能足够快地处理它们(例如,用户在GUI的模式对话框中),它们将被缓冲,并消耗内存。
相反,您可以使用类似以下内容:
Acquisition thread ==> (Blocking Queue) ==> Processing thread基本上,您的获取线程只是将块放入队列中。处理线程将在循环中从队列中抓取块,并将它们发送到GUI进行显示,然后对它们进行处理。或者相反,如果你想要可视化的话。
https://stackoverflow.com/questions/18935956
复制相似问题