Адамның бетін анықтау және тану

Адамның бетін анықтау және тану
жеке
блог

әл-Фараби атындағы Қазақ Ұлттық университеті, Ақпараттық технологиялар факультеті, Жасанды интеллект және Big Data кафедрасының меңгерушісі Мансурова М.Е. және аға эдвайзер Сакыпбекова М.Ж. бастамасымен екі апталық стажировка өтті. Бизнес аналитика және Big Data мамандығының 2 курс магистранттары Нұраханова А.А. және Шілмағамбетова А.Ә. төмендегі құралдарды пайдаланып, лабораториялық жұмыс жасады. Raspberry Pi 4 мен Raspberry Pi Camera – ны пайдаланып, Python-да адамның бетін анықтау және тану.

Керекті құралдар:

  • Raspberry Pi 4 Model B
  • Raspberry Pi Camera
  • HDMI
  • SD card
  • Монитор, тінтуір, клавитура
  • Блок питания - 5А

Raspberry Pi-бұл ересек адамның алақанына оңай сәйкес келетін миниатюралық бір тақталы компьютер. Қарапайым мөлшеріне қарамастан, тақтаның жоғары өнімділігі бар, бұл оған тұрақты компьютерлермен бір деңгейге жетуге мүмкіндік береді.

1. Raspberry Pi 4 қондыру.

1.1. Raspberry Pi OS using Raspberry Pi Imager қондыру. Ссылкасы:  https://www.raspberrypi.org/software/

1.2. Raspberry Pi Imager – ды ашып, керекті операциялық жүйені таңдап, SD картаға Write батырмасын басу арқылы жазу керек.

1.3. SD картаны Raspberry Pi 4 процессорына қондыру.

2. Камераны процессорға қосу.  Raspberry Pi Configuration-да камера «enabled» болып тұруы қажет.

3. Python программалау тілін қондыру.

4. OpenCV –ді Raspberry Pi 4 процессорына қондыру. Қондыру сілтемесі: https://robotclass.ru/articles/raspberrypi-3-opencv-3-install/

OpenCV –дің дұрыс қондырылуын тексеру:

5. Бетті танудың толық жобасын құру үшін біз үш түрлі кезеңде жұмыс жасауымыз керек:

  • Бетті анықтау және деректерді жинау
  • Танушыларды оқыту
  • Бетті тану

Төмендегі блок-схема қадамдарды көрсетеді:

6. Адамның бетін анықтау

Бетті танудың ең негізгі міндеті, әрине,"бетті анықтау". Ең алдымен, болашақта қолданатын жаңа адамның кескінімен салыстырғанда, оны тану үшін бетті "анықтау" керек.

Бетті (немесе кез-келген нысанды) анықтаудың ең көп таралған әдісі "Хаар каскадтарының классификаторын"қолданады.

"Хаар каскадтарының классификаторын" қолдана отырып, нысандарды анықтау - 2001 жылы Пол Виола мен Майкл Джонс өзінің "қарапайым функциялардың кеңейтілген каскадын қолдана отырып, нысандарды жылдам анықтау" мақаласында ұсынған нысандарды анықтаудың тиімді әдісі. Бұл оқыту механизміне негізделген тәсіл, каскадты функция көптеген оң және теріс бейнелерден үйренеді. Содан кейін ол басқа суреттердегі нысандарды анықтау үшін қолданылады.

Бастапқыда алгоритм классификаторды оқыту үшін көптеген оң кескіндерді (бет суреттері) және теріс кескіндерді (бет суреттері) қажет етеді. Содан кейін біз одан функцияларды алып тастауымыз керек. OpenCV жаттықтырушымен, сонымен қатар детектормен бірге келеді. Егер сіз өзіңіздің классификаторыңызды автомобиль, ұшақ және т.б. сияқты кез-келген объектіге үйреткіңіз келсе, оны жасау үшін OpenCV қолдана аласыз.

faceDetection.py:

import numpy as np

import cv2

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades

faceCascade = cv2.CascadeClassifier('/home/pi/Downloads/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)

cap.set(3,640) # set Width

cap.set(4,480) # set Height

while True:

    ret, img = cap.read()

    img = cv2.flip(img, -1)

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(

        gray,

        scaleFactor=1.2,

        minNeighbors=5,    

        minSize=(20, 20)

    )

    for (x,y,w,h) in faces:

        cv2.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]

    cv2.imshow('video',img)

#if cv2.waitKey(1) & 0xFF == ord('q'):

    k = cv2.waitKey(30) & 0xff

    if k == 27: # press 'ESC' to quit

        break

cap.release()

cv2.destroyAllWindows()


7. Мәліметтерді жинау

Мұнда не істейтініміз соңғы қадамнан басталады (бетті анықтау), біз әр идентификатор үшін сақтайтын мәліметтер жиынтығын, бетті анықтау үшін пайдаланылған бөлігі бар сұр түсті фотосуреттер тобын жасаймыз.

Алдымен сіздің жобаңызды жасайтын каталог жасаңыз, мысалы, FacialRecognitionProject:

Бұл каталогта біздің жобамыз үшін жасайтын 3 python сценарийінен басқа, біз оған бет классификаторын сақтауымыз керек.

Содан кейін біз бет үлгілерін сақтайтын және оны "dataset" деп атайтын ішкі каталог жасаймыз:

01_face_dataset.py:

import cv2
import os
 
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video width
cam.set(4, 480) # set video height
 
