Одновременный просмотр и обработка камеры

Я разрабатываю приложение, которое имеет конвейер обработки OpenGL (коллекция шейдеров), и одновременно требует, чтобы конечный пользователь просматривал предварительный просмотр необработанной камеры.

Для примера предположим, что вы хотите показать пользователю предварительный просмотр камеры и в то же время подсчитать количество красных объектов в сценах, которые вы получаете с камеры, но любые шейдеры, которые вы используете, для подсчета объектов, таких как фильтрация оттенков, И т. Д. Не должны быть видны пользователю.

Как я могу правильно настроить это?

Я знаю, что я могу настроить предварительный просмотр камеры, а затем на данные кадровой камеры, получающей обратную связь, в формате YUV, а затем сбрасывать их в текстуру OpenGL и обрабатывать этот кадр тем самым, что связано с проблемами производительности, связанными с ним. Мне нужно округлить данные с аппаратного обеспечения камеры на виртуальную машину, а затем передать ее обратно в память GPU. Я использую SurfaceTexture чтобы получить данные с камеры непосредственно в понятном формате OpenGL и передать это моим шейдерам, чтобы решить эту проблему.

Я думал, что смогу показать этому же необработанному SurfaceTexture конечному пользователю, но TextureView не имеет конструктора или сеттера, где я могу передать ему SurfaceTexture я хочу отобразить. Он всегда создает свои собственные.

Это обзор моей текущей настройки:

  • GLRenderThread: этот класс распространяется от Thread, настраивает контекст OpenGL, отображение и т. Д. И использует SurfaceTexture в качестве поверхности (третий параметр eglCreateWindowSurface).
  • GLFilterChain: коллекция шейдеров, которые выполняют обнаружение на входной текстуре.
  • Камера: используется отдельная SurfaceTexture, которая используется как вход GLFilterChain и захватывает предварительный просмотр камеры
  • Наконец, TextureView, который отображает SurfaceTexture GLRenderThread

Очевидно, что с этой настройкой я показываю обработанные кадры для пользователя, который не то, что я хочу. Кроме того, обработка кадров не выполняется в режиме реального времени. В принципе, я запускаю вход с камеры через цепочку один раз, и как только все фильтры сделаны, я вызываю updateTexImage, чтобы захватить следующий кадр из камеры. На Nexus 4 моя обработка составляет около 10 кадров в секунду.

Я чувствую, что мне, вероятно, нужно использовать 2 контекста GL, один для предварительного просмотра в реальном времени и один для обработки, но я не уверен. Я надеюсь, что кто-то сможет подтолкнуть меня в правильном направлении.

Solutions Collecting From Web of "Одновременный просмотр и обработка камеры"

Можете ли вы загрузить часть кода, который вы используете?

Вы могли бы вызвать glDrawArrays на текстуре, созданной для привязки к поверхности, которую вы используете для предварительного просмотра предварительного просмотра, и затем очистить ее и связать отдельную текстуру с другой текстурой, чтобы выполнить анализ? что-то вроде

 GLES20.glUseProgram(simpleProgram); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glUseProgram(crazyProgram); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[1]); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

Где предварительный просмотр surfacetexture камеры привязан к текстурам [0], а затем отдельная структура surfacetexture, созданная для текстуры [1]

может быть?

Если ваша обработка работает медленнее, чем в реальном времени, тогда ответ прост: просто держите исходную текстуру камеры нетронутой, вычислите обработанное изображение на другую текстуру и покажите как пользователю, бок о бок в одном GLView. Сохраняйте один поток, так как вся обработка происходит на GPU в любом случае. Здесь много осложнений.

Количество шагов обработки не имеет большого значения, так как может быть произвольное количество промежуточных текстур (также см. Ping-ponging), которые никогда не отображаются пользователю – никто и ничто не заставляет вас это делать.

Понятие реального времени, вероятно, путается здесь. Просто подумайте о кадре, как о неотвратимом временном снимке. Поступая таким образом, вы проигнорируете задержку, которую требуется для того, чтобы изображение переместилось с камеры на экран, но если вы можете сохранить его при интерактивной частоте кадров (например, по меньшей мере 20 кадров в секунду), тогда это может быть в основном игнорируются.

С другой стороны, если ваша обработка происходит намного медленнее, вам нужно сделать выбор между введением задержки в подаче камеры и обработкой только каждого N-го кадра или поочередно отображать каждый кадр камеры в реальном времени и оставлять отставание следующего обработанного кадра , Для этого вам, вероятно, понадобится два отдельных контекста рендеринга, чтобы включить асинхронную обработку, что может быть потенциально трудно сделать на Android (или, может быть, так же просто, как создать второй GLView, поскольку вы можете жить без обмена данными между контекстами).