目录
介绍
细节
使用代码
最后结果
- 下载数据集 - 3.8 MB
- 下载完整的源代码 - 2.1 KB
Akinator最初是为了通过回答一些问题来预测著名人物而创建的游戏,但现在Akinator想要改进人工智能概念,尤其是计算机视觉。新的Akinator正在开发Akinator Vision,它仅根据图片识别著名角色,他们希望在一些已经开发的应用程序中添加新的计算机视觉功能。此功能将允许应用程序根据已上传到已开发应用程序的单个面部的个人资料图像检测和识别每个字符。因此,作为Akinator Vision的程序员,您需要使用Python编程语言和OpenCv库创建一个简单的演示功能。
细节1、数据集描述
给定的数据集包含由Akinator Vision开发的应用程序上传的7个用户的总共44张个人资料图片和由5个随机用户个人资料图片组成的测试图像组成的训练数据集。
2、获取训练图像标签
给定训练数据集的目录将存储在一个包含每个著名角色名称的列表中。该列表也将用作训练图像的标签。
3、获取训练图像数据
图像数据将存储到图像列表中。
4、检测人脸并过滤
将检测训练图像中的人脸并将其存储到图像列表中。检测到的人脸的位置和大小也将存储到矩形列表中。如果没有人脸或检测到多于一张人脸,您还需要过滤训练图像(将图像宽度调整为300像素,将图像高度调整为训练图像的相应比例)。
5、训练数据
已经检测到的人脸图像列表将用于训练人脸识别分类器。
6、获取测试图像数据
选择的测试图像将被加载和存储。
7、预测测试图像
将根据上面训练的分类器预测测试图像列表以产生预测结果。
8、写入预测结果
由预测的用户姓名组成的预测结果将被绘制到每个测试图像。上一步中存储的人脸周围的矩形也将一起绘制。
9、结合并展示
已绘制的测试图像列表将合并为单个图像。之后,程序将显示组合结果。
使用代码上面提到的所有步骤都已经放在了代码中对应的函数中。
# Import Library Needed
import os
import cv2
import numpy as np
# Main
if __name__ == "__main__":
'''
Please modify train_path value according to the location of
your data train root directory
-------------------
Modifiable
-------------------
'''
train_path = "dataset/train"
'''
-------------------
End of modifiable
-------------------
'''
train_image_labels, train_image_indexes = get_all_train_image_labels(train_path)
train_image_list = get_all_train_images(train_path)
gray_train_image_list, _, gray_train_labels = detect_faces_and_filter\
(train_image_list, train_image_indexes)
classifier = train(gray_train_image_list, gray_train_labels)
'''
Please modify test_path value according to the location of
your data train root directory
-------------------
Modifiable
-------------------
'''
test_path = "dataset/test"
'''
-------------------
End of modifiable
-------------------
'''
test_image_list = get_all_test_images(test_path)
gray_test_image_list, gray_test_location, _ = detect_faces_and_filter(test_image_list)
predict_results = predict(classifier, gray_test_image_list)
predicted_test_image_list = write_prediction(predict_results, \
test_image_list, gray_test_location, train_image_labels)
combine_and_show_result(predicted_test_image_list)
# Function to Labelling and Indexing Training Images
def get_all_train_image_labels(path):
image_list = []
image_index = []
train_directory = os.listdir(path)
for index, train in enumerate(train_directory):
image_path_list = os.listdir(path + '/' + train)
image_list.append(train)
for image_path in image_path_list:
if(image_path[-3:]=='jpg'):
image_index.append(index)
return image_list,image_index
'''
To get a list of path directories from root path
Parameters
----------
path : str
Location of root directory
Returns
-------
list
List containing all train images label
list
List containing all train images indexes
'''
# Function to Get All Training Images
def get_all_train_images(path):
image_data = []
train_directory = os.listdir(path)
for train in train_directory:
image_path_list = os.listdir(path + '/' + train)
for image_path in image_path_list:
if(image_path[-3:]=='jpg'):
image = cv2.imread(path +'/' + train + '/' + image_path)
image_data.append(image)
return image_data
'''
Get all Train Images & resize it using the given path
Parameters
----------
path : str
Location of root directory
Returns
-------
list
List containing all the resized train images
'''
# Function to Detect Faces Using Haarcascade
def detect_faces_and_filter(image_list, image_labels=None):
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
image_location = []
image_penampung = []
label_penampung = []
for idx,image in enumerate(image_list):
faces = face_cascade.detectMultiScale(image, 1.2, 3)
if len(faces)==1:
for x,y,w,h in faces:
image_location.append((x,y,w,h))
image_crop = image[y:y+h,x:x+w]
width = 300
height = int(image_crop.shape[0] * width / image_crop.shape[1])
dim = (width,height)
image_crop = cv2.resize(image_crop,dim)
image_crop = cv2.cvtColor(image_crop,cv2.COLOR_BGR2GRAY)
image_penampung.append(image_crop)
if image_labels is not None:
label_penampung.append(image_labels[idx])
return image_penampung,image_location,label_penampung
'''
To detect a face from given image list and filter it if the face on
the given image is not equals to one
Parameters
----------
image_list : list
List containing all loaded images
image_labels : list
List containing all image classes labels
Returns
-------
list
List containing all filtered and cropped face images in grayscale
list
list containing image gray face location
list
List containing all filtered image classes label
'''
# Function to do Training using LBPH Recognizer
def train(gray_image_list, gray_labels):
lbph = cv2.face.LBPHFaceRecognizer_create()
lbph.train(gray_image_list,np.array(gray_labels))
return lbph
'''
To create and train face recognizer object
Parameters
----------
gray_image_list : list
List containing all filtered and cropped face images in grayscale
gray_labels : list
List containing all filtered image classes label
Returns
-------
object
Classifier object after being trained with cropped face images
'''
# Function to Get All Testing Images
def get_all_test_images(path):
image_data = []
image_path_list = os.listdir(path + '/')
for image_path in image_path_list:
if(image_path[-3:]=='jpg'):
image = cv2.imread(path +'/'+ image_path)
image_data.append(image)
return image_data
'''
To load a list of test images from given path list
Parameters
----------
path : str
Location of images root directory
Returns
-------
list
List containing all image in the test directories
'''
# Function to Predict the Face Images in Test Set
def predict(classifier, gray_test_image_list):
prediction_list = []
for image in gray_test_image_list:
lists, _ = classifier.predict(image)
prediction_list.append(lists)
return prediction_list
'''
To predict the test image with the classifier
Parameters
----------
classifier : object
Classifier object after being trained with cropped face images
gray_test_image_list : list
List containing all filtered and cropped face images in grayscale
Returns
-------
list
List containing all prediction results from given test faces
'''
# To draw prediction results on the given test images and resize the image Parameters
def write_prediction(predict_results, test_image_list, test_faces_rects, train_labels):
train_labels = np.unique(train_labels)
images = []
for idx,image in enumerate(test_image_list):
x, y, w, h = test_faces_rects[idx]
image = cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
image = cv2.putText(image,train_labels[predict_results[idx]],\
(x,y-10),cv2.FONT_HERSHEY_COMPLEX,1,(0,0,255),2)
images.append(image)
return images
'''
To draw prediction results on the given test images and resize the image
Parameters
----------
predict_results : list
List containing all prediction results from given test faces
test_image_list : list
List containing all loaded test images
test_faces_rects : list
List containing all filtered faces location saved in rectangle
train_names : list
List containing the names of the train sub-directories
Returns
-------
list
List containing all test images after being drawn with
final result
'''
# To show the final image that already combine into one image
def combine_and_show_result(image_list):
scale_percent = 60 # percent of original size
width = int(image_list[0].shape[1] * scale_percent / 100)
height = int(image_list[0].shape[0] * scale_percent / 100)
dim = (width, height)
image_list[0] = cv2.resize(image_list[0], dim, interpolation = cv2.INTER_AREA)
width = int(image_list[1].shape[1] * scale_percent / 100)
height = int(image_list[1].shape[0] * scale_percent / 100)
dim = (width, height)
image_list[1] = cv2.resize(image_list[1], dim, interpolation = cv2.INTER_AREA)
width = int(image_list[2].shape[1] * scale_percent / 100)
height = int(image_list[2].shape[0] * scale_percent / 100)
dim = (width, height)
image_list[2] = cv2.resize(image_list[2], dim, interpolation = cv2.INTER_AREA)
width = int(image_list[3].shape[1] * scale_percent / 100)
height = int(image_list[3].shape[0] * scale_percent / 100)
dim = (width, height)
image_list[3] = cv2.resize(image_list[3], dim, interpolation = cv2.INTER_AREA)
width = int(image_list[4].shape[1] * scale_percent / 100)
height = int(image_list[4].shape[0] * scale_percent / 100)
dim = (width, height)
image_list[4] = cv2.resize(image_list[4], dim, interpolation = cv2.INTER_AREA)
combined_image = np.hstack(image_list)
cv2.imshow("Final Result",combined_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
'''
To show the final image that already combine into one image
Parameters
----------
image_list : nparray
Array containing image data
'''
最后结果
数据集来自谷歌图片。(注意:为了本案例的目的,修改了一些数据集。)
https://www.codeproject.com/Tips/5320792/Akinator-Vision