Создание Android приложения для обнаружения лиц в режиме реального времени с использованием Firebase ML Kit

Создание Android приложения для обнаружения лиц в режиме реального времени с использованием ML Kit

В начале этого года Google представил новый продукт: Firebase Machine Learning Kit. ML Kit позволяет эффективно использовать возможности машинного обучения в Android и iOS приложениях. В этом посте я буду рассказывать о том, как с его помощью создать Android приложение для обнаружения лиц в реальном времени.

Обнаружение лиц — это только одна из возможностей компьютерного зрения, которую предлагает Firebase ML Kit (или, вернее, облегчает её использование). Это функция, которая может быть полезна во многих приложениях: подписывание людей на фотографиях, работа с селфи, добавление эмоджи и других эффектов во время съёмки, фотографирование только тогда, когда все улыбаются с открытыми глазами, и т.д. Возможности безграничны.

Мы уже публиковали статьи о других функциях Firebase ML Kit:

Однако, реализовать детектор лиц в собственном приложении по-прежнему нелегко. Нужно понять, как работает API, какую информацию он предоставляет, как её обрабатывать и использовать, учитывая ориентацию устройства, источник камеры и выбранную камеру (переднюю или заднюю).

В идеале мы должны получить код вроде этого:

camera.addFrameProcessor { frame ->      faceDetector.detectFaces(frame)  }

Основные компоненты здесь — это camera, frame, faceDetector. Прежде чем разобраться с каждым из них, предположим, что наш layout содержит сам компонент камеры и некий оверлей, на котором мы будем рисовать квадратики вокруг обнаруженных лиц.

<FrameLayout     ...>      // Any other views      <CameraView         ... />      <husaynhakeem.io.facedetector.FaceBoundsOverlay         ... />      // Any other views  </FrameLayout>

Камера (Camera)

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

Кадр (Frame)

Кадр представляет собой информацию, предоставленную камерой, для обнаружения лиц. Он должен содержать всё, что требуется детектору лиц для их обнаружения. Эта необходимая информация определяется ниже:

data class Frame(     val data: ByteArray?,     val rotation: Int,     val size: Size,     val format: Int,     val isCameraFacingBack: Boolean)  data class Size(val width: Int, val height: Int)

  • data — массив байтов, содержащий информацию о том, что камера отображает;
  • rotation — ориентация устройства;
  • size — ширина и высота предпросмотра камеры;
  • format — формат кодирования кадров;
  • isCameraFacingBack — указывает, используется ли передняя камера или задняя.

Детектор лиц (Face Detector)

Детектор лиц является самым важным компонентом — он берёт кадр, обрабатывает его и затем выводит результаты пользователю. Таким образом, детектор лиц использует экземпляр FirebaseVisionFaceDetector для обработки входящих кадров с камеры. Он также должен знать ориентацию камеры и её направление (передняя или задняя). Наконец, он должен знать на каком оверлее будут отображаться результаты. Скелет класса FaceDetector выглядит так:

class FaceDetector(private val faceBoundsOverlay: FaceBoundsOverlay) {      private val faceBoundsOverlayHandler = FaceBoundsOverlayHandler()     private val firebaseFaceDetectorWrapper = FirebaseFaceDetectorWrapper()      fun process(frame: Frame) {         updateOverlayAttributes(frame)         detectFacesIn(frame)     }      private fun updateOverlayAttributes(frame: Frame) {         faceBoundsOverlayHandler.updateOverlayAttributes(...)     }      private fun detectFacesIn(frame: Frame) {         firebaseFaceDetectorWrapper.process(                 image = convertFrameToImage(frame),                 onSuccess = {                     faceBoundsOverlay.updateFaces( /* Faces */)                 },                 onError = { /* Display error message */ })     } }

Оверлей (Overlay)

Оверлей — это View-компонент, который находится поверх камеры. Он отображает рамки (или границы) вокруг обнаруженных лиц. Он должен знать ориентацию устройства, направление камеры (передняя или задняя) и размеры камеры (ширина и высота). Эта информация помогает определить, как рисовать границы вокруг обнаруженного лица, как масштабировать границы и следует ли их отражать.

class FaceBoundsOverlay @JvmOverloads constructor(         ctx: Context,         attrs: AttributeSet? = null,         defStyleAttr: Int = 0) : View(ctx, attrs, defStyleAttr) {      private val facesBounds: MutableList<FaceBounds> = mutableListOf()      fun updateFaces(bounds: List<FaceBounds>) {         facesBounds.clear()         facesBounds.addAll(bounds)         invalidate()     }      override fun onDraw(canvas: Canvas) {         super.onDraw(canvas)         facesBounds.forEach {             val centerX = /* Compute the center's x coordinate */             val centerY = /* Compute the center's ycoordinate */             drawBounds(it.box, canvas, centerX, centerY)         }     }      private fun drawBounds(box: Rect, canvas: Canvas, centerX: Float, centerY: Float) {         /* Compute the positions left, right, top and bottom */         canvas.drawRect(                 left,                 top,                 right,                 bottom,                 boundsPaint)     } }

На приведённой ниже диаграмме показаны компоненты, описанные выше, и способы взаимодействия их друг с другом с момента, когда камера подаёт на вход кадр, до момента, когда результаты отображаются пользователю.

Взаимодействие компонентов детектора лиц

Создание приложения для обнаружения лиц в реальном времени за 3 шага

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

В этом примере я выбрал следующую библиотеку камеры.

Шаг 1. Добавьте FaceBoundsOverlay поверх камеры.

<FrameLayout     ...>      // Any other views      <CameraView         ... />      <husaynhakeem.io.facedetector.FaceBoundsOverlay         ... />      // Any other views  </FrameLayout>

Шаг 2. Определите экземпляр FaceDetection и подключите его к камере.

private val faceDetector: FaceDetector by lazy {     FaceDetector(facesBoundsOverlay) } cameraView.addFrameProcessor {     faceDetector.process(Frame(             data = it.data,             rotation = it.rotation,             size = Size(it.size.width, it.size.height),             format = it.format)) }

Шаг 3. Настройте Firebase в проекте.

Заключение

Обнаружение лиц — это мощный функционал, а ML Kit делает его доступным и позволяет разработчикам выполнять с его помощью более сложные функции, такие как распознавание лиц, что выходит за рамки простого обнаружения: важно не только обнаружить лицо, но и определить, чьё оно.

Скоро в Ml Kit планируют добавить новую функцию — распознавание контура лица. С её помощью можно будет обнаруживать более 100 точек вокруг лица и быстро обрабатывать их. Это потенциально может быть полезно в приложениях с использованием объектов дополненной реальности или виртуальных стикеров (таких как Snapchat). Вместе функционалом обнаружения лиц можно будет создать много интересных приложений.

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *