Как применить «фильтры» к AVCaptureVideoPreviewLayer - PullRequest
29 голосов
/ 01 марта 2011

Мое приложение в настоящее время использует AVFoundation для получения необработанных данных камеры с задней камеры iPhone и отображения их на AVCaptureVideoPreviewLayer в режиме реального времени.

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

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

Это единственный способ достичь моей цели?

Как я уже упоминал, я не собираюсь снимать видео AVCaptureSession, просто предпросмотрю его.

Ответы [ 2 ]

66 голосов
/ 01 марта 2011

Вероятно, наиболее эффективный способ справиться с этим - использовать OpenGL ES для фильтрации и отображения этих видеокадров.Вы не сможете многое сделать напрямую с AVCaptureVideoPreviewLayer, кроме настройки его непрозрачности при наложении на другой вид или слой.

У меня есть пример приложения здесь , где я беру кадры изкамеру и применять шейдеры OpenGL ES 2.0 для обработки видео в реальном времени для отображения.В этом приложении (подробно объясненном здесь ) я использовал цветовую фильтрацию для отслеживания объектов на виде с камеры, но другие модифицировали этот код, чтобы сделать некоторые аккуратные эффекты обработки видео.Все фильтры на основе графического процессора в этом приложении, отображаемые на экране, работают на скорости 60 кадров в секунду на моем iPhone 4.

Единственное iOS-устройство, поддерживающее видео, но не имеющее GPU с поддержкой OpenGL ES 2.0,это iPhone 3G.Если вам необходимо настроить таргетинг на это устройство, вы можете взять базовый код для захвата видео и генерации текстур OpenGL ES, а затем использовать код фильтра из образца приложения Apple GLImageProcessing .Это приложение построено на основе OpenGL ES 1.1, поддержка которого присутствует на всех устройствах iOS.

Однако я настоятельно рекомендую рассмотреть возможность использования OpenGL ES 2.0 для этого, поскольку вы можете использовать гораздо большеэффект с использованием шейдеров, чем с помощью фиксированной функции OpenGL ES 1.1 pipe.

(Редактирование: 13.02.2012) В качестве обновления вышеизложенного я создал инфраструктуру с открытым исходным кодом под названием GPUImage , который инкапсулирует этот вид пользовательской фильтрации изображений.Он также обрабатывает захват видео и выводит его на экран после фильтрации, для чего требуется всего шесть строк кода.Чтобы узнать больше о фреймворке, вы можете прочитать мой более подробный анонс .

3 голосов
/ 19 октября 2015

Я бы порекомендовал посмотреть на пример Rosy Writer из библиотеки разработки ios. Библиотека GPUImage Брэда Ларсона довольно хороша, но кажется немного излишней в этом вопросе.

Если вы просто заинтересованы в добавлении шейдеров OpenGL (aka Filters) в AVCaptureVideoPreviewLayer, рабочий процесс должен отправить выходные данные сеанса захвата в представление OpenGL для рендеринга.

AVCaptureVideoDataOutput *videoOut = [[AVCaptureVideoDataOutput alloc] init];
videoOut.videoSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(_renderer.inputPixelFormat) };
[videoOut setSampleBufferDelegate:self queue:_videoDataOutputQueue];

Затем в делегате captureOutput: отправьте пример буфера в OpenGL Renderer

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    CVPixelBufferRef sourcePixelBuffer = CMSampleBufferGetImageBuffer( sampleBuffer );
    _renderer copyRenderedPixelBuffer:sourcePixelBuffer];
}

В OpenGL Renderer прикрепите sourcePixelBuffer к текстуре, и вы можете отфильтровать ее в шейдерах OpenGL. Шейдер - это программа, которая запускается на основе пикселей. Пример Rosy Writer также показывает примеры использования различных методов фильтрации, отличных от OpenGL.

...