人脸匹配——OpenCV

人脸匹配

导入所需的库

cv2:OpenCV库,用于图像处理。
dlib:一个机器学习库,用于人脸检测和特征点预测。
numpy:用于数值计算的库。
PILImageTk:用于处理图像和创建Tkinter兼容的图像对象。
filedialog:Tkinter的一个模块,用于打开文件对话框。
TkLabelButtonCanvas:Tkinter库的组件,用于创建GUI。

python 复制代码
import cv2
import dlib
import numpy as np
from PIL import Image, ImageTk
from tkinter import filedialog
from tkinter import Tk, Label, Button, Canvas

加载dlib的人脸识别模型和面部检测器

使用dlib.get_frontal_face_detector()加载面部检测器。

使用dlib.shape_predictor()加载面部特征点预测模型。

使用dlib.face_recognition_model_v1()加载人脸识别模型。

python 复制代码
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

读取图片并转换为灰度图

读取图片并转换为灰度图。

使用面部检测器检测图像中的面部。

如果检测到多张或没有脸,则抛出异常。

提取面部特征点并计算人脸编码。

python 复制代码
def get_face_encoding(image_path):
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector(gray)
    if len(faces) != 1:
        raise ValueError("图片中检测到多张或没有脸")
    face = faces[0]
    shape = predictor(gray, face)
    face_encoding = np.array(face_rec.compute_face_descriptor(img, shape))
    return face_encoding

比较两张人脸

比较两个人脸编码。

计算两个编码之间的欧氏距离。

如果距离小于0.6,则认为它们是同一个人脸。

python 复制代码
def compare_faces(face1, face2):
    distance = np.linalg.norm(face1 - face2)
    if distance < 0.6:
        return "相同人脸"
    else:
        return "不同人脸"

选择图片并显示结果

定义select_image1、select_image2和select_image3函数。

打开文件对话框让用户选择图片。

将选择的图片显示在相应的画布上。

python 复制代码
def select_image1():
    global image1_path, image1
    image1_path = filedialog.askopenfilename()
    image1 = Image.open(image1_path)
    image1 = image1.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo1 = ImageTk.PhotoImage(image1)
    canvas1.create_image(0, 0, anchor='nw', image=photo1)
    canvas1.image = photo1


def select_image2():
    global image2_path, image2
    image2_path = filedialog.askopenfilename()
    image2 = Image.open(image2_path)
    image2 = image2.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo2 = ImageTk.PhotoImage(image2)
    canvas2.create_image(0, 0, anchor='nw', image=photo2)
    canvas2.image = photo2


def select_image3():
    global image3_path, image3
    image3_path = filedialog.askopenfilename()
    image3 = Image.open(image3_path)
    image3 = image3.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo3 = ImageTk.PhotoImage(image3)
    canvas3.create_image(0, 0, anchor='nw', image=photo3)
    canvas3.image = photo3

比较图片

定义compare_images1和compare_images2函数:

获取两个人脸编码并进行对比。

显示对比结果。

python 复制代码
def compare_images1():
    try:
        face1 = get_face_encoding(image1_path)
        face2 = get_face_encoding(image2_path)
        result1 = compare_faces(face1, face2)
        result_label1.config(text=result1)
    except Exception as e:
        result_label1.config(text="发生错误: " + str(e))

def compare_images2():
    try:
        face2 = get_face_encoding(image2_path)
        face3 = get_face_encoding(image3_path)
        result2 = compare_faces(face2, face3)
        result_label2.config(text=result2)
    except Exception as e:
        result_label2.config(text="发生错误: " + str(e))

创建GUI界面

设置窗口标题和大小。

创建画布来显示图片。

创建标签来显示对比结果。

创建按钮让用户选择图片和进行对比。

python 复制代码
# 创建GUI
root = Tk()
root.title("人脸对比")
root.geometry("1000x620")

# 创建画布来显示图片
canvas1 = Canvas(root, width=300, height=300, bg='white')
canvas1.pack(side='left', padx=10, pady=10)
canvas2 = Canvas(root, width=300, height=300, bg='white')
canvas2.pack(side='left', padx=10, pady=10)
canvas3 = Canvas(root, width=300, height=300, bg='white')
canvas3.pack(side='left', padx=10, pady=10)

# 创建标签来显示结果
result_label1 = Label(root, text="")
result_label1.place(x=300, y=120)
result_label2 = Label(root, text="")
result_label2.place(x=640, y=120)

# 创建按钮来选择图片
button1 = Button(root, text="选择第一张图片", command=select_image1)
button1.place(x=100, y=50)
button2 = Button(root, text="选择第二张图片", command=select_image2)
button2.place(x=450, y=50)
button3 = Button(root, text="选择第三张图片", command=select_image3)
button3.place(x=800, y=50)

# 创建按钮来对比图片
compare_button1 = Button(root, text="对比图像12", command=compare_images1)
compare_button1.place(x=300, y=80)
compare_button2 = Button(root, text="对比图像23", command=compare_images2)
compare_button2.place(x=640, y=80)

运行GUI主循环

python 复制代码
root.mainloop()

运行显示

全部代码

python 复制代码
import cv2
import dlib
import numpy as np
from PIL import Image, ImageTk
from tkinter import filedialog
from tkinter import Tk, Label, Button, Canvas

# 加载dlib的人脸识别模型和面部检测器
#使用dlib.get_frontal_face_detector()加载面部检测器,
# 使用dlib.shape_predictor()加载面部特征点预测模型,
# 使用dlib.face_recognition_model_v1()加载人脸识别模型
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

# 读取图片并转换为灰度图
def get_face_encoding(image_path):
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector(gray)
    if len(faces) != 1:
        raise ValueError("图片中检测到多张或没有脸")
    face = faces[0]
    shape = predictor(gray, face)
    face_encoding = np.array(face_rec.compute_face_descriptor(img, shape))
    return face_encoding

# 比较两张人脸
def compare_faces(face1, face2):
    distance = np.linalg.norm(face1 - face2)
    if distance < 0.6:
        return "相同人脸"
    else:
        return "不同人脸"

# 选择图片并显示结果
def select_image1():
    global image1_path, image1
    image1_path = filedialog.askopenfilename()
    image1 = Image.open(image1_path)
    image1 = image1.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo1 = ImageTk.PhotoImage(image1)
    canvas1.create_image(0, 0, anchor='nw', image=photo1)
    canvas1.image = photo1


def select_image2():
    global image2_path, image2
    image2_path = filedialog.askopenfilename()
    image2 = Image.open(image2_path)
    image2 = image2.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo2 = ImageTk.PhotoImage(image2)
    canvas2.create_image(0, 0, anchor='nw', image=photo2)
    canvas2.image = photo2


def select_image3():
    global image3_path, image3
    image3_path = filedialog.askopenfilename()
    image3 = Image.open(image3_path)
    image3 = image3.resize((300, 300), Image.LANCZOS)  # 使用Image.LANCZOS替换ANTIALIAS
    photo3 = ImageTk.PhotoImage(image3)
    canvas3.create_image(0, 0, anchor='nw', image=photo3)
    canvas3.image = photo3


def compare_images1():
    try:
        face1 = get_face_encoding(image1_path)
        face2 = get_face_encoding(image2_path)
        result1 = compare_faces(face1, face2)
        result_label1.config(text=result1)
    except Exception as e:
        result_label1.config(text="发生错误: " + str(e))

def compare_images2():
    try:
        face2 = get_face_encoding(image2_path)
        face3 = get_face_encoding(image3_path)
        result2 = compare_faces(face2, face3)
        result_label2.config(text=result2)
    except Exception as e:
        result_label2.config(text="发生错误: " + str(e))

# 创建GUI
root = Tk()
root.title("人脸对比")
root.geometry("1000x620")

# 创建画布来显示图片
canvas1 = Canvas(root, width=300, height=300, bg='white')
canvas1.pack(side='left', padx=10, pady=10)
canvas2 = Canvas(root, width=300, height=300, bg='white')
canvas2.pack(side='left', padx=10, pady=10)
canvas3 = Canvas(root, width=300, height=300, bg='white')
canvas3.pack(side='left', padx=10, pady=10)

# 创建标签来显示结果
result_label1 = Label(root, text="")
result_label1.place(x=300, y=120)
result_label2 = Label(root, text="")
result_label2.place(x=640, y=120)

# 创建按钮来选择图片
button1 = Button(root, text="选择第一张图片", command=select_image1)
button1.place(x=100, y=50)
button2 = Button(root, text="选择第二张图片", command=select_image2)
button2.place(x=450, y=50)
button3 = Button(root, text="选择第三张图片", command=select_image3)
button3.place(x=800, y=50)

# 创建按钮来对比图片
compare_button1 = Button(root, text="对比图像12", command=compare_images1)
compare_button1.place(x=300, y=80)
compare_button2 = Button(root, text="对比图像23", command=compare_images2)
compare_button2.place(x=640, y=80)

root.mainloop()
相关推荐
云烟成雨TD2 分钟前
Spring AI 1.x 系列【15】AI Agent 基石:Tool Calling 标准与 Spring AI 集成
java·人工智能·spring
科学创新前沿4 分钟前
逆向设计新范式:深度学习驱动的声学超材料智能优化!
人工智能·python·深度学习·声学·逆向设计·声学超材料
铮铭5 分钟前
上海交大 RoboClaw VS EmbodiedAgentsSys 两个框架对比分析
人工智能·机器人·ai编程·具身智能·vla
rgb2gray6 分钟前
论文详解:基于POI数据的城市功能区动态演化分析——以北京为例
人工智能·算法·机器学习·回归·gwr
不懂网络的坤坤7 分钟前
2026中关村论坛AI主题日深度解读
人工智能
产业家8 分钟前
“龙虾思想”背后:把AI战火正式推向软件层
人工智能
新缸中之脑8 分钟前
将Autoresearch转化为通用技能
人工智能
Yao.Li16 分钟前
LINEMOD 训练流程与实施细节
人工智能·深度学习·机器学习
AORUO奥偌18 分钟前
奥偌医用气体系统——全链条一站式服务商 | 中心供氧/负压吸引/压缩空气源头厂家
人工智能·数字化·智慧医院·医用气体系统·中心供氧系统工程
Sagittarius_A*21 分钟前
传统图像分割:阈值 / 区域生长 / 分水岭 / 图割全解析【计算机视觉】
图像处理·人工智能·python·opencv·计算机视觉·图像分割