Вступление

Я обычно пишу о развитии бизнеса, маркетинге и взломе роста. Это другой пост. Что ж, наша жизнь тоже стала совсем другой ...

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

Библиотека, которую я в итоге использовал для обнаружения лиц (cvlib), также может обнаруживать 80 общих объектов в контексте. Так что это может быть полезно для других приложений.

Полный код доступен здесь: https://github.com/borismay/dont_touch_your_face

Если вы помните, там был очень вирусный пост: Захват парковочных мест с помощью маски R-CNN и Python, я использовал примерно такой же подход.

Он работает на моем ноутбуке с процессором i7 без графического процессора, и, как вы можете видеть, он довольно близок к реальному времени. Таким образом, его можно перенести на другие платформы или использовать дома, чтобы развить здоровые и жизненно важные привычки :-)

Вы будете поражены тем, сколько раз вы касаетесь своего лица!

Итак, будьте в безопасности и здоровы, и давайте посмотрим, как это работает.

Поиск подходящего классификатора

Для распознавания лиц я протестировал несколько существующих библиотек.

Вы можете обратиться к Detectors.py, который реализует все протестированные детекторы. Также имеется пользовательский интерфейс Streamlit для точной настройки параметров обнаружения. Все доступно в репозитории Github.

Вот вердикт:

  1. cv2.CascadeClassifier - это встроенный классификатор, который поставляется с библиотекой Open-CV. Есть несколько параметров, которые можно настроить, но не очень хорошо объяснены в документации. К счастью, есть StackOverflow post, который поможет вам разобраться. Общая производительность недостаточна. Работает только тогда, когда вы смотрите прямо в камеру
  2. face_recognition - пакет, который построен поверх библиотеки dlib. Существует 2 режима обнаружения: ‘hog’ и ‘cnn’. Он дает приемлемые результаты с ‘cnn’, однако на моем простом оборудовании это отнимало очень много времени
  3. И победитель ... cvlib - внизу cvlib использует модель, подобную AlexNet, обученную на наборе данных Adience Гилом Леви. и Тал Хасснер за их статью CVPR 2015. Он дал очень надежные результаты и высокую производительность. Помимо распознавания лиц, он может обнаруживать 80 обычных объектов в контексте с помощью одной строчки кода. Для обнаружения объектов используется модель YOLOv3, обученная на COCO dataset.

Найти надежную библиотеку для обнаружения рук было немного сложнее. Я использовал работу Виктора Дибиа, описанную в этом посте: Как создать детектор рук в реальном времени с использованием нейронных сетей (SSD) на Tensorflow (2017), репозиторий GitHub, https: // github .com / victordibia / handtracking .

Собираем все вместе

Поток следующий:

  1. Настройте веб-камеру и инициализируйте ее параметры
  2. Инициализировать детекторы
  3. Бесконечный цикл:
    прочитать изображение
    определить лицо и руки
    , если они находятся в непосредственной близости, предупредить пользователя

Вебкамера

Создание объекта веб-камеры и настройка размера изображения:

cap = cv2.VideoCapture(0)
cap.set(3, 1280/2)
cap.set(4, 1024/2)

Описание параметров веб-камеры можно найти здесь.

Захват видеокадра тоже довольно прост:

ret, frame = cap.read()

Однако изображение с камеры находится в формате BGR. Чтобы передать его классификатору, вам нужно преобразовать его в RGB:

rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

Обнаружение лица и рук

Я определил базовый класс, чтобы обеспечить аналогичный интерфейс для всех детекторов, которые я буду использовать:

class Detector:
    detector_params = {}
    detector = None

    def __init__(self):
        pass

    def set_detector_params(self, params):
        self.detector_params = params

    def detect(self):
        pass

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

Так, например, это реализация FaceDetector и то, как он будет вызываться в коде:

class CVLibDetector(Detector):
    def __init__(self):
        self.detector = cv

    def detect(self, rgb_image):
        # returns an array of (top, right, bottom, left)
        objects, confidences = self.detector.detect_face(rgb_image)
        # change to an array of (x, y, w, h)
        return [(top, left, bottom - top, right - left) for (top, right, bottom, left) in objects]
FaceDetector = CVLibDetector()
face = FaceDetector.detect(rgb)

Как я уже упоминал, я использовал Как создать детектор рук в реальном времени с использованием нейронных сетей (SSD) на Tensorflow (2017), репозиторий GitHub, https://github.com/victordibia/handtracking в качестве отправной точки. . Мне нужно было обновить несколько строк кода, чтобы он работал с TensorFlow 2.0 и без графического процессора.

Обнаружить прикосновение к лицу

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

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

Для реализации детектирования я использовал shapely библиотеку. Это очень полезная библиотека для геометрических расчетов, я часто использую ее для геопространственного анализа.

Каждый обнаруженный объект представлен следующими параметрами:

x, y, w, h = obj

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

def obj_to_poly(obj):
    x, y, w, h = obj
    return Polygon([(x, y), (x+w, y), (x+w, y+h), (x, y+h)])
def objects_touch(face, hands):
    if face and hands:
        face_poly = obj_to_poly(face[0])
        for hand in hands:
            hand_poly = obj_to_poly(hand)
            if face_poly.intersects(hand_poly):
                return True
    return False

Если эти объекты пересекаются, функция вернет True.

Вот и все.

В выходные я потратил пару часов на сборку всего этого, чтобы продемонстрировать, насколько легко можно использовать машинное обучение и ИИ с Python. Существует множество уже доступных обученных библиотек, которые позволяют нам создавать мощные приложения с минимальными усилиями.

И еще кое-что. Возможно, этот прототип можно использовать также для повышения нашего самосознания касания лица. Скачайте, запустите всего на 30 минут, и вы увидите результат.

Оставайтесь дома и держите руки подальше от лица.