Все мы знаем, как круто выглядит приложение для Android, когда оно может определять наше лицо или отслеживать, закрыты или открыты наши глаза. Становится намного круче, когда приложение может даже определить, улыбаемся ли мы, читаем по телефону или не смотрим на него.

Хорошо…

Я верю ... все, что мне нравится, просто заставляет меня строить!

Извините, попробовал каламбур «Темного рыцаря» :)

Итак, давайте сделаем приложение для отслеживания взгляда и распознавания лиц для Android с помощью Google Vision API.

Из Google:

Cloud Vision API позволяет разработчикам понимать содержание изображения, инкапсулируя мощные модели машинного обучения в простой в использовании REST API. Он быстро классифицирует изображения по тысячам категорий (например, «парусник»), обнаруживает отдельные объекты и лица на изображениях и считывает напечатанные слова, содержащиеся в изображениях. Вы можете создать метаданные в своем каталоге изображений, смягчить оскорбительный контент или задействовать новые маркетинговые сценарии с помощью анализа настроения изображений.

Здесь мы создадим приложение для Android, которое сможет отслеживать наше лицо и определять, закрыты наши глаза или открыты.

Звучит круто? Это даже не так уж и сложно.

Итак, давайте погрузимся в понимание того, как это будет работать на простой блок-схеме.

Наше приложение для Android → Использует камеру → Обнаруживает лицо → Запускает некоторые операции → Проверяет, открыты ли глаза зрителя → Продолжает операцию → Если глаза закрыты → Остановить операцию.

Это основная идея нашего приложения для Android. В учебных целях мы просто будем делать это в нашем приложении, но гораздо более продвинутые функции могут быть добавлены с помощью Google Vision API.

Операция, которую мы выполняем в нашем приложении, - это воспроизведение простого видео. Что ж, я выбрал видео из PIXAR Animation.

Вы можете найти полный исходный код приложения здесь.

Запустите новый проект Android в своей среде IDE, например Android Studio или любой другой.

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

<uses-permission android:name="android.permission.CAMERA" />

Нам также необходимо импортировать Google Vision API в наше приложение для Android, поэтому перейдите к Build Gradle для приложения, которое в основном написано как build.gradle (Module: app).

Вы увидите файл с текстом, похожим на этот:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.pd.trackeye"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.android.gms:play-services:12.0.1'
}

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

На верхней панели появится всплывающее окно с предложением синхронизировать файлы. Нажмите Синхронизировать сейчас и дождитесь завершения сборки проекта.

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

Теперь давайте напишем код для Android, который сотворит чудеса. Перейдите к MainActivity файла и объявите следующие переменные, например:

private static final String TAG = "MainActivity";
VideoView videoView;
EditText textView;

//For looking logs
ArrayAdapter adapter;
ArrayList<String> list = new ArrayList<>();

CameraSource cameraSource;

Эти строки кода должны быть ниже строки, в которой говорится примерно следующее:

public class MainActivity extends AppCompatActivity {

Теперь давайте выполним магический код внутри метода onCreate (), который вы увидите в том же файле.

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

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
    Toast.makeText(this, "Grant Permission and restart app", Toast.LENGTH_SHORT).show();
}
else {
    videoView = findViewById(R.id.videoView);
    textView = findViewById(R.id.textView);
    adapter = new ArrayAdapter<>(this,   android.R.layout.simple_list_item_1, list);
    videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.videoplayback));
    videoView.start();
    createCameraSource();
}

Добавьте приведенный выше код в метод onCreate(), о котором мы говорили выше.

Теперь нам нужно добавить код, который отслеживает глаза с помощью Google Vision API. Мы создадим для этого новый private класс с именем EyesTracker. Код класса выглядит так:

private class EyesTracker extends Tracker<Face> {

    private final float THRESHOLD = 0.75f;

    private EyesTracker() {

    }

    @Override
    public void onUpdate(Detector.Detections<Face> detections, Face face) {
        if (face.getIsLeftEyeOpenProbability() > THRESHOLD || face.getIsRightEyeOpenProbability() > THRESHOLD) {
            Log.i(TAG, "onUpdate: Eyes Detected");
            showStatus("Eyes Detected and open, so video continues");
            if (!videoView.isPlaying())
                videoView.start();

        }
        else {
            if (videoView.isPlaying())
                videoView.pause();

            showStatus("Eyes Detected and closed, so video paused");
        }
    }

    @Override
    public void onMissing(Detector.Detections<Face> detections) {
        super.onMissing(detections);
        showStatus("Face Not Detected yet!");
    }

    @Override
    public void onDone() {
        super.onDone();
    }
}

Здесь videoView - ссылка на видео, для которого установлен атрибут VideoView в activity_main.xml, который предназначен для пользовательского интерфейса приложения.

Теперь мы можем добавить код, определяющий лицо пользователя, в новый private класс с именем FaceTrackerFactory. Код будет выглядеть примерно так:

private class FaceTrackerFactory implements MultiProcessor.Factory<Face> {

    private FaceTrackerFactory() {

    }

    @Override
    public Tracker<Face> create(Face face) {
        return new EyesTracker();
    }
}

public void createCameraSource() {
    FaceDetector detector = new FaceDetector.Builder(this)
            .setTrackingEnabled(true)
            .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
            .setMode(FaceDetector.FAST_MODE)
            .build();
    detector.setProcessor(new MultiProcessor.Builder(new FaceTrackerFactory()).build());

    cameraSource = new CameraSource.Builder(this, detector)
            .setRequestedPreviewSize(1024, 768)
            .setFacing(CameraSource.CAMERA_FACING_FRONT)
            .setRequestedFps(30.0f)
            .build();

    try {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        cameraSource.start();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

Нам также нужно приостановить видео и завершить видео, о чем мы позаботимся с помощью onDestory() и onPause() методов MainActivity.

Теперь давайте добавим XML-код для базового пользовательского интерфейса приложения.

Перейдите к файлу, который называется что-то вроде activity_main.xml. Теперь просто замените в нем код следующим кодом.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <VideoView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/videoView"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/textView"
        android:text="@string/face_not_found"
        android:textSize="20sp"/>

</LinearLayout>

Весь этот код добавляет EditText для отображения текста, в котором указывается, что обнаруживается, а что нет для пользователя. И VideoView, который воспроизводит видео для пользователя.

Вы можете найти полный исходный код приложения здесь.

Вот и все. Вы создали собственное приложение для отслеживания глаз и распознавания лиц для Android.

Все сделано, выглядит так:

А теперь иди и покажись !!

Прочтите мой предыдущий пост о библиотеке Android, которая легко поможет вам настроить Snackbar с помощью всего нескольких строк кода. ChocoBar.