【问题标题】:Multithreaded real time camera processing in AndroidAndroid中的多线程实时相机处理
【发布时间】:2014-03-31 07:38:08
【问题描述】:

目标是在 Android 设备的实时预览中进行实时图像处理。这已经在这里解决了很多次,并且在网络上有一些提及(请参阅问题末尾的参考资料),但是,我还没有找到一个关于适当的多线程框架来完成此任务的建议。

据我了解,要正确使用多线程(以及具有多个物理内核的设备),需要实现以下功能:

  1. 在 UI 线程 (onCameraPreview) 上调用帧处理程序并将帧数据排入共享队列 @9​​87654336@。
  2. n 线程池等待Q。每个线程都会在可用时取出一个帧,执行“繁重”的图像处理并将结果发送到 UI 线程。

我的主要问题是以上是否是正确的方向,以及如何在 Android 上实现它。此外,如果图像处理必须以串行方式完成 - 即在任何给定时间处理的帧不超过 1 帧,但仍然在与主线程不同的线程上完成处理,则需要进行哪些修改。


更新 1:
我最终将其实现为AsyncTask,它接收原始帧数据作为输入并使用onPostExecute 回调来更新UI。但是,这种情况大约每秒发生 10 次,这让我想知道它是否不会产生太多开销。这就是为什么,就我而言,这个问题仍然有待验证,这确实是最有效的方法。此外,我仍然不清楚如何将这种方法扩展到多核上的多个工作线程。


相关问题:
- Video processing in Android
- Android Camera Frame processing with MultiThreading
- Android: How to record video and process its frames in real time?
- Processing Android camera frames in real time
- Ways of getting high FPS for real time computer vision processing
- Multithreading in openCV4Android
- Android: Real Time Image Processing
- Android video frame processing
- Simultaneous camera preview and processing
- Real Time Image Processing in Android using the NDK
- Android Camera Preview filtering
- How to show real time filtered camera preview while recording videos?

还有链接:
http://ibuzzlog.blogspot.co.il/2012/08/how-to-do-real-time-image-processing-in.html

【问题讨论】:

  • 如果有人可以提供帮助,我仍在寻找这个问题的答案......如果有人发现问题不够清晰,我很乐意编辑/添加信息。
  • 一个滑倒我的研究并准确回答我的问题的 SO 问题是 here
  • Stav,我正在尝试一些非常相似的东西并找到了你的帖子。我还阅读了您说回答了您的问题的 SO 帖子,但无法理解其中的重要部分,所以我问了他一个问题。然后意识到你肯定已经解决了这个问题,因为你最近发布的时间比他要多得多,也许你可以帮助我。他写道“以固定的延迟分隔每个线程”。如果内核并行处理,为什么会有帮助?无论如何,您如何将每个线程分开一个固定的延迟?一旦你启动一个线程,它不就在不考虑它何时相对于其他线程产生的情况下运行吗?
  • 嗯,我还没有实现它,我认为@Rick77 的答案没有回答的真正悬而未决的问题是如何确切地 实现线程池。但是,根据您的问题 - 延迟对性能没有帮助 - 但对于大多数用例来说可能更有意义。如果您的处理返回给用户一些关于当前帧的有意义的答案,那么您会希望这些答案在时间上均匀分布。这是让用户感觉处理已完成的最有效方式

标签: java android multithreading video-processing


【解决方案1】:

Android 文档指出,使用 byte[] 数组对“onPreviewFrame()”的调用不能放入队列或其他东西中,因为每次调用后都会重复使用该数组。必须尽快返回调用以获得更好的帧速率。

这就是你可以做的(我做到了,得到了 29 FPS)

  1. 通过 JNI 调用将数组传递给原生 c 或 c++ 库

  2. 在你的 C 程序中实现一个队列并 malloc 一个节点来存储这个数组

  3. 内存复制数组并返回调用。

  4. 然后回电

  5. 使用一些编码器,例如 FFMPEG

  6. 并行运行此排队过程和编码过程,以便在对帧进行编码后,您可以将其从内存中清除,以防止内存溢出。

  7. 并记得选择最佳分辨率,以便您的编码器与输入帧速率的速度相匹配,从而不会因队列而导致内存溢出。

【讨论】:

  • 感谢您的回答,但是,我希望仅在 Java 中执行此操作。挑战是实现一个适当的线程池,该线程池适用于您描述的队列。此外,虽然我觉得我知道通用框架应该是什么样子,但我对实现细节更感兴趣 - 即使用哪些线程工具等。
猜你喜欢
  • 2011-08-03
  • 2012-11-06
  • 2011-12-28
  • 1970-01-01
  • 2012-03-31
  • 2020-02-02
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多