樹莓派4b+raspberry pi camera V2實現實時的人臉檢測


本文我將如何在樹莓派上,使用 OpenCV 和 Python 完成人臉檢測項目。不僅可以實時的檢測,還可以進行學習、訓練和檢測。

項目所需設備

硬件:
樹莓派4b
樹莓派攝像頭模塊(Camrea V2)

語言和庫:
OpenCV
Python 3

環境配置在我上篇博客已經介紹的很詳細了,可以進行參考一下。

首先啟動樹莓派攝像頭模塊。

 運行樹莓派配置工具來激活攝像頭模塊:

$ sudo raspi-config 
進入Interfacing Options然后就可以啟動你想要的功能,移動光標至菜單中的 "Enable Camera(啟用攝像頭)",將其設為Enable(啟用狀態)。完成之后重啟樹莓派。 

在重啟完樹莓派后,我們就可以使用Pi Camera v2了。要用它來拍攝照片的話,可以從命令行運行raspistill:raspistill -o test.jpg

這樣的話就啟動了,注意照片的文件名可以自己任意設置。

 

下載需要的庫

pip install pillow

 

接下來開始項目開始了

本教程使用 OpenCV 完成,一個神奇的「開源計算機視覺庫」,並主要關注樹莓派(因此,操作系統是樹莓派系統)和 Python,但是我也在 Mac 電腦上測試了代碼,同樣運行很好。OpenCV 具備很強的計算效率,且專門用於實時應用。因此,它非常適合使用攝像頭的實時人臉識別。要創建完整的人臉識別項目,我們必須完成3個階段:

1)人臉檢測和數據收集;
2)訓練識別器;
3)人臉識別。

一.我們項目的第一步是創建一個簡單的數據集,該數據集將儲存每張人臉的 ID 和一組用於人臉檢測的灰度圖。

因此,以下命令行將為我們的項目創建一個目錄,目錄名可以如以下為 FaceProject 

mkdir FaceProject

在該目錄中,除了我們為項目創建的 3 個 Python 腳本外,我們還需要儲存人臉分類器。我們可以從 GitHub 中下載:haarcascade_frontalface_default.xml

下一步需要創建一個子目錄「dtatset」,並用它來儲存人臉樣本:

mkdir dataset

收集數據的代碼如下:face_dataset_01.py

 1 import cv2
 2 import os
 3  
 4 cam = cv2.VideoCapture(0)
 5 cam.set(3, 640) # set video width
 6 cam.set(4, 480) # set video height
 7  
 8 face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
 9  
10 # For each person, enter one numeric face id
11 face_id = input('\n enter user id end press <return> ==>  ')
12  
13 print("\n [INFO] Initializing face capture. Look the camera and wait ...")
14 # Initialize individual sampling face count
15 count = 0
16  
17 while(True):
18     ret, img = cam.read()
19     img = cv2.flip(img, -1) # flip video image vertically
20     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
21     faces = face_detector.detectMultiScale(gray, 1.3, 5)
22  
23     for (x,y,w,h) in faces:
24         cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)     
25         count += 1
26  
27         # Save the captured image into the datasets folder
28         cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
29  
30         cv2.imshow('image', img)
31  
32     k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
33     if k == 27:
34         break
35     elif count >= 30: # Take 30 face sample and stop video
36          break
37  
38 # Do a bit of cleanup
39 print("\n [INFO] Exiting Program and cleanup stuff")
40 cam.release()
41 cv2.destroyAllWindows()

 

  運行命令:python face_dataset_01.py

我是以第一個人的ID唯一開始的,收集測試人的30張灰度圖片,存到dataset文件中,可以自己進行查看。

在我的代碼中,我從每一個 ID 捕捉 30 個樣本,我們能在最后一個條件語句中修改抽取的樣本數。如果我們希望識別新的用戶或修改已存在用戶的相片,可以自己進行添加。

 

二.開始訓練數據

下面開始創建子目錄以儲存訓練數據:

mkdir trainer

在第二階段中,我們需要從數據集中抽取所有的用戶數據,並訓練 OpenCV 識別器,這一過程可由特定的 OpenCV 函數直接完成。這一步將在「trainer/」目錄中保存為trainer.yml 文件。

