【问题标题】:How can I speed Up my Android-openCV application?如何加速我的 Android-openCV 应用程序?
【发布时间】:2011-12-16 12:36:42
【问题描述】:

我已经实现了一个 openCV 应用程序,其中我使用了 SURF 描述符。它工作正常,代码如下所示:

我减小输入视频流的大小以加快速度

            capture.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, display.getWidth());
            capture.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, display.getHeight());

            capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

            try{

          //-- Step 1: Detect the keypoints using SURF Detector

            surfDetector.detect( mRgba, vector1 );

            for (KeyPoint t : vector1)
                Core.circle(mRgba, t.pt, 10, new Scalar(100, 100,100));    

          //-- Step 2: Calculate descriptors (feature vectors)
            //extractor.compute(mRgba, vector1, descriptor1);

          //-- Draw matches
            //Mat img_matches;
            //drawMatches( mRgba, vector1, mRgba, vector1, matches, img_matches );


            }catch(Exception e){
                Log.e( "ERROR", e.toString());

            }

但是计算仍然太慢,所以我需要找到另一种方法来降低输入视频流的质量。或者,如果您知道另一种加快速度的方法,请随时与我分享;)

感谢您的时间和回答

【问题讨论】:

  • 你的帧率是多少?
  • 我没有设置它是默认值,但我不知道如何设置它,或者性能/视觉的最佳值是什么
  • 但是如果你想要输出视频 FPS,它是每 4-5 秒 1 帧,所以这太可怕了
  • 您是否进行了分析?我认为来自 davlik 的本地调用非常昂贵。访问从相机应用程序分配的映射内存也非常昂贵
  • 我不是很明白你的问题,但答案是不会的。

标签: android opencv


【解决方案1】:

但是计算还是太慢了,所以我需要再找一个 降低输入视频流质量的方法。

这个问题的真正答案更接近于“你无能为力!”胜过其他任何事情。我们必须承认,手机还没有像任何台式机那样强大的处理能力。世界上大多数 Android 手机仍在使用以前版本的系统,最重要的是:它们是单核设备,主频低于 1GHz,内存有限,bla bla...

尽管如此,您始终可以采取一些措施来提高速度,而性能几乎没有变化。

现在,我还在 GalaxyS 上计算 OpenCV SURF,在 320x240 图像中,200 个特征的帧速率为 1.5 fps,hessian 阈值为 1500。我承认这是糟糕的性能,但在我的情况下,我只需要每隔一段时间计算一次特征,因为我正在测量光流以进行跟踪。但是,每 4-5 秒只能获取 1 帧,这很奇怪。

  1. 首先,在我看来,您正在使用 VideoCapture 来获取相机帧。好吧,我不是。我正在使用 Android 相机实现。我没有检查如何在 OpenCV 的 Java 端口中实现 VideoCapture,但它似乎比使用某些教程中的实现要慢。但是,我不能 100% 确定这一点,因为我还没有测试过。有吗?

  2. 尽可能减少本机调用。 Java OpenCV 本地调用非常耗时。此外,请遵循Android-OpenCV best practices page 中指定的所有准则。如果您有多个本机调用,请将它们全部加入一个 JNI 调用中。

  3. 您还应该减小图像大小并增加 SURF hessian 阈值。然而,这会减少检测到的特征的数量,但它们会更强大、更健壮,以用于识别和匹配。当您说 SURF 是更强大的检测器时,您是对的(它也是最慢的,并且已获得专利)。但是,如果这对您来说不是死锁,我建议使用新的 ORB 检测器,它是 BRIEF 的一种变体,在旋转方面表现更好。但 ORB 也有缺点,例如检测到的关键点数量有限和尺度不变性差。 This 是一份非常有趣的特征检测算法比较报告。它还表明 SURF 检测器在新的 OpenCV 2.3.1 版本中速度较慢,可能是由于算法的一些变化,以提高鲁棒性。

  4. 现在是有趣的部分。 ARM 处理器架构(大多数 Android 手机都基于该架构)因其处理浮点计算的速度慢而被广泛报道,其中特征检测算法严重依赖于浮点计算。关于这个问题已经有very interesting discussions,许多人说你应该尽可能使用定点计算。新的 armv7-neon 架构提供更快的浮点计算,但并非所有设备都支持它。要检查您的设备是否支持它,请运行adb shell cat proc/cpuinfo。您也可以使用 NEON 指令 (LOCAL_ARM_NEON := true) 编译您的本机代码,但我怀疑这会带来什么好处,因为显然很少有 OpenCV 例程经过 NEON 优化。因此,提高速度的唯一方法是使用 NEON 内在函数重建代码(这对我来说完全是未开发的领域,但您可能会发现它值得一看)。在 android.opencv 组it was suggested 中,未来的 OpenCV 版本将有更多的 NEON 优化库。这可能很有趣,但是我不确定是否值得继续努力或等待更快的 CPU 和使用 GPU 计算的优化系统。请注意,Android 系统 do not use built-in hardware acceleration.

  5. 如果您这样做是出于学术目的,请说服您的大学为您购买更好的设备 ^^。这最终可能是更快的 SURF 特征检测的最佳选择。另一种选择是重写算法。我知道英特尔实验室的一些人做到了,并取得了一些成功,但显然他们不会分享。 老实说,在对这个问题进行了几周的调查之后,我意识到对于我的特定需求(而且因为我既不是计算机科学工程师也不是算法专家),等待几个月以获得更好的设备比敲打我的头更有价值在墙上剖析算法并开发近乎汇编的代码。

【讨论】:

  • Ievgen Khvedchenia 对此主题的更多有趣见解:computer-vision-talks.com/2012/04/reader-questions-1
  • 欢迎来到 2015 年,我们拥有多达 8 个内核的设备
  • @DmitryZaitsev 然而,OpenCV 的 warpPerspective 在 Snapdragon 800 四核 2.3GHz 和 2GB RAM 上将图像变形到 920x720 的目标尺寸需要大约 250 毫秒。见:stackoverflow.com/questions/32880842/…
  • 我还遇到了一些在 Snapdragon 上检测角点的 OpenCV 函数的帧速率非常慢。我打算试一试FastCV。这里有人介绍 FastCV 吗?
  • @jairobjunior 是的。我试过使用它,老实说,它是一个非常难以使用的工具——文档非常有限。另外,从 v1.7.1 开始,只提供了一个 ML api; SVM 分类器。
【解决方案2】:

您需要为您的应用程序使用 SURF 功能/描述符吗? SURF 很有吸引力,因为它匹配得非常好,但是你发现它有点慢。如果您只是通过视频跟踪点,您可以假设点不会因帧而变化很大,因此您可以检测并匹配 Harris/FAST 角,然后过滤匹配仅当它们在范围内时才有效原点的 x 像素半径?

OpenCV 有 feature detectorsdescriptor extractorsdescriptor matchers 的选择(尽管有些有限),如果您还没有研究这些选项,那么值得研究一下。

【讨论】:

  • 是的,我知道,但 SURF 更健壮,我可以使用 FAST 或 Harris Corner...但问题是如何加快使用 SURF 的代码
猜你喜欢
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
相关资源
最近更新 更多