如何使用阻塞队列在后台处理相机Feed?

时间:2012-08-31 12:48:08

标签: java android multithreading thread-safety blockingqueue

我在处理Android应用程序中的摄像头时遇到了问题'人脸检测''。

我想做什么:

- 我有一个活动,可以在surfaceView(UI线程)

中连续显示手机摄像头

- 为了避免性能问题,我将一个surfaceview放在顶部,使用OpenCv在检测到的面上绘制矩形(这是在线程中运行,比如thread2)

- 我正在尝试将Direct Feed图像的副本传递给Thread2,以便线程2可以执行检测并在覆盖表面上绘制

我现在的位置:

- 我正在考虑使用带有阻塞队列的线程,以便UIthread可以使用BlockingQueue.add(..)将Image放入BlockingQueue,并且Thread2可以获取BlockingQ中的图像,处理它并检测面在背景中

条件:   我想要UI线程,而不是等待,以便在显示器上看到uniterupted feed。它只需要放置图像然后无需等待其他任何东西它可以去获取下一个feed并重复进程

目前我正在使用一个实现Runnable接口的新类,它有两个方法putImage(bitmap)和getImage()使用blockingQueue来放置和获取图像。由UIthread调用.putImage()由thread2调用getImage() / p>

问题:   当我继续将图像放到阻塞队列时,Thread2无法访问blockingQ(Itsblocked),并且由于UI线程应该不间断地运行,我不能在主线程中调用wait()或sleep()。

Thread2有没有办法从队列中获取此图像而不会阻塞MainThread ???

1 个答案:

答案 0 :(得分:1)

这里有一个典型的生产者 - 消费者问题。你的制作人应该是主线程。消费者是检测面部的消费者。消费者必须在不同的线程中运行。不需要处理队列的单独线程,它可以是生产者和消费者可访问的任何地方。
这样,除非你的队列有界,否则不应该有任何阻塞。默认LinkedBlockingQueue几乎是无限制的。
要在不阻塞的情况下访问现成产品,您可以执行以下操作:声明另一个将保存已完成任务结果的队列。面部处理器将是它的生产者,主线程将是消费者。让处理器按原样填充它,主线程定期检查它是否有现成的产品。如果发现结果队列不为空,则可以通知用户或执行任何操作。