face_detector = cv2.CascadeClassifier('/home/pi/Downloads/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml')
 
# For each person, enter one numeric face id
face_id = input('\n enter user id end press  ==>  ')
 
print("\n [INFO] Initializing face capture. Look the camera and wait ...")
# Initialize individual sampling face count
count = 0
while(True):
    ret, img = cam.read()
    img = cv2.flip(img, -1) # flip video image vertically
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)    
        count += 1
      # Save the captured image into the datasets folder
        cv2.imwrite("/home/pi/python/dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
 
       cv2.imshow('image', img)
    k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break
    elif count >= 30: # Take 30 face sample and stop video
         break
 
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()


Пайдаланушы идентификаторын түсіруге арналған" енгізу пәрмені", ол бүтін сан болуы керек (1, 2, 3 және т. б.):

Түсірілген кадрлардың әрқайсысы үшін біз оны "dataset" каталогында файл ретінде сақтауымыз керек:

Жоғарыда аталған файлды сақтау үшін "os" кітапханасын импорттау қажет екенін ескеріңіз. Әр файлдың аты құрылымға сәйкес келеді:

Мысалы, face_id = 1 бар пайдаланушы үшін dataset / каталогындағы файлдың 4-ші мысалы келесідей болады:

Біздің кодта біз әр идентификатордан 30 үлгіні жинаймыз. Сіз оны соңғы "elif" - те өзгерте аласыз. Үлгілер саны бет үлгілері алынған циклды бұзу үшін қолданылады.

8. Жаттықтыру

Осы екінші кезеңде біз барлық пайдаланушы деректерін деректер жиынтығынан және OpenCV Recognizer-дегі "нұсқаушыдан" алуымыз керек. Бұл белгілі бір OpenCV функциясы арқылы тікелей жасалады. Нәтиже "trainer /" каталогында сақталатын .yml файлы болады.

Сонымен, дайындалған деректерді сақтайтын ішкі каталогты құруды бастайық:

02_face_training.py:

import cv2
import numpy as np
from PIL import Image
import os
 
path = '/home/pi/python/dataset'
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier('/home/pi/Downloads/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml');
 
# function to get the images and label data
def getImagesAndLabels(path):
 
    imagePaths = [os.path.join(path,f) for f in os.listdir(path)]    
    faceSamples=[]
    ids = []
 
   for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
        img_numpy = np.array(PIL_img,'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x,y,w,h) in faces:
            faceSamples.append(img_numpy[y:y+h,x:x+w])
            ids.append(id)
    return faceSamples,ids
print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces,ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
 
# Save the model into trainer/trainer.yml
recognizer.write('/home/pi/python/trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi
 
# Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

 
Біз OpenCV пакетіне кіретін LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) Face Recognizer-ді танушы ретінде қолданамыз. Біз мұны келесі жолда жасаймыз:

"GetImagesAndLabels (path)" функциясы каталогтағы барлық фотосуреттерді қабылдайды: "dataset /", 2 массивті қайтарады: "идентификаторлар(lds)" және "беттер(Faces)". Осы массивтермен біз кіріс ретінде «біздің бетті анықтаушыны үйретеміз»:

Нәтижесінде "trainer.yml " біз бұрын жасаған жаттықтырушы каталогында сақталады.

9. Адамның бетін тану

Енді біз жобамыздың соңғы кезеңіне жеттік. Мұнда біз камерада бет-әлпетті көреміз, егер бұл адам бұрын суретке түсіп, оқытылса, біздің анықтаушы өзінің идентификаторы мен индексін қайтаратын "өңдеуді" жасайды, бұл белгінің қаншалықты сенімді екенін көрсетеді.

Біз мұнда жаңа массивті қосамыз, сондықтан нөмірленген идентификаторларды емес, "адамның есімдерін" көрсетеміз.

03_face_recognition.py:

import cv2
import numpy as np
import os
 
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('/home/pi/python/trainer/trainer.yml')
cascadePath = '/home/pi/Downloads/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(cascadePath);
 
font = cv2.FONT_HERSHEY_SIMPLEX
 
#iniciate id counter
id = 0
 
# names related to ids: example ==> Marcelo: id=1,  etc
names = ['None', 'Azhar', 'Ayazhan', 'Omirbek', 'Aisha']
 
# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height
 
# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
 
while True:
    ret, img =cam.read()
    img = cv2.flip(img, -1) # Flip vertically
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor = 1.2,
        minNeighbors = 5,
        minSize = (int(minW), int(minH)),
       )
 
    for(x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
        id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
        # Check if confidence is less them 100 ==> "0" is perfect match
        if (confidence < 100):
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
        else:
            id = "unknown"
            confidence = "  {0}%".format(round(100 - confidence))
       
        cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)
        cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1) 
    cv2.imshow('camera',img)
    k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break
 
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()

Мысалы: Azhar id = 1 бар пайдаланушы болады; Ayazhan: id = 2 т. б.

Содан кейін біз haascascade классификаторын қолдана отырып, бұрынғыдай бетті табамыз. Анықталған тұлға арқылы біз жоғарыдағы кодтағы ең маңызды функцияны атай аламыз:

Ecognizer.predict() функциясы талданатын тұлғаның түсірілген бөлігін параметр ретінде қабылдайды және сәйкестендіргішті және осы сәйкестікке байланысты танушының сенімділік дәрежесін көрсете отырып, оның ықтимал иесін қайтарады.

Нәтижесі: