人脸匹配——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()
相关推荐
飞哥数智坊7 小时前
我的“龙虾”罢工了!正好对比下GLM、MiniMax、Kimi 3家谁更香
人工智能
风象南8 小时前
很多人说,AI 让技术平权了,小白也能乱杀老师傅 ?
人工智能·后端
董董灿是个攻城狮9 小时前
大模型连载1:了解 Token
人工智能
花酒锄作田10 小时前
使用 pkgutil 实现动态插件系统
python
RoyLin12 小时前
沉睡三十年的标准:HTTP 402、生成式 UI 与智能体原生软件的时代
人工智能
needn14 小时前
TRAE为什么要发布SOLO版本?
人工智能·ai编程
毅航14 小时前
自然语言处理发展史:从规则、统计到深度学习
人工智能·后端
前端付豪14 小时前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain
ursazoo14 小时前
写了一份 7000字指南,让 AI 帮我消化每天的信息流
人工智能·开源·github
曲幽15 小时前
FastAPI实战:打造本地文生图接口,ollama+diffusers让AI绘画更听话
python·fastapi·web·cors·diffusers·lcm·ollama·dreamshaper8·txt2img