5

我正在使用 OpenCV 来检测图像。这是我的问题:我的函数detect_image(mRgba)需要一些时间来执行操作并给出一些结果。虽然功能正在计算相机预览被冻结,因为它只在代码到达时显示图像return inputFrame.rgba()我想知道如何使这些操作并行,当相机预览以正常速度工作时,功能将在后台计算。

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
detect_image(mRgba);
return inputFrame.rgba();
}
4

1 回答 1

10

为了体验并行化,简单的方法是使用 AsyncTask 来处理图像:

AsyncTask 参考页面

更友好的介绍可以在这里找到:

http://android-developers.blogspot.co.il/2010/07/multithreading-for-performance.html

而这:

http://developer.att.com/developer/forward.jsp?passedItemId=11900176

是对 Android 上多线程的全面介绍。

如果你想开始,一个简单的算法应该是这样的:

  • 从您的“onCameraFrame”方法中检查您是否有一个 AsyncThread 用于处理已经运行的图像
  • 如果答案是“是”,只需在预览窗口中显示 mRgba 并返回
  • 如果答案是“否”,则启动一个新的 AsyncThread 并让它在 mRgba 上运行“detectImage”,确保结果保存在 onPostExecute 方法中。

使用此算法,如果您的系统可以在以 60fps 进行预览时每秒检测 4 张图像(例如),您将能够在单个处理器设备上获得流畅的视频,其中大约每 20-30 帧有一个新结果,在实际假设 detect_image 是 CPU 密集型的,而相机预览/显示是 I/O 密集型的。

   捕获:xxxxxxxxxxxxxxxxxxxxx...
   处理:1.......1........1.......1......1........1....
                时间------------------------------------>

从 HoneyComb 开始,一种更精细的方法是考虑 CPU 中的内核数量(多核手机/平板电脑变得越来越普遍)并并行启动 N 个 AsyncTask(每个内核一个),为每个内核提供不同的预览图像一个(也许使用线程池......)。

如果您通过固定延迟(大约为 detectImage/N 的持续时间)将每个线程分开,您应该得到一个恒定的结果流,其频率应该是单线程版本的倍数。

   捕获:xxxxxxxxxxxxxxxxxxxxx...
   处理:1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4....
                时间------------------------------------>

希望这可以帮助

于 2013-04-04T00:10:27.447 回答