Ответ 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 сделали это с некоторым успехом, но, очевидно, они не поделятся этим. Честно говоря, после изучения этой проблемы в течение нескольких недель, я понял, что для моих конкретных потребностей (и поскольку я не инженер компьютерных наук и не специалист по алгоритмам), больше стоит ждать несколько месяцев для лучших устройств, чем удары головой на стене, анализируя алгоритмы и разрабатывая код сбоку.
С наилучшими пожеланиями и удачи!