訓練代碼:face_training_02.py

 1 import numpy as np
 2 from PIL import Image
 3 import os
 4  
 5 # Path for face image database
 6 path = 'dataset'
 7  
 8 recognizer = cv2.face.LBPHFaceRecognizer_create()
 9 detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
10  
11 # function to get the images and label data
12 def getImagesAndLabels(path):
13     imagePaths = [os.path.join(path,f) for f in os.listdir(path)]     
14     faceSamples=[]
15     ids = []
16     for imagePath in imagePaths:
17         PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
18         img_numpy = np.array(PIL_img,'uint8')
19         id = int(os.path.split(imagePath)[-1].split(".")[1])
20         faces = detector.detectMultiScale(img_numpy)
21         for (x,y,w,h) in faces:
22             faceSamples.append(img_numpy[y:y+h,x:x+w])
23             ids.append(id)
24     return faceSamples,ids
25  
26 print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
27 faces,ids = getImagesAndLabels(path)
28 recognizer.train(faces, np.array(ids))
29  
30 # Save the model into trainer/trainer.yml
31 recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi
32  
33 # Print the numer of faces trained and end program
34 print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

 運行命令:python face_training_02.py 

數據在被訓練之后,文件「trainer.yml」將保存在我們前面定義的 trainer 目錄下

 

三.人臉識別

 我們將通過攝像頭捕捉一個新人臉,如果這個人的面孔之前被捕捉和訓練過,我們的識別器將會返回其預測的 id 和索引。

代碼如下:face_recognition_03.py

 1 import cv2
 2 import numpy as np
 3 import os 
 4  
 5 recognizer = cv2.face.LBPHFaceRecognizer_create()
 6 recognizer.read('trainer/trainer.yml')
 7 cascadePath = "haarcascade_frontalface_default.xml"
 8 faceCascade = cv2.CascadeClassifier(cascadePath);
 9  
10 font = cv2.FONT_HERSHEY_SIMPLEX
11  
12 #iniciate id counter
13 id = 0
14  
15 # names related to ids: example ==> Marcelo: id=1,  etc
16 names = ['None', 'tanshengjang', 'Paula', 'Ilza', 'Z', 'W'] 
17  
18 # Initialize and start realtime video capture
19 cam = cv2.VideoCapture(0)
20 cam.set(3, 640) # set video widht
21 cam.set(4, 480) # set video height
22  
23 # Define min window size to be recognized as a face
24 minW = 0.1*cam.get(3)
25 minH = 0.1*cam.get(4)
26  
27 while True:
28     ret, img =cam.read()
29     img = cv2.flip(img, -1) # Flip vertically
30     gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
31      
32     faces = faceCascade.detectMultiScale( 
33         gray,
34         scaleFactor = 1.2,
35         minNeighbors = 5,
36         minSize = (int(minW), int(minH)),
37        )
38  
39     for(x,y,w,h) in faces:
40         cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
41         id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
42  
43         # Check if confidence is less them 100 ==> "0" is perfect match 
44         if (confidence < 100):
45             id = names[id]
46             confidence = "  {0}%".format(round(100 - confidence))
47         else:
48             id = "unknown"
49             confidence = "  {0}%".format(round(100 - confidence))
50          
51         cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)
52         cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1)  
53      
54     cv2.imshow('camera',img) 
55  
56     k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
57     if k == 27:
58         break
59  
60 # Do a bit of cleanup
61 print("\n [INFO] Exiting Program and cleanup stuff")
62 cam.release()
63 cv2.destroyAllWindows()

 

運行命令:face_recognition_03.py

這里我們包含了一個新數組,因此我們將會展示「名稱」,而不是編號的 id:

names = ['None', 'tanshengjiang', 'Paula', 'Ilza', 'Z', 'W'] 

所以,如上所示的列表,tanshengjiang的 ID 或索引為 1,Paula 的 ID 等於 2。
可以自行改成自己的名字或者想要的標記。
到這里,項目基本完成了,好好去跑一遍吧,還挺好玩的。
 
原文鏈接:https://shumeipai.nxez.com/2018/03/09/real-time-face-recognition-an-end-to-end-project-with-raspberry-pi.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM