如何加速我的Android-openCV应用程序?

时间:2011-10-27 13:32:23

标签: android opencv

我已经实现了一个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());

            }

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

感谢您的时间和答案

2 个答案:

答案 0 :(得分:37)

  

但计算仍然太慢,所以我需要找另一个   减少输入视频流质量的方法。

这个问题的真正答案更接近于“没有太多你可以做的!”而不是别的什么。我们必须承认,手机还没有像任何桌面那样强大的处理能力。世界上大多数Android手机仍然使用以前版本的系统,最重要的是:它们是单核设备,时钟频率低于1GHz,内存有限,bla bla ...

尽管如此,总有一些事情可以通过改变性能来提高速度。

现在,我也计算了GalaxyS上的OpenCV SURF,我对200个特征的帧速率为1.5 fps,在320x240图像中,粗糙度阈值为1500。我承认这是糟糕的性能,但在我的情况下,我只需要偶尔计算一些功能,因为我正在测量光流用于跟踪目的。然而,非常奇怪的是,你每4-5秒只能获得1帧。

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

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

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

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系统< 3.0 do not use built-in hardware acceleration

5)如果你出于学术目的这样做,说服你的大学给你买一台更好的设备^^。这可能最终是更快的SURF特征检测的最佳选择。另一种选择是重写算法。我知道英特尔实验室的一些人做了这件事,取得了一些成功,但显然他们不会分享它。 老实说,在调查了这个问题几个星期之后,我意识到,根据我的具体需求,(因为我不是计算机科学工程师也不是算法专家),等待几个月来获得更好的设备更有价值,而不是敲打我的脑袋。在墙上解剖算法和开发近汇编代码。

祝你好运!

答案 1 :(得分:2)

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

OpenCV对feature detectors以及descriptor extractorsdescriptor matchers的选择(尽管有些限制),如果你还没有,那么值得调查这些选项。