Обнаружение лица, затем автообрезка изображений

Я пытаюсь найти приложение, которое может обнаруживать лица на моих фотографиях, центрировать обнаруженное лицо и обрезать изображение размером 720 x 720 пикселей. Редактирование сотен фотографий, которые я планирую сделать, требует очень много времени и тщательности.

Я пытался сделать это, используя упомянутый здесь python opencv, но я думаю, что это устаревший. Я также пробовал использовать это, но это также дает мне ошибка в моей системе. Также пробовал использовать плагин распознавания лиц для GIMP, но он предназначен для GIMP 2.6, но я регулярно использую 2.8. Я также пытался сделать то, что было опубликовано в блоге ultrahigh, но это очень устарело (поскольку я использую Precise, производную от Ubuntu, а сообщение в блоге было сделано еще во времена Hardy). Также пытался использовать Phatch, но распознавание лиц отсутствует, поэтому на некоторых обрезанных изображениях лицо сразу обрезается.

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

У вас, ребята, есть предложения по достижению цели около 800 фотографий, которые у меня есть.

Моя операционная система — Linux Mint 13 MATE.

Примечание. Я собирался добавить еще 2 ссылки, но stackexchange не позволил мне опубликовать еще две ссылки, так как у меня пока не очень высокая репутация.


person AisIceEyes    schedule 01.11.2012    source источник
comment
Я не был уверен, относится ли этот вопрос к теме или нет, поэтому я начал мета-дискуссию именно по этому поводу, подробнее см. здесь: meta.photo.stackexchange.com/questions/ 2606/   -  person    schedule 02.11.2012
comment
На самом деле я просто пытаюсь найти какое-либо решение для автоматического определения лиц, а затем обрезать изображение. Так уж получилось, что я использую не очень удобную для пользователя операционную систему, которая требует немного программирования для достижения целей, а именно Linux. Ответ @jrista — это вкратце то, что я хочу здесь объяснить. В любом случае, спасибо за ответ, dpollitt   -  person    schedule 02.11.2012
comment
Я бы выбрал вариант opencv. opencv очень мощный и не устарел. Если вы не знаете Python, это может быть сложнее. Если у меня будет время на этих выходных, я попытаюсь вместе написать код. Кстати, какая у вас версия opencv и python?   -  person Onlyjus    schedule 02.11.2012
comment
Вероятно, мне просто нужно было полностью прочитать opencv и сделать несколько проб и ошибок. Причина, по которой я сказал, что он устарел, заключается в том, что сообщения в блогах, которые я нашел в Google, были старыми и больше не работают. Я думаю, что установил opencv 2.4.1 с помощью учебника, который я нашел в Google. Моя версия Python 2.7.3. Я знаком с Python, но не могу сказать, что я действительно эксперт. (поскольку мне очень нужен обзор языка, так как моя работа на полную ставку использует C и C++, поэтому другие языки я склонен постепенно забывать)   -  person    schedule 03.11.2012


Ответы (11)


Мне удалось взять фрагменты кода из разных источников и сшить их вместе. Это все еще продолжается. Кроме того, у вас есть примеры изображений?

'''
Sources:
http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
http://www.lucaamore.com/?p=638
'''

#Python 2.7.2
#Opencv 2.4.2
#PIL 1.1.7

import cv
import Image

def DetectFace(image, faceCascade):
    #modified from: http://www.lucaamore.com/?p=638

    min_size = (20,20)
    image_scale = 1
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Allocate the temporary images
    smallImage = cv.CreateImage(
            (
                cv.Round(image.width / image_scale),
                cv.Round(image.height / image_scale)
            ), 8 ,1)

    # Scale input image for faster processing
    cv.Resize(image, smallImage, cv.CV_INTER_LINEAR)

    # Equalize the histogram
    cv.EqualizeHist(smallImage, smallImage)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            smallImage, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    if faces:
        for ((x, y, w, h), n) in faces:
            # the input to cv.HaarDetectObjects was resized, so scale the
            # bounding box of each face and convert it to two CvPoints
            pt1 = (int(x * image_scale), int(y * image_scale))
            pt2 = (int((x + w) * image_scale), int((y + h) * image_scale))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    return image

def pil2cvGrey(pil_im):
    #from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def cv2pil(cv_im):
    return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())


pil_im=Image.open('testPics/faces.jpg')
cv_im=pil2cv(pil_im)
#the haarcascade files tells opencv what to look for.
faceCascade = cv.Load('C:/Python27/Lib/site-packages/opencv/haarcascade_frontalface_default.xml')
face=DetectFace(cv_im,faceCascade)
img=cv2pil(face)
img.show()

Тестирование на первой странице Google (погуглил "лица"): введите здесь описание изображения


Обновить

Этот код должен делать именно то, что вы хотите. Дайте мне знать, если у вас есть вопросы. Я попытался включить много комментариев в код:

'''
Sources:
http://opencv.willowgarage.com/documentation/python/cookbook.html
http://www.lucaamore.com/?p=638
'''

#Python 2.7.2
#Opencv 2.4.2
#PIL 1.1.7

import cv #Opencv
import Image #Image from PIL
import glob
import os

def DetectFace(image, faceCascade, returnImage=False):
    # This function takes a grey scale cv image and finds
    # the patterns defined in the haarcascade function
    # modified from: http://www.lucaamore.com/?p=638

    #variables    
    min_size = (20,20)
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Equalize the histogram
    cv.EqualizeHist(image, image)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            image, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    if faces and returnImage:
        for ((x, y, w, h), n) in faces:
            # Convert bounding box to two CvPoints
            pt1 = (int(x), int(y))
            pt2 = (int(x + w), int(y + h))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    if returnImage:
        return image
    else:
        return faces

def pil2cvGrey(pil_im):
    # Convert a PIL image to a greyscale cv image
    # from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def cv2pil(cv_im):
    # Convert the cv image to a PIL image
    return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())

def imgCrop(image, cropBox, boxScale=1):
    # Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]

    # Calculate scale factors
    xDelta=max(cropBox[2]*(boxScale-1),0)
    yDelta=max(cropBox[3]*(boxScale-1),0)

    # Convert cv box to PIL box [left, upper, right, lower]
    PIL_box=[cropBox[0]-xDelta, cropBox[1]-yDelta, cropBox[0]+cropBox[2]+xDelta, cropBox[1]+cropBox[3]+yDelta]

    return image.crop(PIL_box)

def faceCrop(imagePattern,boxScale=1):
    # Select one of the haarcascade files:
    #   haarcascade_frontalface_alt.xml  <-- Best one?
    #   haarcascade_frontalface_alt2.xml
    #   haarcascade_frontalface_alt_tree.xml
    #   haarcascade_frontalface_default.xml
    #   haarcascade_profileface.xml
    faceCascade = cv.Load('haarcascade_frontalface_alt.xml')

    imgList=glob.glob(imagePattern)
    if len(imgList)<=0:
        print 'No Images Found'
        return

    for img in imgList:
        pil_im=Image.open(img)
        cv_im=pil2cvGrey(pil_im)
        faces=DetectFace(cv_im,faceCascade)
        if faces:
            n=1
            for face in faces:
                croppedImage=imgCrop(pil_im, face[0],boxScale=boxScale)
                fname,ext=os.path.splitext(img)
                croppedImage.save(fname+'_crop'+str(n)+ext)
                n+=1
        else:
            print 'No faces found:', img

def test(imageFilePath):
    pil_im=Image.open(imageFilePath)
    cv_im=pil2cvGrey(pil_im)
    # Select one of the haarcascade files:
    #   haarcascade_frontalface_alt.xml  <-- Best one?
    #   haarcascade_frontalface_alt2.xml
    #   haarcascade_frontalface_alt_tree.xml
    #   haarcascade_frontalface_default.xml
    #   haarcascade_profileface.xml
    faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
    face_im=DetectFace(cv_im,faceCascade, returnImage=True)
    img=cv2pil(face_im)
    img.show()
    img.save('test.png')


# Test the algorithm on an image
#test('testPics/faces.jpg')

# Crop all jpegs in a folder. Note: the code uses glob which follows unix shell rules.
# Use the boxScale to scale the cropping area. 1=opencv box, 2=2x the width and height
faceCrop('testPics/*.jpg',boxScale=1)

Используя изображение выше, этот код извлекает 52 из 59 лиц, создавая обрезанные файлы, такие как: введите описание изображения здесьвведите здесь описание изображениявведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите здесь описание изображениявведите здесь описание изображения

person Onlyjus    schedule 06.11.2012
comment
Ух ты. Какой красивый код! Спасибо, что потратили на это время. Просто вау! Проверю, когда у меня будет время во время перерывов в офисе (поскольку месяцы, как правило, адские, когда клиенты укладываются в сроки на праздники) - person AisIceEyes; 07.11.2012
comment
Спасибо, код для начала. Я работаю над тем, чтобы код делал именно то, что вы хотите. - person Onlyjus; 08.11.2012
comment
Я просто обновляю свой ответ. Это должно делать свое дело. Дайте знать, если у вас появятся вопросы. - person Onlyjus; 10.11.2012
comment
Извините, если я не ответил вам, поскольку я, честно говоря, не полностью протестировал прекрасный код, который вы сделали. К сожалению, я все еще занят в данный момент, но я надеюсь, что смогу проверить это до конца февраля. Еще раз спасибо за это Onlyjus! - person AisIceEyes; 08.02.2013
comment
Крутой чувак! Stackoverflow нужны такие щедрые люди, как вы... Мне это помогло спустя два года.. - person Aditya; 18.04.2014
comment
Хорошо! Я не тестировал код с последними выпусками. Надеюсь, он еще работает? - person Onlyjus; 22.04.2014
comment
С последней версией OpenCV вы можете сделать это со значительно меньшим количеством кода. - person Onlyjus; 15.06.2015
comment
Я просто искал способ улучшить свой скрипт автоматического изменения размера/обрезки. Это потрясающе. Кажется, я знаю, что буду делать в эти выходные! Большое спасибо! - person Maxim; 18.07.2015
comment
@Onlyjus Я запускаю код и обнаруживаю ошибку: faceCascade = cv.Load('haarcascade_frontalface_alt.xml') TypeError: OpenCV вернул NULL. Как исправить эту ошибку? - person Timothy; 18.11.2015
comment
@ Джереми, проверь, существует ли этот файл. os.path.exists('haarcascade_frontalface_alt.xml') Эти файлы должны быть включены в opencv. Или вы можете скачать их отсюда: github.com/Itseez/opencv/tree/ master/data/haarcascades - person Onlyjus; 18.11.2015
comment
@Onlyjus Возвращает false, поэтому его не существует. Я скачал opencv. какой путь использует python для связывания opencv (или где я должен установить свой opencv)? Спасибо за помощь? - person Timothy; 18.11.2015
comment
@Jeremy должно быть что-то вроде opencv/share/OpenCV/haarcascades/ - person Onlyjus; 19.11.2015
comment
Есть ли версия этого кода для python 3.5? Многие компоненты open cv устарели в версии cv2, совместимой с 3.5. - person Shaz; 07.10.2017
comment
Как уже отмечали другие, к сожалению, многое из этого больше не работает с версиями выше 3. - person Skeleton Bow; 23.05.2018
comment
Я хочу то же самое, но не могу ли python точно обрезать лицо, как с помощью инструмента Marquee в Adobe Photoshop. Я хочу, чтобы на выходе получился контур тела с данного изображения. - person Nischaya Sharma; 01.10.2020
comment
Кажется, не работает с последними версиями python + opencv :( - person Harsh; 01.03.2021
comment
Попробуйте github.com/leblancfg/autocrop - person Harsh; 01.03.2021

Другой доступный вариант — dlib, основанный на подходах машинного обучения.

import dlib
from PIL import Image
from skimage import io
import matplotlib.pyplot as plt


def detect_faces(image):

    # Create a face detector
    face_detector = dlib.get_frontal_face_detector()

    # Run detector and get bounding boxes of the faces on image.
    detected_faces = face_detector(image, 1)
    face_frames = [(x.left(), x.top(),
                    x.right(), x.bottom()) for x in detected_faces]

    return face_frames

# Load image
img_path = 'test.jpg'
image = io.imread(img_path)

# Detect faces
detected_faces = detect_faces(image)

# Crop faces and plot
for n, face_rect in enumerate(detected_faces):
    face = Image.fromarray(image).crop(face_rect)
    plt.subplot(1, len(detected_faces), n+1)
    plt.axis('off')
    plt.imshow(face)

введите здесь описание изображения введите здесь описание изображения

person Katerina    schedule 23.02.2017
comment
Это прекрасно работает. Это первый раз, когда я попробовал dlib. Единственная проблема заключается в том, что он показывает только одно лицо из двух лиц на изображении, которое я использую. У тебя есть идеи, почему это происходит? Я скопировал ваш точный код. ... РЕДАКТИРОВАТЬ это происходит только на некоторых изображениях, но на некоторых других изображениях отображаются все лица. - person Joe T. Boka; 10.06.2018

facedetect Оболочка командной строки OpenCV, написанная на Python

https://github.com/wavexx/facedetect — хорошая оболочка Python OpenCV CLI, и у меня есть добавил следующий пример в свой файл README.

Установка:

sudo apt install python3-opencv opencv-data imagemagick
git clone https://gitlab.com/wavexx/facedetect
git -C facedetect checkout 5f9b9121001bce20f7d87537ff506fcc90df48ca

Получите мое тестовое изображение:

mkdir -p pictures
wget -O pictures/test.jpg https://raw.githubusercontent.com/cirosantilli/media/master/Ciro_Santilli_with_a_stone_carved_Budai_in_the_Feilai_Feng_caves_near_the_Lingyin_Temple_in_Hangzhou_in_2012.jpg

Использование:

mkdir -p faces
for file in pictures/*.jpg; do
  name=$(basename "$file")
  i=0
  facedetect/facedetect --data-dir /usr/share/opencv4 "$file" |
    while read x y w h; do
      convert "$file" -crop ${w}x${h}+${x}+${y} "faces/${name%.*}_${i}.${name##*.}"
    i=$(($i+1))
    done
done

Если вы не передадите --data-dir в этой системе, произойдет сбой:

facedetect: error: cannot load HAAR_FRONTALFACE_ALT2 from /usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml

и файл, который он ищет, скорее всего находится по адресу: /usr/share/opencv4/haarcascades в системе.

После запуска файл:

faces/test_0.jpg

содержит:

введите здесь описание изображения

который был извлечен из исходного изображения pictures/test.jpg:

введите здесь описание изображения

Budai не был распознан :-( Если бы он был, он бы появился под faces/test_1.jpg, но этого файла не существует.

Давайте попробуем еще один с частично повернутыми лицами https://raw.githubusercontent.com/cirosantilli/media/master/Ciro_Santilli_with_his_mother_in_law_during_his_wedding_in_2017.jpg

введите здесь описание изображения

Мда, нет попаданий, лица недостаточно четкие для софта.

Протестировано на Ubuntu 20.10, OpenCV 4.2.0.

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 28.05.2016
comment
Мне нужно было изменить строку обнаружения на facedetect "$file" | grep -v INFO | while read x y w h; do, потому что я продолжал получать [ INFO:0] Initialize OpenCL runtime... в качестве вывода первой строки. - person Laurenz; 04.05.2019
comment
Кроме того, по какой-то причине инкрементирование не работало в моей оболочке zsh, но в этом нет необходимости: просто используйте эту строку преобразования: convert "$file" -crop ${w}x${h}+${x}+${y} "crop_$file" - person Laurenz; 04.05.2019

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

Тем не менее, вы изучали что-то вроде этого jquery-скрипт обнаружения лиц ? Я не знаю, насколько вы сообразительны, но это один из вариантов, который не зависит от ОС.

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

person ckoerner    schedule 02.11.2012
comment
Спасибо за ответ @ckoerner. Я немного покопаюсь в вашем предложении и попытаюсь использовать ссылку jquery, которую вы дали (хотя мне, честно говоря, нужен обзор). Я не думаю, что смогу использовать Windows, поскольку у меня нет компьютера с ОС Windows и установщика (и я не планирую его пиратство). Еще раз спасибо. - person AisIceEyes; 07.11.2012

Автообрезка сработала для меня очень хорошо. Это так же просто, как autocrop -i pics -o crop -w 400 -H 400. Вы можете получить информацию об использовании в их файле readme.

usage: autocrop [-h] [-i INPUT] [-o OUTPUT] [-r REJECT] [-w WIDTH] [-H HEIGHT]
                [-v] [--no-confirm] [--facePercent FACEPERCENT] [-e EXTENSION]

Automatically crops faces from batches of pictures

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Folder where images to crop are located. Default:
                        current working directory
  -o OUTPUT, --output OUTPUT, -p OUTPUT, --path OUTPUT
                        Folder where cropped images will be moved to. Default:
                        current working directory, meaning images are cropped
                        in place.
  -r REJECT, --reject REJECT
                        Folder where images that could not be cropped will be
                        moved to. Default: current working directory, meaning
                        images that are not cropped will be left in place.
  -w WIDTH, --width WIDTH
                        Width of cropped files in px. Default=500
  -H HEIGHT, --height HEIGHT
                        Height of cropped files in px. Default=500
  -v, --version         show program's version number and exit
  --no-confirm          Bypass any confirmation prompts
  --facePercent FACEPERCENT
                        Percentage of face to image height
  -e EXTENSION, --extension EXTENSION
                        Enter the image extension which to save at output
person Abhishek Singh    schedule 17.06.2018
comment
Документации нет, не могли бы вы немного помочь мне, как использовать это - person Talha Anwar; 12.09.2019
comment
@TalhaAnwar readme не требует пояснений и полностью детализирован. Какая помощь вам нужна конкретно? - person Abhishek Singh; 13.09.2019
comment
Это очень хороший пакет, спасибо за рекомендацию Abhishek! Доступно через PyPI, как указано в README. - person Louis Maddox; 06.04.2021

приведенные выше коды работают, но это недавняя реализация с использованием OpenCV. Я не смог запустить вышеизложенное последним и нашел что-то, что работает (из разных мест)

import cv2
import os

def facecrop(image):
    facedata = "haarcascade_frontalface_alt.xml"
    cascade = cv2.CascadeClassifier(facedata)

    img = cv2.imread(image)

    minisize = (img.shape[1],img.shape[0])
    miniframe = cv2.resize(img, minisize)

    faces = cascade.detectMultiScale(miniframe)

   for f in faces:
        x, y, w, h = [ v for v in f ]
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,255,255))

        sub_face = img[y:y+h, x:x+w]
        fname, ext = os.path.splitext(image)
        cv2.imwrite(fname+"_cropped_"+ext, sub_face)



    return



facecrop("1.jpg")
person Israel-abebe    schedule 07.10.2017

Просто добавляю к версии @Israel Abebe. Если вы добавите счетчик перед расширением изображения, алгоритм выдаст все обнаруженные лица. Прикрепите код, такой же, как у Исраэля Абебе. Просто добавьте счетчик и примите каскадный файл в качестве аргумента. Алгоритм работает прекрасно! Спасибо @Israel Abebe за это!

import cv2
import os
import sys

def facecrop(image):
facedata = sys.argv[1]
cascade = cv2.CascadeClassifier(facedata)

img = cv2.imread(image)

minisize = (img.shape[1],img.shape[0])
miniframe = cv2.resize(img, minisize)

faces = cascade.detectMultiScale(miniframe)
counter = 0
for f in faces:
    x, y, w, h = [ v for v in f ]
    cv2.rectangle(img, (x,y), (x+w,y+h), (255,255,255))

    sub_face = img[y:y+h, x:x+w]
    fname, ext = os.path.splitext(image)
    cv2.imwrite(fname+"_cropped_"+str(counter)+ext, sub_face)
    counter += 1
return

facecrop("Face_detect_1.jpg")

PS: Добавление в качестве ответа. Не удалось добавить комментарий из-за проблемы с баллами.

person Mrunal    schedule 13.11.2018

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

import numpy as np
import cv2 as cv
face_cascade = cv.CascadeClassifier('./haarcascade_frontalface_default.xml')
#eye_cascade = cv.CascadeClassifier('haarcascade_eye.xml')
img = cv.imread('./face/nancy-Copy1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
    cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    #eyes = eye_cascade.detectMultiScale(roi_gray)
    #for (ex,ey,ew,eh) in eyes:
     #   cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
    sub_face = img[y:y+h, x:x+w]
    face_file_name = "face/" + str(y) + ".jpg"
    plt.imsave(face_file_name, sub_face)
plt.imshow(sub_face)


person ashish bansal    schedule 11.05.2019

Я разработал приложение «Распознавание лиц с собственным набором данных», используя пакет python ‘face_recognition’ и ‘opencv-python’.

Исходный код и руководство по установке находятся на GitHub — Face-Recognition-with -Собственный набор данных

Или запустить исходник -

import face_recognition
import cv2
import numpy as np

import os
'''
    Get current working director and create a Data directory to store the faces
'''
currentDirectory = os.getcwd()
dirName = os.path.join(currentDirectory, 'Data')
print(dirName)
if not os.path.exists(dirName):
    try:
        os.makedirs(dirName)
    except:
        raise OSError("Can't create destination directory (%s)!" % (dirName))
'''
    For the given path, get the List of all files in the directory tree 
'''
def getListOfFiles(dirName):
    # create a list of file and sub directories
    # names in the given directory
    listOfFile = os.listdir(dirName)
    allFiles = list()
    # Iterate over all the entries
    for entry in listOfFile:
        # Create full path
        fullPath = os.path.join(dirName, entry)
        # If entry is a directory then get the list of files in this directory
        if os.path.isdir(fullPath):
            allFiles = allFiles + getListOfFiles(fullPath)
        else:
            allFiles.append(fullPath)

    return allFiles

def knownFaceEncoding(listOfFiles):
    known_face_encodings=list()
    known_face_names=list()
    for file_name in listOfFiles:
        # print(file_name)
        if(file_name.lower().endswith(('.png', '.jpg', '.jpeg'))):
            known_image = face_recognition.load_image_file(file_name)
            # known_face_locations = face_recognition.face_locations(known_image)
            # known_face_encoding = face_recognition.face_encodings(known_image,known_face_locations)
            face_encods = face_recognition.face_encodings(known_image)
            if face_encods:
                known_face_encoding = face_encods[0]
                known_face_encodings.append(known_face_encoding)
                known_face_names.append(os.path.basename(file_name[0:-4]))
    return known_face_encodings, known_face_names


# Get the list of all files in directory tree at given path
listOfFiles = getListOfFiles(dirName)
known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)

video_capture = cv2.VideoCapture(0)
cv2.namedWindow("Video", flags= cv2.WINDOW_NORMAL)
# cv2.namedWindow("Video")

cv2.resizeWindow('Video', 1024,640)
cv2.moveWindow('Video', 20,20)


# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True


while True:
    # Grab a single frame of video
    ret, frame = video_capture.read()
    # print(ret)
    # Resize frame of video to 1/4 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_small_frame = small_frame[:, :, ::-1]


    k = cv2.waitKey(1)
    # Hit 'c' on capture the image!
    # Hit 'q' on the keyboard to quit!
    if k == ord('q'):
        break
    elif k== ord('c'):
        face_loc = face_recognition.face_locations(rgb_small_frame)
        if face_loc:
            print("Enter Name -")
            name = input()
            img_name = "{}/{}.png".format(dirName,name)
            (top, right, bottom, left)= face_loc[0]
            top *= 4
            right *= 4
            bottom *= 4
            left *= 4
            cv2.imwrite(img_name, frame[top - 5 :bottom + 5,left -5 :right + 5])
            listOfFiles = getListOfFiles(dirName)
            known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)

    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
        # print(face_locations)

        face_names = []

        for face_encoding,face_location in zip(face_encodings,face_locations):
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance= 0.55)
            name = "Unknown"
            distance = 0

            # use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            #print(face_distances)
            if len(face_distances) > 0:
                best_match_index = np.argmin(face_distances)
                if matches[best_match_index]:
                    name = known_face_names[best_match_index]
                    # distance = face_distances[best_match_index]
            #print(face_distances[best_match_index])
            # string_value = '{} {:.3f}'.format(name, distance)
            face_names.append(name)


    process_this_frame = not process_this_frame


    # Display the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4

        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom + 46), (right, bottom+11), (0, 0, 155), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom +40), font, 1.0, (255, 255, 255), 1)

    # Display the resulting image
    cv2.imshow('Video', frame)

# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()

Он создаст каталог «Данные» в текущем местоположении, даже если этот каталог не существует.

Когда лицо отмечено прямоугольником, нажмите 'c', чтобы сделать снимок, и в командной строке будет запрошено имя лица. Введите название изображения и введите. Это изображение можно найти в каталоге 'Data'.

person Anupam Bera    schedule 29.06.2019

Я использовал эту команду оболочки:

for f in *.jpg;do PYTHONPATH=/usr/local/lib/python2.7/site-packages python -c 'import cv2;import sys;rects=cv2.CascadeClassifier("/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml").detectMultiScale(cv2.cvtColor(cv2.imread(sys.argv[1]),cv2.COLOR_BGR2GRAY),1.3,5);print("\n".join([" ".join([str(item) for item in row])for row in rects]))' $f|while read x y w h;do convert $f -gravity NorthWest -crop ${w}x$h+$x+$y ${f%jpg}-$x-$y.png;done;done

Вы можете установить opencv и imagemagick на OS X с помощью brew install opencv imagemagick.

person Lri    schedule 07.02.2015

Я думаю, что лучший вариант — Google Vision API. Он обновляется, использует машинное обучение и со временем улучшается.

Примеры можно найти в документации: https://cloud.google.com/vision/docs/other-features

person Hernán Acosta    schedule 29.06.2017