Face recognition based on opencv+python+pycharm
catalog
- preface
- preparation in advance
- Face detection
- Sample collection
- Sample training
- epilogue
preface
I am a sophomore in the University, programming rookie. Recently, I did the final course design, and the topic I chose was face recognition. Write a blog for the first time, want to record the whole process of doing the system, convenient for subsequent use. I stand on the shoulders of giants to make face recognition. Here is my reference blog.
https://www.cnblogs.com/xp12345/p/9818435.html (final reference)
https://blog.csdn.net/WALRE_HUNTER_RICO/article/details/88361212
preparation in advance
- Pycharm (some third-party packages need to be installed)
- Opencv340 (the version should not be too high, which will affect the program operation)
Face detection
Code up (Unknown God)
import numpy as np import cv2 # Face recognition classifier faceCascade = cv2.CascadeClassifier(r'F:/face_test01/haarcascade_frontalface_default.xml') # Eye recognition classifier eyeCascade = cv2.CascadeClassifier(r'F:/face_test01/haarcascade_eye.xml') # Turn on the camera cap = cv2.VideoCapture(0) ok = True result = [] while ok: # Read the image in the camera, ok is the judgment parameter of whether the reading is successful ok, img = cap.read() # Convert to grayscale image gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Face detection faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(32, 32) ) # Eye detection based on face detection for (x, y, w, h) in faces: fac_gray = gray[y: (y+h), x: (x+w)] result = [] eyes = eyeCascade.detectMultiScale(fac_gray, 1.3, 2) # Conversion of eye coordinates, changing relative position to absolute position for (ex, ey, ew, eh) in eyes: result.append((x+ex, y+ey, ew, eh)) # Draw rectangle for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) for (ex, ey, ew, eh) in result: cv2.rectangle(img, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) cv2.imshow('video', img) k = cv2.waitKey(1) if k == 27: # press 'ESC' to quit break cap.release() cv2.destroyAllWindows()
Note: note that the path of the above two classifiers should be changed to the path of their own files
Sample collection
Upper code! (of the great God)
import cv2 import os # Call the built-in camera of the notebook, so the parameter is 0. If there are other cameras, you can adjust the parameter to 1, 2 cap = cv2.VideoCapture(0) # Cascade classifier is a cascaded classifier for face detection in Opencv face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') face_id = input('\n enter user id:') print('\n Initializing face capture. Look at the camera and wait ...') count = 0 while True: # Read pictures from camera sucess, img = cap.read() # Turn to grayscale picture gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Face detection faces = face_detector.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0)) count += 1 # Save image cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w]) cv2.imshow('image', img) # Keep the picture going. k = cv2.waitKey(1) if k == 27: # Exit camera by esc key break elif count >= 1000: # Get 1000 samples and exit the camera break # Turn off camera cap.release() cv2.destroyAllWindows()
Note: 1. Before running this program, please create a Facedata folder and put it in a folder with your program.
(friendly tip: please pack the program and file in a folder called face recognition. You can also put the classifier in it.)
2. During the operation of the program, you will be prompted to enter the id. please start from 0, that is, the data id of the first person's face is 0, and the data id of the second person's face is 1. You can collect the data of one face at a time. (this is very important, which will affect the list of names in face recognition.)
3. The running time of the program may be long, maybe a few minutes. If it is too long, you can change 1000 to 100.
4. About the training samples, I trained 15000, three people. There's a problem that hasn't been figured out yet: as the number of samples increases (for example, training 20000), errors will be reported in face recognition later.
If you can't wait, you can press esc to exit, but the data may not be accurate enough.
training sample
Upper code (God's)
import numpy as np from PIL import Image import os import cv2 # Face data path path = "F:/face_test01/Facedata" # Using LBPH algorithm in OpenCV to build face data model recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") def getImagesAndLabels(path): imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # What is the function of join? faceSamples = [] ids = [] for imagePath in imagePaths: PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale img_numpy = np.array(PIL_img, 'uint8') # Picture format conversion id = int(os.path.split(imagePath)[-1].split(".")[1]) faces = detector.detectMultiScale(img_numpy) # Face detection for (x, y, w, h) in faces: faceSamples.append(img_numpy[y:y + h, x: x + w]) ids.append(id) return faceSamples, ids print('Training faces. It will take a few seconds. Wait ...') faces, ids = getImagesAndLabels(path) recognizer.train(faces, np.array(ids)) recognizer.write(r'face_trainer\trainer.yml') print("{0} faces trained. Exiting Program".format(len(np.unique(ids))))
Note: before running this program, please create face in the face recognition folder_ The trainer folder and modify the file path. (1 place)
Face detection
Code (God's)
import cv2 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('face_trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath) font = cv2.FONT_HERSHEY_SIMPLEX idnum = 0 names = ['Allen', 'Bob'] cam = cv2.VideoCapture(0) minW = 0.1*cam.get(3) minH = 0.1*cam.get(4) while True: ret, img = cam.read() 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) idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w]) if confidence < 100: idnum = names[idnum] confidence = "{0}%".format(round(100 - confidence)) else: idnum = "unknown" confidence = "{0}%".format(round(100 - confidence)) cv2.putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1) cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (0, 0, 0), 1) cv2.imshow('camera', img) k = cv2.waitKey(10) if k == 27: break cam.release() cv2.destroyAllWindows()
Note: the name of a person is stored in the names list. If the id of the person is 0, his name will be in the first place, and the id 1 will be in the second place, and so on. In addition, it's easy to make this mistake here:
There are two reasons for this problem:
1. When inputting ID for the sample collected in the front, letters are input instead of index numbers (0,1,...).
2. The number of trainees does not correspond to the number in the list.
epilogue
Generally speaking, it is relatively easy and fast to make the whole face recognition system because of standing on the shoulders of giants, using the open source code on the Internet, and basically no need to change. What I have done is to do some debugging for small problems such as file path. Finally, I really thank the online programmers for their selfless sharing to us.