最近在學習OpenCV,它是一個高效的計算機視覺和機器學習軟體庫。在學習過程中,我突發奇想,打算搞一個AAJ人臉識別程序。在幾天的學習和一下午的ctrl+c和ctrl+v後,我終於實現了這一功能——通過訓練10張左右AAJ同學提供的訓練照片(training-data),可以判斷測試圖片(test-data)是否為AAJ本人。
考慮到個人隱私,我將訓練對象改為大家喜聞樂見的坤坤,以下為展示視頻:
(科普:右圖為萊娜·瑟德貝裡,1951年3月31日出生於瑞典,在1972年11月期的《花花公子》雜誌中,她化名為萊娜·舍布洛姆,成為了當期的玩伴女郎。她的中間折頁照片由Dwight Hooker拍攝。她的照片(即萊娜圖)後來被數字圖像處理領域所廣泛使用。)
下面向大家展示一下我從網上學習的原始碼:
(IDE為pycharm,需預先安裝opencv-python、numpy、opencv-contrib-python)
cv2.destroyAllWindows()import cv2import osimport numpy as npsubjects = ["", "kunkun", "Others"]
def detect_face(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
if (len(faces) == 0): return None, None (x, y, w, h) = faces[0]
return gray[y:y+w, x:x+h], faces[0]
def prepare_training_data(data_folder_path):
dirs = os.listdir(data_folder_path)
faces = []
labels = []
for dir_name in dirs:
if not dir_name.startswith("s"): continue label = int(dir_name.replace("s", ""))
subject_dir_path = data_folder_path + "/" + dir_name
subject_images_names = os.listdir(subject_dir_path)
for image_name in subject_images_names:
if image_name.startswith("."): continue image_path = subject_dir_path + "/" + image_name
image = cv2.imread(image_path)
cv2.imshow("Training on image...", cv2.resize(image, (400, 500))) cv2.waitKey(100)
face, rect = detect_face(image)
if face is not None:
faces.append(face)
labels.append(label) cv2.destroyAllWindows() cv2.waitKey(1) cv2.destroyAllWindows() return faces, labels
print("Preparing data...")faces, labels = prepare_training_data("training-data")print("Data prepared")
print("Total faces: ", len(faces))print("Total labels: ", len(labels))
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))
def draw_rectangle(img, rect): (x, y, w, h) = rect cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
def draw_text(img, text, x, y): cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)
def predict(test_img):
img = test_img.copy()
face, rect = detect_face(img)
label, confidence = face_recognizer.predict(face)
if confidence < 60 : label_text = subjects[1]
else: label_text = subjects[2]
draw_rectangle(img, rect)
draw_text(img, label_text, rect[0], rect[1]-5)
print(label) print(confidence) return img
print("Predicting images...")
test_img1 = cv2.imread("test-data/test1.jpg")test_img2 = cv2.imread("test-data/test2.jpg")
predicted_img1 = predict(test_img1)predicted_img2 = predict(test_img2)
print("Prediction complete")
cv2.imshow("face1", cv2.resize(predicted_img1, (400, 500)))cv2.imshow("face2", cv2.resize(predicted_img2, (400, 500)))cv2.waitKey(0)cv2.destroyAllWindows()cv2.waitKey(1)其中,測試圖片存放在test-data文件夾中
訓練圖片存放在training-data文件夾中,標籤為s1
終於,我們的計算機認識坤坤啦!
歡迎大家批評與指正。
注釋大部分來自:
https://www.cnblogs.com/zhuifeng-mayi/p/9171383.html
項目下載連結:
https://github.com/informramiz/opencv-face-recognition-python