1.OpenCV基本介绍
OpenCV 是一个开源的计算机视觉库,可以从 http://opencv.org 获取。
OpenCV 设计用于进行高效的计算,十分强调实时应用的开发。
它由 C++ 语言编写并进行了深度优化,从而可以享受多线程处理的优势。
OpenCV 的一个目标是提供易于使用的计算机视觉接口,从而帮助人们快速建立精巧的视觉应用。
OpenCV 库包含从计算机视觉各个领域衍生出来的 500 多个函数,包括工业产品质量检验、医学图像处理、安保领域、交互操作、相机校正、双目视觉以及机器人学。
因为计算机视觉和机器学习经常在一起使用,所以 OpenCV 也包含一个完备的、具有通用性的机器学习库(ML模块)。
这个子库聚焦于统计模式识别以及聚类。ML 模块对 OpenCV 的核心任务(计算机视觉)相当有用,但是这个库也足够通用,可以用于任意机器学习问题。
2.OpenCV安装
pip install opencv-python
pip install opencv-contrib-python
3.操作目录说明
上面的目录和名称,OpenCV小白千万不要改变。
4.代码实现
''' author : zhaofeng092 data : 2020.1.6 goal : OpenCV人脸识别Demo ''' # # -*- coding:utf-8 -*- import cv2 import os import numpy as np # 检测人脸 def detect_face(img): # 将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 加载OpenCV人脸检测分类器Haar face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5) print(faces) # 如果未检测到面部,则返回原始图像 if (len(faces) == 0): return None, None # 目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高 (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: # dir_name(str类型)即标签 label = int(dir_name) # 建立包含当前主题主题图像的目录路径 subject_dir_path = data_folder_path + "/" + dir_name # 获取给定主题目录内的图像名称 subject_images_names = os.listdir(subject_dir_path) # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[] for image_name in subject_images_names: # 建立图像路径 image_path = subject_dir_path + "/" + image_name # 读取图像 image = cv2.imread(image_path) # 显示图像0.1s cv2.imshow("Training on image...", image) cv2.waitKey(100) # 检测脸部 face, rect = detect_face(image) # 我们忽略未检测到的脸部 if face is not None: # 将脸添加到脸部列表并添加相应的标签 faces.append(face) labels.append(label) cv2.waitKey(1) cv2.destroyAllWindows() # 最终返回值为人脸和标签列表 return faces, labels # 调用prepare_training_data()函数 faces, labels = prepare_training_data("training_data") # 创建LBPH识别器并开始训练,当然也可以选择Eigen或者Fisher识别器 face_recognizer = cv2.face.LBPHFaceRecognizer_create() face_recognizer.train(faces, np.array(labels)) # 根据给定的(x,y)坐标和宽度高度在图像上绘制矩形 def draw_rectangle(img, rect): (x, y, w, h) = rect cv2.rectangle(img, (x, y), (x + w, y + h), (128, 128, 0), 2) # 根据给定的(x,y)坐标标识出人名 def draw_text(img, text, x, y): cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2) # 建立标签与人名的映射列表(标签只能为整数) subjects = ["jay zhou", "another zhou"] # 此函数识别传递的图像中的人物并在检测到的脸部周围绘制一个矩形及其名称 def predict(test_img): # 生成图像的副本,这样就能保留原始图像 img = test_img.copy() # 检测人脸 face, rect = detect_face(img) # 预测人脸 label = face_recognizer.predict(face) # 获取由人脸识别器返回的相应标签的名称 label_text = subjects[label[0]] # 在检测到的脸部周围画一个矩形 draw_rectangle(img, rect) # 标出预测的名字 draw_text(img, label_text, rect[0], rect[1] - 5) # 返回预测的图像 return img # 加载测试图像 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) # 显示两个图像 cv2.imshow(subjects[0], predicted_img1) cv2.imshow(subjects[1], predicted_img2) cv2.waitKey(0) cv2.destroyAllWindows()
结果: