Thông tin tài liệu
TRƯỜNG ĐẠI HỌC CƠNG NGHIỆP HÀ NỘI KHOA: CƠ KHÍ ĐỒ ÁN TỐT NGHIỆP CHỦ ĐỀ: NGHIÊN CỨU, THIẾT KẾ HỆ THỐNG NHẬN DIỆN KHN MẶT SỬ DỤNG TRÍ TUỆ NHÂN TẠO Giảng viên hướng dẫn: TS Nguyễn Văn Trường Sinh viên thực hiện: Nguyễn Quang Sáng - 2018601678 Nguyễn Quốc Hưng - 2018603413 Hà Nội, 2022 NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN Hà Nội, ngày tháng năm 2022 Giáo viên hướng dẫn (Ký ghi rõ họ tên) TS Nguyễn Văn Trường NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN Hà Nội, ngày tháng năm 2022 Giáo viên phản biện (Ký ghi rõ họ tên) TS Bùi Thanh Lâm MỤC LỤC MỤC LỤC I Danh mục hình ảnh IV Danh mục bảng biểu VI Danh mục từ viết tắt VII LỜI CẢM ƠN VIII LỜI MỞ ĐẦU CHƯƠNG Giới thiệu chung Về hệ thống nhận diện khuôn mặt 1.1 Các vấn đề đặt 1.2 Tổng quan đề tài 1.3 Ý nghĩa khoa học thực tiễn đề tài 1.3.1 Ý nghĩa khoa học 1.3.2 Ý nghĩa thực tiễn 1.4 Mục tiêu nghiên cứu đề tài 1.5 Đối tượng phạm vi nghiên cứu 1.6 Phương pháp nghiên cứu CHƯƠNG Tổng quan hệ thống nhận diện khuôn mặt sử dụng trí tuệ nhân tạo 2.1 Khái quát chung xử lý ảnh 2.1.1 Một số vấn đề xử lý ảnh 2.1.2 Một số ứng dụng xử lý ảnh 2.2 Tổng quan Open CV 2.2.1 Giới thiệu Open CV 2.2.2 Ứng dụng Open CV 10 2.3 Các phương pháp sử dụng toán nhận diện mặt người 10 2.3.1 Bài toán nhận diện mặt người 10 I 2.3.2 Những khó khăn nhận dạng khn mặt 10 2.3.3 Một số phương pháp giải tốn nhận dạng khn mặt 11 CHƯƠNG Thiết kế hệ thống hệ thống nhận diện khn mặt sử dụng trí tuệ nhân tạo 24 3.1 Sơ đồ tổng quát hệ thống 24 3.2 Sơ đồ cấu trúc chức trình xử lý ảnh 25 3.3 Hệ thống nhận diện khuôn mặt sử dụng thuật toán SVM 25 3.3.1 Sử dụng thuật toán SVM để training liệu 25 3.3.2 Kết nhận diện áp dụng thuật toán SVM 27 3.4 Hệ thống nhận diện khuôn mặt sử dụng mạng CNN 28 3.4.1 Training với VGG-16 28 3.4.2 Training với ResNet-50 31 3.4.3 Mơ hình FaceNet 35 3.5 Xây dựng giao diện người dùng 40 3.5.1 Ứng dụng Qt 40 3.5.2 Giao diện người dùng 42 3.6 Thiết kế hệ thống khí 44 CHƯƠNG Kết Luận định hướng phát triển 46 4.1 Kết 46 4.1.1 Kết kiểm tra nhận diện ảnh 46 4.1.2 Kết kiểm tra nhận diện thực tế 47 4.2 Đánh giá 53 4.2.1 Đối với thuật toán SVM 53 4.2.2 Đối với mô hình FaceNet 53 4.3 Kết luận định hướng phát triển 54 4.3.1 Kết luận 54 II 4.3.2 Định hướng phát triển 54 Tài liệu tham khảo 56 Phụ lục 58 III DANH MỤC HÌNH ẢNH Hình 1: Đề tài nhận diện khn mặt Hình 2: Hệ thống máy chấm cơng tự động Hình 3: Mơ hình nhận diện đối tượng Hình 4: Quá trình tiền xử lý ảnh Hình 5: Ứng dụng xử lý ảnh công nghiệp Hình 6: Thư viện OpenCV Hình 7: Xử lý ảnh 11 Hình 8: Hệ thống nhận dạng khn mặt 12 Hình 9: Mơ hình thuật tốn SVM 13 Hình 10: Đường hyper-plane thuật toán SVM 14 Hình 11: Giải thuật SVM với nhiều lớp 14 Hình 12: Mơ hình mạng CNN 16 Hình 13: Phép tích chập ma trận 17 Hình 14: Phép tích chập xử lý ảnh 18 Hình 15: Hàm ReLU 19 Hình 16: Một số ma trận Kernel lớp tích chập 19 Hình 17: Mơ hình Max-pooling 20 Hình 18: Thuật tốn Triplet loss 21 Hình 19: Lựa chọn input cho Triplet loss 22 Hình 20: Sơ đồ tổng quát hệ thống 24 Hình 21: Sơ đồ trình xử lý ảnh 25 Hình 22: Dữ liệu training sử dụng thuật toán SVM 26 Hình 23: Dán nhãn liệu training 26 Hình 24: Cấu hình máy tính training sử dụng thuật toán SVM 27 Hình 25: Kết nhận diện áp dụng thuật tốn SVM 28 Hình 26: Kiến trúc VGG-16 29 Hình 27: Phương pháp data augment 29 Hình 28: Dữ liệu training VGG-16 30 Hình 29: Dữ liệu Test VGG-16 30 Hình 30: Kết training VGG-16 31 IV det_arr.append(np.squeeze(det[i])) else: bounding_box_size = (det[:,2]-det[:,0])*(det[:,3]-det[:,1]) img_center = img_size / offsets = np.vstack([ (det[:,0]+det[:,2])/2-img_center[1], (det[:,1]+det[:,3])/2-img_center[0] ]) offset_dist_squared = np.sum(np.power(offsets,2.0),0) index = np.argmax(bounding_box_sizeoffset_dist_squared*2.0) # some extra weight on the centering det_arr.append(det[index,:]) else: det_arr.append(np.squeeze(det)) for i, det in enumerate(det_arr): det = np.squeeze(det) bb = np.zeros(4, dtype=np.int32) bb[0] = np.maximum(det[0]-args.margin/2, 0) bb[1] = np.maximum(det[1]-args.margin/2, 0) bb[2] = np.minimum(det[2]+args.margin/2, img_size[1]) bb[3] = np.minimum(det[3]+args.margin/2, img_size[0]) cropped = img[bb[1]:bb[3],bb[0]:bb[2],:] scaled = misc.imresize(cropped, (args.image_size, args.image_size), interp='bilinear') nrof_successfully_aligned += filename_base, file_extension = os.path.splitext(output_filename) if args.detect_multiple_faces: output_filename_n = "{}_{}{}".format(filename_base, i, file_extension) else: output_filename_n = "{}{}".format(filename_base, 88 file_extension) misc.imsave(output_filename_n, scaled) text_file.write('%s %d %d %d %d\n' % (output_filename_n, bb[0], bb[1], bb[2], bb[3])) else: print('Unable to align "%s"' % image_path) text_file.write('%s\n' % (output_filename)) print('Total number of images: %d' % nrof_images_total) print('Number of successfully aligned images: %d' % nrof_successfully_aligned) def parse_arguments(argv): parser = argparse.ArgumentParser() parser.add_argument('input_dir', type=str, help='Directory with unaligned images.') parser.add_argument('output_dir', type=str, help='Directory with aligned face thumbnails.') parser.add_argument(' image_size', type=int, help='Image size (height, width) in pixels.', default=182) parser.add_argument(' margin', type=int, help='Margin for the crop around the bounding box (height, width) in pixels.', default=44) parser.add_argument(' random_order', help='Shuffles the order of images to enable alignment using multiple processes.', action='store_true') parser.add_argument(' gpu_memory_fraction', type=float, help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0) parser.add_argument(' detect_multiple_faces', type=bool, 89 help='Detect and align multiple faces per image.', default=False) return parser.parse_args(argv) if name == ' main ': main(parse_arguments(sys.argv[1:])) Training from future import absolute_import from future import division from future import print_function import tensorflow as tf import numpy as np import argparse import facenet import os import sys import math import pickle from sklearn.svm import SVC def main(args): with tf.Graph().as_default(): with tf.Session() as sess: np.random.seed(seed=args.seed) if args.use_split_dataset: dataset_tmp = facenet.get_dataset(args.data_dir) train_set, test_set = split_dataset(dataset_tmp, args.min_nrof_images_per_class, args.nrof_train_images_per_class) if (args.mode=='TRAIN'): 90 dataset = train_set elif (args.mode=='CLASSIFY'): dataset = test_set else: dataset = facenet.get_dataset(args.data_dir) # Check that there are at least one training image per class for cls in dataset: assert(len(cls.image_paths)>0, 'There must be at least one image for each class in the dataset') paths, labels = facenet.get_image_paths_and_labels(dataset) print('Number of classes: %d' % len(dataset)) print('Number of images: %d' % len(paths)) # Load the model print('Loading feature extraction model') facenet.load_model(args.model) # Get input and output tensors images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0") embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0") phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0") embedding_size = embeddings.get_shape()[1] # Run forward pass to calculate embeddings print('Calculating features for images') nrof_images = len(paths) 91 nrof_batches_per_epoch = int(math.ceil(1.0*nrof_images / args.batch_size)) emb_array = np.zeros((nrof_images, embedding_size)) for i in range(nrof_batches_per_epoch): start_index = i*args.batch_size end_index = min((i+1)*args.batch_size, nrof_images) paths_batch = paths[start_index:end_index] images = facenet.load_data(paths_batch, False, False, args.image_size) feed_dict = { images_placeholder:images, phase_train_placeholder:False } emb_array[start_index:end_index,:] = sess.run(embeddings, feed_dict=feed_dict) classifier_filename_exp = os.path.expanduser(args.classifier_filename) if (args.mode=='TRAIN'): # Train classifier print('Training classifier') model = SVC(kernel='linear', probability=True) model.fit(emb_array, labels) # Create a list of class names class_names = [ cls.name.replace('_', ' ') for cls in dataset] # Saving classifier model with open(classifier_filename_exp, 'wb') as outfile: pickle.dump((model, class_names), outfile) print('Saved classifier model to file "%s"' % classifier_filename_exp) elif (args.mode=='CLASSIFY'): # Classify images 92 print('Testing classifier') with open(classifier_filename_exp, 'rb') as infile: (model, class_names) = pickle.load(infile) print('Loaded classifier model from file "%s"' % classifier_filename_exp) predictions = model.predict_proba(emb_array) best_class_indices = np.argmax(predictions, axis=1) best_class_probabilities = predictions[np.arange(len(best_class_indices)), best_class_indices] for i in range(len(best_class_indices)): print('%4d %s: %.3f' % (i, class_names[best_class_indices[i]], best_class_probabilities[i])) accuracy = np.mean(np.equal(best_class_indices, labels)) print('Accuracy: %.3f' % accuracy) def split_dataset(dataset, min_nrof_images_per_class, nrof_train_images_per_class): train_set = [] test_set = [] for cls in dataset: paths = cls.image_paths # Remove classes with less than min_nrof_images_per_class if len(paths)>=min_nrof_images_per_class: np.random.shuffle(paths) train_set.append(facenet.ImageClass(cls.name, paths[:nrof_train_images_per_class])) test_set.append(facenet.ImageClass(cls.name, 93 paths[nrof_train_images_per_class:])) return train_set, test_set def parse_arguments(argv): parser = argparse.ArgumentParser() parser.add_argument('mode', type=str, choices=['TRAIN', 'CLASSIFY'], help='Indicates if a new classifier should be trained or a classification ' + 'model should be used for classification', default='CLASSIFY') parser.add_argument('data_dir', type=str, help='Path to the data directory containing aligned LFW face patches.') parser.add_argument('model', type=str, help='Could be either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file') parser.add_argument('classifier_filename', help='Classifier model file name as a pickle (.pkl) file ' + 'For training this is the output and for classification this is an input.') parser.add_argument(' use_split_dataset', help='Indicates that the dataset specified by data_dir should be split into a training and test set ' + 'Otherwise a separate test set can be specified using the test_data_dir option.', action='store_true') parser.add_argument(' test_data_dir', type=str, help='Path to the test data directory containing aligned images used for testing.') parser.add_argument(' batch_size', type=int, help='Number of images to process in a batch.', default=90) parser.add_argument(' image_size', type=int, help='Image size (height, width) in pixels.', default=160) parser.add_argument(' seed', type=int, help='Random seed.', default=666) 94 parser.add_argument(' min_nrof_images_per_class', type=int, help='Only include classes with at least this number of images in the dataset', default=20) parser.add_argument(' nrof_train_images_per_class', type=int, help='Use this number of images from each class for training and the rest for testing', default=10) return parser.parse_args(argv) if name == ' main ': main(parse_arguments(sys.argv[1:])) Thuật toán SVM Training import numpy as np import cv2 from sklearn.preprocessing import LabelEncoder from sklearn.svm import SVC import pickle import os import imutils from sklearn.model_selection import GridSearchCV curr_path = os.getcwd() print("Loading face detection model") proto_path = os.path.join(curr_path, 'model', 'deploy.prototxt') model_path = os.path.join(curr_path, 'model', 'res10_300x300_ssd_iter_140000.caffemodel') 95 face_detector = cv2.dnn.readNetFromCaffe(prototxt=proto_path, caffeModel=model_path) print("Loading face recognition model") recognition_model = os.path.join(curr_path, 'model', 'openface_nn4.small2.v1.t7') face_recognizer = cv2.dnn.readNetFromTorch(model=recognition_model) data_base_path = os.path.join(curr_path, 'database') filenames = [] for path, subdirs, files in os.walk(data_base_path): for name in files: filenames.append(os.path.join(path, name)) face_embeddings = [] face_names = [] for (i, filename) in enumerate(filenames): print("Processing image {}".format(filename)) image = cv2.imread(filename) image = imutils.resize(image, width=400) (h, w) = image.shape[:2] image_blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), False, False) face_detector.setInput(image_blob) face_detections = face_detector.forward() i = np.argmax(face_detections[0, 0, :, 2]) confidence = face_detections[0, 0, i, 2] 96 if confidence >= 0.5: box = face_detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") face = image[startY:endY, startX:endX] face_blob = cv2.dnn.blobFromImage(face, 1.0/255, (96, 96), (0, 0), True, False) face_recognizer.setInput(face_blob) face_recognitions = face_recognizer.forward() name = filename.split(os.path.sep)[-2] face_embeddings.append(face_recognitions.flatten()) face_names.append(name) data = {"embeddings": face_embeddings, "names": face_names} le = LabelEncoder() labels = le.fit_transform((data["names"])) recognizer = SVC(C=100, kernel="linear", probability=True) recognizer.fit(data["embeddings"], labels) f = open('recognizer.pickle', "wb") f.write(pickle.dumps(recognizer)) f.close() f = open("le.pickle", "wb") f.write(pickle.dumps(le)) f.close() parameter_candidates = [ 97 {'C': [0.001, 0.01, 0.1, 1, 5, 10, 100, 1000], 'kernel': ['linear']}, ] recognizer= GridSearchCV(estimator=SVC(), param_grid=parameter_candidates, n_jobs=-1) recognizer.fit(data["embeddings"], labels) print('Best score:', recognizer.best_score_) print('Best C:',recognizer.best_estimator_.C) Recognize import numpy as np import pickle import os import cv2 import time import datetime import imutils curr_path = os.getcwd() print("Loading face detection model") proto_path = os.path.join(curr_path, 'model', 'deploy.prototxt') model_path = os.path.join(curr_path, 'model', 'res10_300x300_ssd_iter_140000.caffemodel') face_detector = cv2.dnn.readNetFromCaffe(prototxt=proto_path, caffeModel=model_path) print("Loading face recognition model") recognition_model = os.path.join(curr_path, 'model', 'openface_nn4.small2.v1.t7') 98 face_recognizer = cv2.dnn.readNetFromTorch(model=recognition_model recognizer = pickle.loads(open('recognizer.pickle', "rb").read()) le = pickle.loads(open('le.pickle', "rb").read()) print("Starting test video file") vs = cv2.VideoCapture(0, cv2.CAP_DSHOW) #captureDevice = camera #frame=cv2.imread(r'C:\Users\Quang Sang\Desktop\Python\FaceRecognition\database\Nguyen Quang Sang\User_1.jpg') while True: ret , frame = vs.read() frame = imutils.resize(frame, width=600) (h, w) = frame.shape[:2] image_blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), False, False) face_detector.setInput(image_blob) face_detections = face_detector.forward() for i in range(0, face_detections.shape[2]): confidence = face_detections[0, 0, i, 2] if confidence >= 0.5: box = face_detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") face = frame[startY:endY, startX:endX] (fH, fW) = face.shape[:2] try: 99 face_blob = cv2.dnn.blobFromImage(face, 1.0/255, (96, 96), (0, 0, 0), True, False) except: break face_recognizer.setInput(face_blob) vec = face_recognizer.forward() preds = recognizer.predict_proba(vec)[0] j = np.argmax(preds) proba = preds[j] name = le.classes_[j] #text = "{}: {:.2f}".format(name, proba * 100) y = startY - 10 if startY - 10 > 10 else startY + 10 cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2) #cv2.putText(frame, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) if proba >=0.8: text = "{}: {:.2f}".format(name, proba * 100) cv2.putText(frame, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) else: text = "uknown" cv2.putText(frame, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) cv2.imshow("Frame", frame) 100 key = cv2.waitKey(1) & 0xFF if key == ord('q'): break cv2.destroyAllWindows() 101 Lưu đồ thuật toán điều khiển hệ thống Dữ liệu ảnh đầu vào Trích xuất khn mặt START Hình ảnh thu nhận từ camera So sánh hình ảnh thu nhận với hình ảnh liệu Sai Phát khuôn mặt Đúng Đưa kết nhận diện khuôn mặt Embedding ảnh thành vecto 512 chiều END Tính tốn khoảng cách vecto hàm Triplet loss 102 ... sử dụng toán nhận diện mặt người 2.3.1 Bài toán nhận diện mặt người Hệ thống nhận dạng mặt người hệ thống nhận vào ảnh đoạn video (một chuỗi ảnh) Qua xử lý tính tốn hệ thống xác định vị trí mặt. .. thời kết dự báo chuẩn xác Lựa chọn ngẫu nhiên dễ dẫn tới thuật tốn khơng hội tụ 23 CHƯƠNG THIẾT KẾ HỆ THỐNG HỆ THỐNG NHẬN DIỆN KHUÔN MẶT SỬ DỤNG TRÍ TUỆ NHÂN TẠO 3.1 Sơ đồ tổng quát hệ thống. .. sở nhà nước, Nhóm đặt mục tiêu: Nghiên cứu lý thuyết hệ thống nhận diện khn mặt người sử dụng trí tuệ nhân tạo Nghiên cứu, thiết kế, thử nghiệm mơ hình hệ thống đánh giá để phân tích hạn chế
Ngày đăng: 11/06/2022, 17:47
Xem thêm: