首页 > 其他分享 >人脸特征标注——OpenCV

人脸特征标注——OpenCV

时间:2024-06-19 20:31:22浏览次数:20  
标签:img image cv2 label OpenCV 人脸 tk landmarks 标注

特征标注

导入必要的库

import tkinter as tk: 导入Tkinter库,并将其重命名为tk。
from tkinter import filedialog: 从Tkinter中导入文件对话框功能。
import cv2: 导入OpenCV库。
from PIL import Image, ImageTk: 从PIL库导入Image和ImageTk模块,用于处理图像。
from tkinter import messagebox: 从Tkinter中导入消息框功能,用于显示消息提示框。
import dlib:导入dlib库,这个库用于人脸检测和关键点标注。

import tkinter as tk
from tkinter import filedialog
import cv2
from PIL import Image, ImageTk
from tkinter import messagebox
import dlib

创建窗口

创建了一个Tkinter窗口实例win,设置窗口标题为"特征标注",大小为800x650像素。

win = tk.Tk()
win.title("特征标注")
win.geometry("800x650")

显示原始图片和标注后的图片

创建了两个空的标签控件image_label_originalimage_label_landmarks,用于显示原始图像和带有标注的图像。

mage_label_original = tk.Label(win)
image_label_landmarks = tk.Label(win)

存储用户选择的图片路径

初始化一个变量selected_image_path,用于存储用户选择的图片路径。

selected_image_path = None

字体样式和大小

定义了字体样式my_font,使用Times New Roman字体,大小为20。

my_font = ("Times New Roman", 20)

定义了select_image函数

global selected_image_path: 声明selected_image_path为全局变量,以便在函数内部修改其值。

selected_image_path = filedialog.askopenfilename():
使用文件对话框让用户选择一个图像文件,并将选择的文件路径存储在selected_image_path变量中。

if selected_image_path:: 检查是否成功选择了图像文件。

img = cv2.imread(selected_image_path):
使用OpenCV的imread()函数读取选择的图像文件,并将其存储在img变量中。

img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB):
将BGR格式的图像转换为RGB格式,便于后续处理。

img_pil = Image.fromarray(img_rgb): 将RGB格式的图像数据转换为PIL图像对象。

img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS):
调整图像大小为300x300像素,使用LANCZOS插值方法保持图像质量。

img_tk = ImageTk.PhotoImage(image=img_pil):
将PIL图像对象转换为Tkinter图像对象,用于在GUI中显示。

image_label_original.config(image=img_tk): 在原始图像标签控件上配置显示图像。

image_label_original.image = img_tk: 更新原始图像标签的图像数据,确保图像正确显示在GUI中。

def select_image():
    global selected_image_path
    selected_image_path = filedialog.askopenfilename()

    if selected_image_path:
        img = cv2.imread(selected_image_path)
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img_pil = Image.fromarray(img_rgb)
        img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS)
        img_tk = ImageTk.PhotoImage(image=img_pil)

        image_label_original.config(image=img_tk)
        image_label_original.image = img_tk

定义了annotate_landmarks()函数

if selected_image_path:: 检查是否已选择图像文件。

img = cv2.imread(selected_image_path):
使用OpenCV的imread()函数读取已选择的图像文件。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY): 将图像转换为灰度图像,便于人脸检测。

detector = dlib.get_frontal_face_detector(): 创建一个人脸检测器对象。

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat"):
创建一个人脸关键点预测器对象,加载已经训练好的68个关键点模型。

faces = detector(gray, 1): 使用人脸检测器检测输入图像中的人脸,并将结果存储在faces中。

if len(faces) > 0:: 检查是否检测到了人脸。

landmarks = predictor(gray, faces[0]): 使用关键点预测器获取第一个检测到的人脸的关键点坐标。

for n in range(0, 68):: 遍历68个人脸关键点。

x = landmarks.part(n).x: 获取第n个关键点的x坐标。

y = landmarks.part(n).y: 获取第n个关键点的y坐标。

cv2.circle(img, (x, y), 1, (255, 0, 0), -1): 在图像上绘制一个圆圈表示关键点的位置。

img_rgb_landmarks = cv2.cvtColor(img, cv2.COLOR_BGR2RGB):
将图像从BGR颜色空间转换为RGB颜色空间,这是因为OpenCV读取图像时默认使用BGR颜色通道。

img_pil_landmarks = Image.fromarray(img_rgb_landmarks):
使用PIL的Image.fromarray()函数将OpenCV格式的图像转换为PIL图像对象。

img_pil_landmarks = img_pil_landmarks.resize((300, 300), Image.Resampling.LANCZOS): 调整PIL图像的大小为(300,
300),使用LANCZOS插值方法来保持图像质量。

img_tk_landmarks = ImageTk.PhotoImage(image=img_pil_landmarks):
将PIL图像转换为Tkinter GUI所需的PhotoImage对象。

