Простое распознавание лица «на лету» в Django

    Доброго дня!

    Меня зовут Соболев Андрей и сегодня мы с вами создадим простую «плюшку» к Django, которая будет проверять, что на фотографии именно лицо человека (что бывает полезно в куче ситуаций).

    Для этого нам понадобится OpenCV и 5 минут свободного времени. Поехали.

    Установка


    Для начала установим необходимые библиотеки в докер контейнер:

    FROM python:3.8.3-buster
    
    RUN apt-get update && \
        apt-get upgrade -y && \
        apt-get install -y \
        gcc && apt-get install -y \  
        libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev libjpeg-dev libfreetype6-dev python-dev libpq-dev python-dev libxml2-dev libxslt-dev postgresql-client git && \
        apt-get install -y libxrender1 libxext-dev fontconfig && \
        pip3 install -U pip setuptools 
    
    COPY ./requirements.txt /home/
    * * *
    

    И добавим зависимости в requirements.txt:

    opencv-python
    matplotlib
    numpy
    

    Функция «проверки лица» detect_face


    Создадим файл utils.py (к примеру в папке main, у вас может быть любая другая папка) и добавим туда следующие строчки:

    import cv2 as cv
    import numpy as np
    
    def detect_face(in_memory_photo):
        face_cascade = cv.CascadeClassifier(cv.__path__[0] + "/data/haarcascade_frontalface_default.xml")
        in_memory_photo = in_memory_photo.read()
        nparr = np.fromstring(in_memory_photo, np.uint8)
        img = cv.imdecode(nparr, 4)
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        if len(faces) > 0:
            return True
        else:
            return False
    

    Интеграция в форму пользовательского ввода


    Импортируем нашу функцию:

    from main.utils import detect_face 
    

    И «проверим лицо» при регистрации нового пользователя.

    if request.method == "POST":
        form = RegistrationForm(request.POST, request.FILES)
    
        if form.is_valid():
    
            try:
                in_memory_uploaded_file = request.FILES["photo"]
            except:
                in_memory_uploaded_file = None
    
            if not in_memory_uploaded_file or not detect_face(in_memory_uploaded_file):
                messages.add_message(request, messages.WARNING, _("You can only upload a face photo. Please try to uploading a different photo."))
                return HttpResponseRedirect(reverse("main:profile_registration"))
    

    Пример без фреймворка


    import os
    import cv2 as cv
    import numpy as np
    
    def detect_face(in_memory_photo):
        face_cascade = cv.CascadeClassifier(cv.__path__[0] + "/data/haarcascade_frontalface_default.xml")
        in_memory_photo = in_memory_photo.read()
        nparr = np.fromstring(in_memory_photo, np.uint8)
        img = cv.imdecode(nparr, 4)
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        if len(faces) > 0:
            return True
        else:
            return False
    
    with open(os.path.dirname(os.path.abspath(__file__)) + '/photo.jpg', 'rb') as in_memory_photo: 
        is_it_face = detect_face(in_memory_photo)
        print(is_it_face)
    

    На этом все.

    Как видим, все довольно просто (если нужна простая проверка конечно).

    Полезные ссылки


    towardsdatascience.com/face-detection-in-2-minutes-using-opencv-python-90f89d7c0f81
    new-friend.org/ru/195/2800/12918/profile-registration (пример работы данного решения).

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 7

      0

      А докер тут прямо необходим?
      И связь с Django слабовата. Да, он на python и на этом всё пожалуй, просто в нем вызов функции, ничего сложного в вызове.
      Были бы несколько таких «плюшек», было бы полезно, а так как то сомнительно.
      Импорт из main.utils?
      Что за main? По тексту этого не видно
      И что такое messages?


      Какой то слишком частный случай кода

        0
        Доброе утро.

        1) А докер тут прямо необходим? Докер удобен. Вы просто копируете приведенный код в Dockerfile и все работает. В противном случае вам долго придется гуглить «какие же пакеты мне надо поставить на мой CentOs6, чтобы наконец то у меня сбилдился OpenCv». Это долго.

        2) И связь с Django слабовата. Вы можете использовать данную функцию в чистом питоне.
        К примеру:
        with open('photo.jpg', 'r') as in_memory_uploaded_file: 
            in_memory_photo = in_memory_uploaded_file.read()
            detect_face(in_memory_photo)
        


        3) Импорт из main.utils? Я специально старался не усложнять статью. Вы можете поместить функцию detect_face в любой удобный вам файл разумеется.

        4) И что такое messages? docs.djangoproject.com/en/3.0/ref/contrib/messages
          0

          А лучше, непонятно зачем, писать докерфайл?
          В котором ещё и джанго проект не запускается, а просто кусок какого то конфига


          Ваш код не рабочий, точнее он работает, но путём полного понимания, что и куда. У вас кусок какого то view, который содержит не определенные переменные. У вас пакет main, который вы не создавали в статье (папка — это не пакет без _ init _.py), хотя пишете «импортируйте из main». То есть не новичку это под силу.
          При этом не новичку и так известно или легко найти, как эти несколько не сложных строчек сделать.

          0
          Прошу прощения, должно быть вот так (обратите внимание на флаг rb и отсутствие .read())

          def test_detect_face():
              with open(os.path.dirname(os.path.abspath(__file__)) + '/photo.jpg', 'rb') as in_memory_photo: 
                  is_it_face = detect_face(in_memory_photo)
                  print(is_it_face)
            0
            А откуда брать?
            face_cascade = cv.CascadeClassifier(cv.__path__[0] + "/data/haarcascade_frontalface_default.xml")
            0

            а чем туториал opencv cascade classifier неугодил? тут что-то новое?

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое