Подтвердить что ты не робот

Как ускорить приложение 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());

            }

Но расчет по-прежнему слишком медленный, поэтому мне нужно найти еще один метод для снижения достоверности входного видеопотока. Или, если вы знаете другой способ ускорить его, не стесняйтесь делиться им со мной;)

Спасибо за ваше время и ответы

4b9b3361

Ответ 1

Но расчет по-прежнему слишком медленный, поэтому мне нужно найти другое метод уменьшения достоверности входного видеопотока.

Реальный ответ на этот вопрос гораздо ближе к "мало что можно сделать!" чем чем-либо еще. Мы должны признать, что мобильные телефоны еще не обладают такими мощными возможностями обработки, как любой рабочий стол. Большинство телефонов Android в мире по-прежнему используют предыдущие версии системы и, что самое главное, это одноядерные устройства, они синхронизируются со скоростью ниже 1 ГГц, они имеют ограниченную память, bla bla...

Тем не менее, вы всегда можете что-то сделать, чтобы улучшить скорость с небольшими изменениями в производительности.

Теперь я также вычисляю OpenCV SURF на GalaxyS, и у меня частота кадров 1,5 кадра в секунду для 200 функций с hessian порогом в 1500 в изображении 320x240. Я признаю, что это дрянная производительность, но в моем случае мне приходится вычислять функции каждый раз в то время, так как я измеряю оптический поток для целей отслеживания. Однако очень странно, что вы можете получить только 1 кадр каждые 4-5 секунд.

1) Во-первых, мне кажется, что вы используете VideoCapture для получения кадров камеры. Ну, я не. Я использую реализацию камеры Android. Я не проверял, как VideoCapture реализован в Java-порту OpenCV, но, похоже, он медленнее, чем использование реализации в некоторых учебниках. Тем не менее, я не могу быть уверен в этом на 100%, так как я его не тестировал. Вы?

2) Сократите нативные вызовы до минимума. Явные вызовы Java OpenCV являются дорогостоящими. Кроме того, следуйте всем рекомендациям, указанным на странице Android-OpenCV.. Если у вас несколько внутренних вызовов, присоедините их все в одном вызове JNI.

3) Вы также должны уменьшить размер изображения и увеличить порог sssf hessian. Это, однако, уменьшит количество обнаруженных функций, но они будут более сильными и более надежными с точки зрения распознавания и сопоставления. Вы правы, когда говорите, что SURF - более надежный детектор (он также самый медленный, и он запатентован). Но, если это не мертвый замок для вас, я бы рекомендовал использовать новый детектор ORB, вариант BRIEF, который лучше работает с точки зрения вращения. ORB имеет недостатки, хотя, например, ограниченное количество обнаруженных ключевых точек и плохую инвариантность шкалы. Это - очень интересный отчет о сравнении алгоритмов детекторов признаков. Это также говорит о том, что детектор SURF медленнее в новой версии OpenCV 2.3.1, возможно, из-за некоторых изменений в алгоритме, для повышения надежности.

4) Теперь забавные биты. Архитектура процессора ARM (в которой базируется большинство телефонов на базе Android) широко известна для медленных вычислений с плавающей запятой, в которых алгоритмы детектирования признаков сильно зависят. очень интересные обсуждения об этой проблеме, и многие говорят, что вы должны использовать вычисления с фиксированной точкой, когда это возможно. Новая архитектура armv7-neon обеспечивает более быстрые вычисления с плавающей запятой, но не все устройства поддерживают ее. Чтобы проверить, поддерживает ли ваше устройство, запустите adb shell cat proc/cpuinfo. Вы также можете скомпилировать свой собственный код с директивами NEON (LOCAL_ARM_NEON := true), но я сомневаюсь, что это будет полезно, поскольку, по-видимому, несколько подпрограмм OpenCV оптимизированы NEON. Таким образом, единственный способ увеличить скорость с этим - это перестроить код с помощью NEON intrinsics (для меня это совершенно неисследованное основание, но вы можете найти его достойным внимания). В группе android.opencv было предложено, что в будущих выпусках OpenCV будет больше библиотек, оптимизированных для NEON. Это может быть интересно, однако я не уверен, стоит ли над этим работать или ждать более быстрых процессоров и оптимизированных систем с использованием графических процессоров. Следует отметить, что системы Android < 3.0 не используют встроенное аппаратное ускорение.

5) Если вы делаете это в академических целях, убедите ваш университет купить вам лучшее устройство ^^. В конечном итоге это может быть лучшим вариантом для более быстрого обнаружения функции SURF. Другой вариант - переписать алгоритмы. Я знаю, что некоторые ребята из лабораторий Intel сделали это с некоторым успехом, но, очевидно, они не поделятся этим. Честно говоря, после изучения этой проблемы в течение нескольких недель, я понял, что для моих конкретных потребностей (и поскольку я не инженер компьютерных наук и не специалист по алгоритмам), больше стоит ждать несколько месяцев для лучших устройств, чем удары головой на стене, анализируя алгоритмы и разрабатывая код сбоку.

С наилучшими пожеланиями и удачи!

Ответ 2

Вам нужно использовать функцию/дескриптор SURF для вашего приложения? SURF привлекателен, так как он подходит очень хорошо, но, как вы выяснили, он несколько медленный. Если вы просто отслеживаете точки через видео, вы можете сделать предположение, что точки не будут сильно отличаться от кадра к кадру, поэтому вы можете обнаружить и сопоставить углы Harris/FAST, а затем фильтровать совпадения, чтобы они были действительными только в том случае, если они находятся внутри радиус x-пикселя исходной точки?

OpenCV имеет (хотя и несколько ограниченный) выбор детекторы функций и дескрипторы-экстракторы и описатели дескрипторов, было бы интересно исследовать параметры, если вы еще этого не сделали.