cv2
cv2是OpenCV库中的一个模块,OpenCV的Python绑定库。
图像处理功能,还集成了一些高级的计算机视觉算法。
cv2.rectangle
图像上绘制矩形,cv2.rectangle(Numpy图片, 左上坐标, 右下坐标, color, thickness粗度)
cv2.cvtColor(图像,颜色空间转换代码)
不同颜色空间之间转换图像
cv.CascadeClassifier
cv2.imwrite(
图像的保存路径(包括文件名),要保存的图像数据)
:保存图像到文件的函数
def paint_face_rectangle(image,faces):for face in faces:#遍历该张图片(帧)上所有人脸cv.rectangle(image, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 3)return image
'''
face.left()是一个方法需要加括号,不是一个属性
(0,255,0)是BGR颜色空间中的绿色
粗细宽度为三像素'''
capture = cv.VideoCapture(0)
'''
实例化一个capture(0表示打开内置摄像头)(还可以打开视频外部摄像头)
相当于一个视频流的集合,还可用作后续一系列操作capture.read()
视频流的逐帧读取,返回两个值(需要在循环里面,因为逐帧)
一个布尔值( True 或 False),表示帧是否被成功读取
一个图像数组(如果成功读取),当前帧的图像'''
人脸检测器
detector = dlib.get_frontal_face_detector()
detector_results = detector(gray_image, 1)
1 在这个上下文中是一个参数,它指定了人脸检测器在检测人脸时应该使用的“上采样次数”或“图像金字塔的层数”。这个参数允许您控制人脸检测器在检测不同大小的人脸时的灵敏度。通过增加这个参数的值,您可以让检测器在更大的图像范围内搜索人脸,从而能够检测到更小的人脸,但这也可能会增加计算成本并降低检测速度。如果这个参数设置为 0,那么检测器将只在原始图像大小上搜索人脸。
如果设置为 1,那么检测器将首先在原始图像大小上搜索,然后将图像大小增加一倍(或按照某种比例上采样),并在上采样后的图像上再次搜索。
如果设置为更高的值,那么检测器将在更多不同大小的图像上搜索人脸。
因此,在这个例子中,1 表示检测器将在原始图像大小和上采样一次后的图像大小上搜索人脸。
capture.release()
与视频捕获相关的资源被正确释放,避免资源泄露。
cv.destroyAllWindows()
关闭所有由OpenCV创建的窗口,释放与之相关的资源
imagePaths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))][表达式 for 变量 in 可迭代对象 if 条件]表达式:os.path.join(path, f)
对于满足条件(即是一个文件)的每个文件名f,这个表达式将目录路径path和文件名f组合成完整的文件路径。变量:f
文件名可迭代对象:os.listdir(path)
这个函数返回指定目录(path)下所有文件和子目录的名称列表条件:os.path.isfile(os.path.join(path, f))
这是一个条件判断语句。对于每个文件名f,它首先使用os.path.join(path, f)将目录路径和文件名组合成完整的文件路径。
然后,os.path.isfile()函数检查这个完整路径是否指向一个文件(而不是目录)。如果是文件,条件判断为真(True)[表达式 for 变量 in 可迭代对象 if 条件]
在这个例子中,表达式是os.path.join(path, f),变量是f,可迭代对象是os.listdir(path)返回的文件名列表,条件是os.path.isfile(os.path.join(path, f))。
因此,整行代码的作用是:遍历指定目录path下的所有文件和子目录名称,对于每个名称,检查它是否指向一个文件。如果是,就将其完整路径添加到imagePaths列表中。最终,imagePaths将包含目录path下所有文件的完整路径。
cv2.CascadeClassifier()
加载一个预训练的Haar或LBP特征级联分类器。这些分类器用于对象检测,比如人脸、眼睛等。
recognizer = cv.face.LBPHFaceRecognizer_create()
recognizer.train(faces, np.array(ids))
基于局部二值模式直方图(LBPH)的人脸识别器实例。利用图像中局部纹理特征进行人脸识别的方法。
使用 train() 方法来训练它,提供一组已知人脸的图像和对应的标签(通常是人的身份标识)。
import cv2 as cv
import argparse
import re
import dlib
from PIL import Image
import numpy as np
import os# 人脸矩形框
def paint_face_rectangle(image,faces):for face in faces:#遍历该张图片(帧)上 所有 人脸cv.rectangle(image, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 3)return image# def getImageAndLabel(path):
# faceSamples = []
# ids = []
# imagePaths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
# face_detector = cv.CascadeClassifier("E:/python_project_sumvac/python_practice/haarcascade_frontalface_alt2.xml")
# for imagePath in imagePaths:
# PIL_image = Image.open(imagePath).convert('L')
# numpy_image = np.array(PIL_image, 'uint8')
# faces = face_detector.detectMultiScale(numpy_image)
# id = int(os.path.split(imagePath)[1].split('.')[0])
# # 提取文件名中数字和字母组合
# # filename = os.path.split(imagePath)[1]
# # id_match = re.search(r'[\w]+', filename) # 匹配字母和数字的组合
# # if id_match:
# # id = id_match.group() # 提取匹配的部分
# # else:
# # print(f"Warning: No valid ID found in {filename}, skipping file.")
# # continue
# for x, y, w, h in faces:
# ids.append(id)
# faceSamples.append(numpy_image[y:y+h, x:x+w])
# print('id:', id)
# print('fs:', faceSamples)
# return faceSamples, ids# def main():
# num = 1
# #开摄像头,取视频
# capture = cv.VideoCapture(0)
# #摄像头是否正常
# if capture.isOpened() is False:
# print("Camera is not opened!")
#
# while capture.isOpened():
# ret, frame = capture.read()
# if ret:
# gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#灰度转换
# detector = dlib.get_frontal_face_detector()
# detector_results = detector(gray_frame, 1)
#
# new_image = paint_face_rectangle(frame, detector_results)
#
# #显示
# cv.imshow("face detection", new_image)# #人脸录入实现# if cv.waitKey(1) & 0xFF == ord('r'):# cv.imwrite("E:/python_project_sumvac/python_practice/facein/"+str(num)+"zzt"+".jpg",frame)# print("Success to save"+str(num)+".jpg")# print("------")# num += 1# elif cv.waitKey(1) == 27:# break# capture.release()# cv.destroyAllWindows()#
# if __name__ == '__main__':
# # # main()
# # path = 'E:/python_project_sumvac/python_practice/facein/'
# # faces,ids = getImageAndLabel(path)
# # recognizer = cv.face.LBPHFaceRecognizer_create()
# # recognizer.train(faces, np.array(ids))
# # recognizer.write("E:/python_project_sumvac/python_practice/trainer.yml")
#
# recognizer = cv.face.LBPHFaceRecognizer_create()
# recognizer.read("E:/python_project_sumvac/python_practice/facein/trainer.yml")
# names=[]
# warningtime = 0recognizer = cv.face.LBPHFaceRecognizer_create()
recognizer.read("E:/python_project_sumvac/python_practice/trainer.yml")
names = []
warningtime = 0def face_detect_demo(img):gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)face_detector = cv.CascadeClassifier("E:/python_project_sumvac/python_practice/haarcascade_frontalface_alt2.xml")face = face_detector.detectMultiScale(gray, 1.1, 5, cv.CASCADE_SCALE_IMAGE, (100, 100), (300, 300))for x, y, w, h in face:cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)cv.circle(img, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1)ids, confidence = recognizer.predict(gray[y:y + h, x:x + w])if confidence > 80:global warningtimewarningtime += 1if warningtime > 100:# warning()warningtime = 0cv.putText(img, 'unkonw', (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)else:cv.putText(img, str(names[ids - 1]), (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)cv.imshow('result', img)def name():path = 'E:/python_project_sumvac/python_practice/facein/'#names = []imagePaths = [os.path.join(path,f) for f in os.listdir(path)]for imagePath in imagePaths:name = str(os.path.split(imagePath)[1].split('.',2)[1])names.append(name)capture = cv.VideoCapture(0)
name()#摄像头是否正常
if capture.isOpened() is False:print("Camera is not opened!")while capture.isOpened():ret, frame = capture.read()if ret:gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#灰度转换detector = dlib.get_frontal_face_detector()detector_results = detector(gray_frame, 1)new_image = paint_face_rectangle(frame, detector_results)#显示cv.imshow("face detection", new_image)if not ret:breakface_detect_demo(frame)if ord(' ') == cv.waitKey(10):breakcv.destroyAllWindows()
capture.release()
import cv2 as cv
import argparse
import re
import dlib
from PIL import Image
import numpy as np
import os#---------------------------------------------------------------------------------#
# 人脸矩形框
def paint_face_rectangle(image,faces):for face in faces:#遍历该张图片(帧)上 所有 人脸cv.rectangle(image, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 3)return image
#---------------------------------------------------------------------------------#
#实现对应(人脸,名字,id),训练,并生成.yml文件
def rel_ImageAndLabel(path):faceSamples = []#存人脸ids = []#存IDnames = []#imagePaths将包含目录path下所有文件的完整路径imagePaths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]# face_detector = cv.CascadeClassifier("E:/python_project_sumvac/python_practice/haarcascade_frontalface_alt2.xml")detector = dlib.get_frontal_face_detector()for imagePath in imagePaths:# print(imagePath)gray_image = Image.open(imagePath).convert('L')# gray_image = cv.cvtColor(_image, cv.COLOR_BGR2GRAY) # 灰度转换(BGR->GRAY)numpy_image = np.array(gray_image, 'uint8')faces = detector(numpy_image, 1) # 该张灰度图片上的人脸id = int(os.path.split(imagePath)[1].split('.')[0])#提出来那个序号name = str(os.path.split(imagePath)[1].split('.', 2)[1])# print(id)for face in faces:x, y, w, h = face.left(), face.top(), face.width(), face.height()ids.append(id)names.append(name)faceSamples.append(numpy_image[y:y+h, x:x+w])print('ids:', ids)print('names:', names)# print('fs:', faceSamples)recognizer = cv.face.LBPHFaceRecognizer_create()try:recognizer.train(faceSamples, np.array(ids))print("Training completed successfully.")except Exception as e:print(f"Error during training: {e}")# recognizer.train(faceSamples, np.array(ids))recognizer.write("E:/python_project_sumvac/python_practice/trainer1.yml")return recognizer, namesdef main(recognizer,names):num = 3#开摄像头,取视频流(实例化)capture = cv.VideoCapture(0)#摄像头是否正常if capture.isOpened() is False:print("Camera Error!")key=Truewhile capture.isOpened():bol, _image = capture.read()#逐帧读取(_image,该帧图像数据)if bol:gray_image = cv.cvtColor(_image, cv.COLOR_BGR2GRAY)#灰度转换(BGR->GRAY)#人脸检测器(实例化)detector = dlib.get_frontal_face_detector()detector_faces = detector(gray_image, 1)#该张灰度图片上的人脸if key:if detector_faces:for face in detector_faces:x, y, w, h = face.left(), face.top(), face.width(), face.height()cv.rectangle(_image, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)# cv.circle(_image, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1)# print(gray_image.shape)_image_height, _image_width = gray_image.shapeif y >= 0 and y + h <= _image_height and x >= 0 and x + w <= _image_width:ids, confidence = recognizer.predict(gray_image[y:y + h, x:x + w])if confidence > 85:cv.putText(_image, 'unkonw', (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)else:cv.putText(_image, str(names[ids - 1]), (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75,(0, 255, 0), 1)else:print("Error: The face region to be predicted is out of the image boundaries.")continuecv.imshow('face detection', _image)else:new_image = _imagecv.putText(new_image, "No face detected!", (291, 291), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255),3)cv.imshow("face detection", new_image)else:new_image = _image#显示cv.imshow("face detection", new_image)#退出,暂停,继续按键控制if cv.waitKey(1) == 27:#ESCbreakelif cv.waitKey(1) & 0xFF == ord('c'):key = Falseelif cv.waitKey(1) & 0xFF == ord('v'):key = True#人脸录入实现elif cv.waitKey(1) & 0xFF == ord('r'):cv.imwrite("E:/python_project_sumvac/python_practice/facein/"+str(num)+".hml"+".jpg", _image)print("Success to save"+str(num)+".jpg")print("------")num += 1capture.release()cv.destroyAllWindows()if __name__ == '__main__':path = 'E:/python_project_sumvac/python_practice/facein/'recognizer,names = rel_ImageAndLabel(path)main(recognizer,names)