Собственно буду искать испанского актера Альваро Морте, не почему-то, а просто так! Есть испанский сериал на 2k серий есть 2k скриншотов — хочу найти с ним и надо это это как-то оптимизировать!
Пытался использовать вот этот мануал Face recognition with OpenCV, Python, and deep learning но он оказался непонятным и чето там надо было регистрироваться — он помог только с установкой нужного. А вот мануал Hussain Mujtaba реально помог Face Recognition with Python and OpenCV.
Установка OpenCV
Ставить буду через pip он у меня уже остановлен
pip --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
Python тоже уже установлен
python --version
Python 2.7.18
python3 --version
Python 3.8.10
К нему понадобиться
sudo apt-get install python-setuptools
sudo apt-get install python-dev
Ставим сам OpenCV
sudo pip install opencv-contrib-python
Установка dlib с поддержкой CUDA ядер
Я точно знаю что у меня на GeForce RTX 2070 есть CUDA ядра — в любой не старой видеокарте Nvidia они должны быть
для сборки понадобиться cmake ставлю его сначала
sudo apt-get install cmake
далее по инструкции
git clone https://github.com/davisking/dlib.git
cd dlib
mkdir build
cd build
cmake .. -DDLIB_USE_CUDA=1 -DUSE_AVX_INSTRUCTIONS=1
cmake --build .
Команда из инструкции 2018 года уже не работает запускаем дальше так
sudo python setup.py install
Установка face_recognition
pip install face_recognition
Установка imutils
Говорят нам еще нужен он
pip install imutils
Учим модель
Создаем папку app в ней создаем папку Images в ней создаем папку alvaro_morte
В неё сохраняем кучу(около 60) фоток Альваро Морте с разных ракурсов
Идем в парку app и создаем py файл
vi learn.py
вставляем в него code тут привязка к путям где лежат фотки
from imutils import paths import face_recognition import pickle import cv2 import os #get paths of each file in folder named Images #Images here contains my data(folders of various persons) imagePaths = list(paths.list_images('Images')) knownEncodings = [] knownNames = [] # loop over the image paths for (i, imagePath) in enumerate(imagePaths): # extract the person name from the image path name = imagePath.split(os.path.sep)[-2] # load the input image and convert it from BGR (OpenCV ordering) # to dlib ordering (RGB) image = cv2.imread(imagePath) rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) #Use Face_recognition to locate faces boxes = face_recognition.face_locations(rgb,model='hog') # compute the facial embedding for the face encodings = face_recognition.face_encodings(rgb, boxes) # loop over the encodings for encoding in encodings: knownEncodings.append(encoding) knownNames.append(name) #save emcodings along with their names in dictionary data data = {"encodings": knownEncodings, "names": knownNames} #use pickle to save data into a file for later use f = open("face_enc", "wb") f.write(pickle.dumps(data))
Запускам его
python3 learn.py
он думает и создает в этой же папки файл face_enc тут оцифрованное лицо Альваро под именем папки в которой были его фотки
Теперь создаем файл
vi recog.py
вставляем код
import face_recognition import imutils import pickle import time import cv2 import os #find path of xml file containing haarcascade file cascPathface = os.path.dirname( cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml" # load the harcaascade in the cascade classifier faceCascade = cv2.CascadeClassifier(cascPathface) # load the known faces and embeddings saved in last file data = pickle.loads(open('face_enc', "rb").read()) #Find path to the image you want to detect face and pass it here image = cv2.imread('./001.jpg') rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) #convert image to Greyscale for haarcascade gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60), flags=cv2.CASCADE_SCALE_IMAGE) # the facial embeddings for face in input encodings = face_recognition.face_encodings(rgb) names = [] # loop over the facial embeddings incase # we have multiple embeddings for multiple fcaes for encoding in encodings: #Compare encodings with encodings in data["encodings"] #Matches contain array with boolean values and True for the embeddings it matches closely #and False for rest matches = face_recognition.compare_faces(data["encodings"], encoding) #set name =inknown if no encoding matches name = "Unknown" # check to see if we have found a match if True in matches: #Find positions at which we get True and store them matchedIdxs = [i for (i, b) in enumerate(matches) if b] counts = {} # loop over the matched indexes and maintain a count for # each recognized face face for i in matchedIdxs: #Check the names at respective indexes we stored in matchedIdxs name = data["names"][i] #increase count for the name we got counts[name] = counts.get(name, 0) + 1 #set name which has highest count name = max(counts, key=counts.get) # update the list of names names.append(name) # loop over the recognized faces for ((x, y, w, h), name) in zip(faces, names): # rescale the face coordinates # draw the predicted face name on the image cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(image, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 2) cv2.imshow("Frame", image) cv2.waitKey(0)
кладем файл 001.jpg в папку app в которой лежит скрипт и файл face_enc — это прописано в этой строчке
image = cv2.imread('./001.jpg')
Запускаем
python3 recog.py
Скрипт показывает фотку(без её названия что плохо) и обводит лицо если узнает — чтобы его закрыть корркетно надо нажать 0 когда фотка показалсь
На фотке из набора для обучения сработало
Если на фотке несколько лиц странно срабатывает, но срабатывает
И так это штукофина работает таки!!! Теперь надо её адаптировать для поиска по многим фоткам и лицам, и чтобы она эти фотки копировала вдругую папку, а для этого надо погрузиться в python, а я его уже не взлюбил…поэтому часть того что нужно сделаю скриптами bash
Итак будет два файла первый pyhon вот такой
vi nrecog.py
вствляем код
import sys import face_recognition import imutils import pickle import time import cv2 import os #find path of xml file containing haarcascade file cascPathface = os.path.dirname( cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml" # load the harcaascade in the cascade classifier faceCascade = cv2.CascadeClassifier(cascPathface) # load the known faces and embeddings saved in last file data = pickle.loads(open('face_enc', "rb").read()) #Find path to the image you want to detect face and pass it here image = cv2.imread(sys.argv[1]) rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) #convert image to Greyscale for haarcascade gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60), flags=cv2.CASCADE_SCALE_IMAGE) # the facial embeddings for face in input encodings = face_recognition.face_encodings(rgb) names = [] # loop over the facial embeddings incase # we have multiple embeddings for multiple fcaes for encoding in encodings: #Compare encodings with encodings in data["encodings"] #Matches contain array with boolean values and True for the embeddings it matches closely #and False for rest matches = face_recognition.compare_faces(data["encodings"], encoding, tolerance=0.5) #set name =inknown if no encoding matches name = "Unknown" # check to see if we have found a match if True in matches: f = open("result.txt", "a") f.write(sys.argv[1] + '\n') f.close() sys.exit()
Это обрезанный и чуть измененный код который был до этого. Он берет с наружи имя файла, которое будем накидывать bash и пишет в файле название если найдет
Создаем српит
vi facecheck.sh
вствляем код
#!/bin/bash IFS=$'\n' folder="test" rm result.txt mkdir "./"$folder"_result" echo $folder for a in $( ls ./$folder ); do python3 nrecog.py $folder/$a echo "./"$folder"/"$a done for a in $( cat ./result.txt | awk -F/ '{print $2}' ); do cp "./"$folder"/"$a "./"$folder"_result/"$a done
тут надо менять только переменнубю folder сейчас там написано папка test
и так в папке у нас три файла facecheck.sh nrecog.py face_enc и папка test с тестовыми фотками(не из обучения)
Запускм срипт
bash ./facecheck.sh
Как он отработаем смотрим файл который он создал result.txt, а так же он копирует все найденные фотки в папк test_result
там получается
28 — всего файлов
9 — сработали как осдержащие Альваро Морте
4 — из них действительно с Альваро
2 — так и не нашло, правда там трудности с лицом — он в профиль, а на втором после пытки
Предпологаю что улучшить этот результат можно лучше прокачавь модель. Беру еще около 2000 скриншотов из видео интервью с Альваро
Делаю сриншот каждой секунды командой
ffmpeg -i video.mp4 -vf fps=1 out%d.jpg
Возвращаюсь на пару шагов назад, кладу их в нужную папку и запускаю обучение — оно уже занимает больше времени!
Опять запускаю распознование
28 — всего файлов
16 — сработали как осдержащие Альваро Морте
6 — из них действительно с Альваро
0 — все Альвары найдены
Должна быть настройка для точности распознования… и она есть!
В файле nrecog.py находим строчку
matches = face_recognition.compare_faces(data["encodings"], encoding)
и меняем её на
matches = face_recognition.compare_faces(data["encodings"], encoding, tolerance=0.4)
Теперь все супер гуд
28 — всего файлов
6 — сработали как осдержащие Альваро Морте
6 — из них действительно с Альваро
0 — все Альвары найдены
Теперь хорошо бы проверить на больших масштабах так чтобы скриншотов 2000 и обычно это проблема, но вот испанский стримнг, надеюсь он не обидеться все же в научных целях — вот тут по ссылке можно безхитростным образом вытащить окло 2350 скринштов — по одному с серии. И я точно знаю что Альваро там был (уже заметил).
Запускаю
При толерантности 0.4 нашел 26 с Морой, при этом глазами я нашел 34, но не нашел 4 где Мора в дали.
Кстати: Процесс обработки 2300 картинок размером 1280×720 у меня занимает 59 минут на:
OS: Ubuntu 20.04.3 LTS
CPU: AMD® Ryzen 7 3700x 8-core processor × 16
Mem: 62,8 GiB
GPU: Nvidia GeForce RTX 2070
Disk: Samsung SSD 970 EVO Plus 500GBПри этом экстремальной нагрузки не возникает, проц с видеокартой даже не прогреваются.
Перезапускаю при толерантности 1.1 НЕТ стоп это слишком много, даже 0.7 много запускаю с 0.5
Найдено 56 из них с Альваро 28. При этом, ладно путает с бородатыми мужиками, но прям неборадатых женщин тоже помечает как Альваро!
Итого: Система помогает найти лица, но точность не очень, видимо это зависит от натренерованной модели. Глазами и своим мозгом у меня ищется быстрее пока — что радает… хотя у ПК возможности по совершенствованию безграничны, а вот мой мозг с каждым годом…
Добавить комментарий