image_label_landmarks.config(image=img_tk_landmarks):
在image_label_landmarks标签控件上配置显示标注后的图像。

image_label_landmarks.image = img_tk_landmarks:
更新image_label_landmarks标签控件的图像数据,确保图像正确显示在GUI中。

messagebox.showinfo("提示", "未检测到人脸"): 如果未检测到人脸,则在弹出窗口中显示相应提示信息。

messagebox.showinfo("提示", "请先选择一张图片"): 如果未选择图像,则在弹出窗口中显示相应提示信息。

def annotate_landmarks():
    if selected_image_path:
        img = cv2.imread(selected_image_path)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        detector = dlib.get_frontal_face_detector()
        predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
        faces = detector(gray, 1)

        if len(faces) > 0:
            landmarks = predictor(gray, faces[0])
            for n in range(0, 68):
                x = landmarks.part(n).x
                y = landmarks.part(n).y
                cv2.circle(img, (x, y), 1, (255, 0, 0), -1)

            img_rgb_landmarks = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            img_pil_landmarks = Image.fromarray(img_rgb_landmarks)
            img_pil_landmarks = img_pil_landmarks.resize((300, 300), Image.Resampling.LANCZOS)
            img_tk_landmarks = ImageTk.PhotoImage(image=img_pil_landmarks)
            image_label_landmarks.config(image=img_tk_landmarks)
            image_label_landmarks.image = img_tk_landmarks
        else:
            messagebox.showinfo("提示", "未检测到人脸")
    else:
        messagebox.showinfo("提示", "请先选择一张图片")

设置按钮

button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
创建一个名为button_select的按钮,显示文本为"选择图片",应用自定义字体my_font,点击按钮时执行select_image函数,文本颜色为黑色。

button_detect = tk.Button(win, text="标注人脸", font=my_font, command=annotate_landmarks, fg='black')
创建一个名为button_detect的按钮,显示文本为"标注人脸",应用自定义字体my_font,点击按钮时执行annotate_landmarks函数,文本颜色为黑色。

button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_detect = tk.Button(win, text="标注人脸", font=my_font, command=annotate_landmarks, fg='black')

调整图片标签的位置

button_height = 40 : 定义一个名为button_height的变量,值为40,表示按钮的高度为40像素。

button_select.place(x=150, y=50)
:将button_select按钮放置在窗口中x坐标为150像素,y坐标为50像素的位置。

button_detect.place(x=450, y=50)
将button_detect按钮放置在窗口中x坐标为450像素,y坐标为50像素的位置。

# 计算按钮的高度,并据此调整图片标签的位置
button_height = 40  # 假设按钮的高度为40像素
button_select.place(x=150, y=50)
button_detect.place(x=450, y=50)

设置图片位置

image_label_original.place(x=50, y=100)
将原始图片标签image_label_original放置在窗口中x坐标为50像素,y坐标为100像素的位置。

image_label_landmarks.place(x=420, y=100)
将人脸标记图片标签image_label_landmarks放置在窗口中x坐标为420像素,y坐标为100像素的位置。

# 将图片标签放置在按钮下方
image_label_original.place(x=50, y=100)
image_label_landmarks.place(x=420, y=100)

主事件循环

win.mainloop() :进入主事件循环,显示窗口并等待用户操作。

win.mainloop()

运行显示:

在这里插入图片描述

全部代码

import tkinter as tk
from tkinter import filedialog
import cv2
from PIL import Image, ImageTk
from tkinter import messagebox
import dlib

win = tk.Tk()
win.title("特征标注")
win.geometry("800x650")

image_label_original = tk.Label(win)
image_label_landmarks = tk.Label(win)

selected_image_path = None

my_font = ("Times New Roman", 20)

def select_image():
    global selected_image_path
    selected_image_path = filedialog.askopenfilename()

    if selected_image_path:
        img = cv2.imread(selected_image_path)
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img_pil = Image.fromarray(img_rgb)
        img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS)
        img_tk = ImageTk.PhotoImage(image=img_pil)

        image_label_original.config(image=img_tk)
        image_label_original.image = img_tk

def annotate_landmarks():
    if selected_image_path:
        img = cv2.imread(selected_image_path)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        detector = dlib.get_frontal_face_detector()
        predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
        faces = detector(gray, 1)

        if len(faces) > 0:
            landmarks = predictor(gray, faces[0])
            for n in range(0, 68):
                x = landmarks.part(n).x
                y = landmarks.part(n).y
                cv2.circle(img, (x, y), 1, (255, 0, 0), -1)

            img_rgb_landmarks = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            img_pil_landmarks = Image.fromarray(img_rgb_landmarks)
            img_pil_landmarks = img_pil_landmarks.resize((300, 300), Image.Resampling.LANCZOS)
            img_tk_landmarks = ImageTk.PhotoImage(image=img_pil_landmarks)
            image_label_landmarks.config(image=img_tk_landmarks)
            image_label_landmarks.image = img_tk_landmarks
        else:
            messagebox.showinfo("提示", "未检测到人脸")
    else:
        messagebox.showinfo("提示", "请先选择一张图片")

button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_detect = tk.Button(win, text="标注人脸", font=my_font, command=annotate_landmarks, fg='black')

# 计算按钮的高度,并据此调整图片标签的位置
button_height = 40  # 假设按钮的高度为40像素
button_select.place(x=150, y=50)
button_detect.place(x=450, y=50)

# 将图片标签放置在按钮下方
image_label_original.place(x=50, y=100)
image_label_landmarks.place(x=420, y=100)

win.mainloop()

标签:img,image,cv2,label,OpenCV,人脸,tk,landmarks,标注
From: https://blog.csdn.net/2301_76794217/article/details/139781780

相关文章

  • OpenCV一文入门
    OpenCV一文入门官网地址OpenCV当前版本opencv-python4.9.0.80python包地址https://pypi.org/project/opencv-python/OpenCV(OpenSourceComputerVisionLibrary)是一个开源计算机视觉和机器学习软件库,由Intel最初开发,现由WillowGarage和Itseez维护。OpenCV旨......
  • 【YOLOv10改进[注意力]】在YOLOv10中添加坐标注意力CoordAtt + 含全部代码和详细修改
    本文将进行在YOLOv10中添加坐标注意力CoordAtt的实践,助力YOLOv10目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。改进前和改进后的参数对比: 目录一CoordAtt二在YOLOv10中添加注意力CoordAtt的实践1整体修改......
  • 深入解析:如何通过Python脚本将YOLO标注格式转换为COCO格式并进行验证
    深入解析:如何通过Python脚本将YOLO标注格式转换为COCO格式并进行验证随着深度学习和计算机视觉技术的飞速发展,物体检测成为了一个热门的研究领域。在物体检测任务中,YOLO(YouOnlyLookOnce)和COCO(CommonObjectsinContext)是两个非常重要的标注格式。YOLO因其高效的实时物......
  • 深入解析:如何通过Python脚本将LabelMe标注格式转换为YOLO格式并进行验证
    深入解析:如何通过Python脚本将LabelMe标注格式转换为YOLO格式并进行验证在计算机视觉领域,标注格式的转换是一个经常会遇到的问题。不同的标注格式有不同的应用场景和优势,能够灵活地进行转换是非常重要的技能。在这篇文章中,我们将详细介绍如何通过Python脚本将LabelMe标注格......
  • 【python】OpenCV—Segmentation
    文章目录cv2.kmeans牛刀小试cv2.kmeanscv2.kmeans是OpenCV库中用于执行K-Means聚类算法的函数。以下是根据参考文章整理的cv2.kmeans函数的中文文档:一、函数功能cv2.kmeans用于执行K-Means聚类算法,将一组数据点划分到K个簇中,使得簇内的数据点尽可能相......
  • 人脸识别系统---年龄预测
    一、预测年龄1.加载预训练的人脸检测模型face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')2.加载预训练的性别和年龄识别模型gender_net=cv2.dnn.readNetFromCaffe('deploy_gender.prototxt','gender_net.caffemodel')age_net=cv2.......
  • 使用Jupyter(python+opencv)实现特别难的脚本-Day2
    Day2那昨天实现了这个自动挖土,我发现这个yb也是很扯0的东西,所以今天简单优化优化,完了再简单优化一下双手,写个yb吧。首先依旧是库一小堆儿fromPILimportImageimportpyautoguiimportrandomimportpygetwindowasgwimporttime然后那既然是优化那肯定是面向对象......
  • 使用Jupyter(python+opencv)实现很难的脚本-Day1
    由于xx西游没办法自动挖图,于是懒狗的我只能自己写一段脚本来实现挖土自由。首先介绍几个比较重要的库都需要自行install。fromPILimportImage#用于计算图片大小的库importpyautogui#用于抓取目标位置的库importpygetwindowasgw#用于得到窗口大小的库......
  • 使用OpenCV进行实时性别和年龄识别
            在计算机视觉领域,使用深度学习技术进行实时性别和年龄识别是一项具有挑战性和实用性的任务。本文将深入解析一个使用OpenCV和预训练模型实现的实时性别和年龄识别代码,并逐行进行详细的注释解析,帮助读者理解代码的工作原理和实现细节。importcv2importnumpy......
  • OpenCV中绘制多边形的函数:fillPoly与polylines
    一、函数接口介绍1.1fillPoly函数这是个重载函数,有2个实现,具体如下:1、重载1voidfillPoly(Mat&img,constPoint**pts,constint*npts,intncontours,constScalar&color,intlineType......