提取人脸——OpenCV

news2024/12/26 23:29:57

提取人脸

    • 导入所需的库
    • 创建窗口
    • 显示原始图片
    • 显示检测到的人脸
    • 创建全局变量
    • 定义字体对象
    • 定义一个函数select_image
    • 定义了extract_faces函数
    • 设置按钮
    • 运行GUI主循环
    • 运行显示

导入所需的库

tkinter:用于创建图形用户界面。 filedialog:用于打开文件对话框。
cv2:OpenCV库,用于图像处理和计算机视觉。 PIL(Python Imaging Library)和ImageTk:用于处理和显示图像。 messagebox:用于显示消息框。
subprocess:用于执行系统命令。

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

创建窗口

创建一个Tkinter窗口对象win,并设置窗口的标题和大小。

win = tk.Tk()
win.title("人脸提取")
win.geometry("800x650")

显示原始图片

创建一个标签(Label)对象image_label_original,用于显示原始图片。然后使用pack()方法将标签放置在窗口的左侧,并设置一些填充和边距。

image_label_original = tk.Label(win)
image_label_original.pack(side=tk.LEFT, padx=10, pady=80)

显示检测到的人脸

创建另一个标签(Label)对象image_label_detected,用于显示检测到的人脸。同样使用pack()方法将标签放置在窗口的左侧,并设置一些填充和边距。

image_label_detected = tk.Label(win)
image_label_detected.pack(side=tk.LEFT, padx=10, pady=80)

创建全局变量

创建一个全局变量selected_image_path,用于存储选择的图片路径。

selected_image_path = None

定义字体对象

定义一个字体对象my_font,用于按钮和其他文本控件。

my_font = ("Times New Roman", 20)

定义一个函数select_image

定义一个函数select_image,当按钮被点击时,它会打开文件选择对话框,让用户选择图片。然后使用OpenCV加载图片,转换颜色空间,使用PIL调整图片大小,并使用Tkinter显示图片。

def select_image(): - 定义一个函数,当按钮被点击时,会执行这个函数。 global selected_image_path :声明selected_image_path是一个全局变量,这样在函数内部可以修改它的值。
selected_image_path = filedialog.askopenfilename()
打开文件选择对话框,让用户选择一个文件。askopenfilename():函数返回用户选择的文件路径。 img = cv2.imread(selected_image_path) : 使用OpenCV的imread函数从选择的文件路径中读取图片。
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
:将图片从BGR颜色空间转换到RGB颜色空间。 img_pil = Image.fromarray(img_rgb)
:将NumPy数组转换为PIL图像。 img_pil = img_pil.resize((300, 300), Image.Resampling.LANCZOS) : 使用LANCZOS插值方法将图像大小调整为300x300像素。 img_tk = ImageTk.PhotoImage(image=img_pil) :将PIL图像转换为Tkinter可以显示的PhotoImage对象。
image_label_original.config(image=img_tk)
配置标签image_label_original以显示新加载的图片。 image_label_original.image = img_tk : 设置标签的image属性,以便在Tkinter中显示图像。

def select_image():
    global selected_image_path
    # 打开文件选择对话框
    selected_image_path = filedialog.askopenfilename()

    # 使用OpenCV加载图片
    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)  # 调整图片大小为300x300
    img_tk = ImageTk.PhotoImage(image=img_pil)

    # 显示原始图片
    image_label_original.config(image=img_tk)
    image_label_original.image = img_tk

定义了extract_faces函数

if selected_image_path: - 检查selected_image_path是否已经被设置,即是否已经选择了图片。
img = cv2.imread(selected_image_path) : 使用OpenCV的imread函数加载选择的图片。
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) :将图片从BGR颜色空间转换到灰度颜色空间。
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') :加载预训练的人脸检测Haar级联分类器。
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
:使用加载的分类器在灰度图像中检测多个人脸,并返回它们的坐标和大小。
print(f"Detected faces: {len(faces)}") : 打印检测到的人脸数量。
if len(faces) > 0: 检查是否检测到人脸。
(x, y, w, h) = faces[0] : 获取第一个检测到的人脸的坐标和大小。
face_img = img[y:y+h, x:x+w]
:从原始图片中裁剪出人脸区域。
face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
: 将裁剪的人脸图像从BGR颜色空间转换到RGB颜色空间。
face_img = Image.fromarray(face_img)
将裁剪后的图像从NumPy数组转换为PIL图像。 face_img = face_img.resize((300, 300), Image.Resampling.LANCZOS) : 使用LANCZOS插值方法将图像大小调整为300x300像素。
face_img = ImageTk.PhotoImage(face_img) : 将PIL图像转换为Tkinter可以显示的PhotoImage对象。 image_label_detected.config(image=face_img)
配置标签image_label_detected以显示新的人脸图像。
image_label_detected.image = face_img : 设置标签的image属性,以便在Tkinter中显示图像。 else: - 如果未检测到人脸,执行以下代码。
messagebox.showinfo("信息", "没有检测到人脸") : 显示一个消息框,告知用户没有检测到人脸。 else:
如果selected_image_path未设置,执行以下代码。 messagebox.showwarning("警告", "请先选择一张图片") :显示一个警告消息框,告知用户需要先选择一张图片。

def extract_faces():
    if selected_image_path:
        # 使用OpenCV的人脸检测
        img = cv2.imread(selected_image_path)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

        # 打印检测到的人脸数量
        print(f"Detected faces: {len(faces)}")

        # 如果检测到人脸,裁剪并显示
        if len(faces) > 0:
            (x, y, w, h) = faces[0]  # 获取第一个检测到的人脸
            print(f"Face coordinates: x={x}, y={y}, w={w}, h={h}")
            face_img = img[y:y+h, x:x+w]  # 裁剪人脸区域

            # 转换为PIL图像并调整大小
            face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
            face_img = Image.fromarray(face_img)
            face_img = face_img.resize((300, 300), Image.Resampling.LANCZOS)  # 调整人脸图片大小为300x300
            face_img = ImageTk.PhotoImage(face_img)
            image_label_detected.config(image=face_img)
            image_label_detected.image = face_img
        else:
            messagebox.showinfo("信息", "没有检测到人脸")
    else:
        messagebox.showwarning("警告", "请先选择一张图片")

设置按钮

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

button_select.place(x=150, y=12):
将button_select按钮放置在窗口win的特定位置,横坐标为150,纵坐标为12。

button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='black'):
创建另一个名为button_extract的按钮,显示文本为"提取人脸",字体样式为my_font,按钮点击时执行extract_faces函数,文本颜色为黑色。

button_extract.place(x=450, y=12):
将button_extract按钮放置在窗口win的特定位置,横坐标为450,纵坐标为12。

创建选择图片和识别人脸的按钮
button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_select.place(x=150, y=12)

button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='black')
button_extract.place(x=450, y=12)

运行GUI主循环

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

win.mainloop()

运行显示

在这里插入图片描述
全部代码:

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

win = tk.Tk()
win.title("人脸提取")
win.geometry("800x650")

image_label_original = tk.Label(win)
image_label_original.pack(side=tk.LEFT, padx=10, pady=80)

image_label_detected = tk.Label(win)
image_label_detected.pack(side=tk.LEFT, padx=10, pady=80)

selected_image_path = None

my_font = ("Times New Roman", 20)

def select_image():
    global selected_image_path
    # 打开文件选择对话框
    selected_image_path = filedialog.askopenfilename()

    # 使用OpenCV加载图片
    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)  # 调整图片大小为300x300
    img_tk = ImageTk.PhotoImage(image=img_pil)

    # 显示原始图片
    image_label_original.config(image=img_tk)
    image_label_original.image = img_tk

# 人脸检测函数
def extract_faces():
    if selected_image_path:
        # 使用OpenCV的人脸检测
        img = cv2.imread(selected_image_path)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

        # 打印检测到的人脸数量
        print(f"Detected faces: {len(faces)}")

        # 如果检测到人脸,裁剪并显示
        if len(faces) > 0:
            (x, y, w, h) = faces[0]  # 获取第一个检测到的人脸
            print(f"Face coordinates: x={x}, y={y}, w={w}, h={h}")
            face_img = img[y:y+h, x:x+w]  # 裁剪人脸区域

            # 转换为PIL图像并调整大小
            face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)
            face_img = Image.fromarray(face_img)
            face_img = face_img.resize((300, 300), Image.Resampling.LANCZOS)  # 调整人脸图片大小为300x300
            face_img = ImageTk.PhotoImage(face_img)
            image_label_detected.config(image=face_img)
            image_label_detected.image = face_img
        else:
            messagebox.showinfo("信息", "没有检测到人脸")
    else:
        messagebox.showwarning("警告", "请先选择一张图片")

# 创建选择图片和识别人脸的按钮
button_select = tk.Button(win, text="选择图片", font=my_font, command=select_image, fg='black')
button_select.place(x=150, y=12)

button_extract = tk.Button(win, text="提取人脸", font=my_font, command=extract_faces, fg='black')
button_extract.place(x=450, y=12)

win.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1837434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DDP算法之线性化和二次近似(Linearization and Quadratic Approximation)

DDP算法线性化和二次近似 在DDP算法中,第三步是线性化系统动力学方程和二次近似代价函数。这一步是关键,它使得DDP能够递归地处理非线性最优控制问题。通过线性化和二次近似,我们将复杂的非线性问题转换为一系列简单的线性二次问题,逐步逼近最优解。通过这些线性化和二次近…

STM32--IAP程序升级实验

1. STM32程序升级方法 1.1 ST-link / J-link下载 将编译生成的hex文件使用ST-Link/J-Link工具直接下载进 Flash 即可。Keil中点击下载也能一键下载。下载后的代码会存放在Flash的起始地址0x0800 0000处。 简单补充一句,bin文件和hex文件的区别: bin文…

易备防勒索备份方案与成功案例

随着信息化的发展,数据安全的重要性愈加突出。据 Hiscox 全球网络安全统计,在勒索软件攻击事件当中,64%以上的用户是中小企业。因此,制定完善的灾备策略,是抵御网络威胁的终极方案。而在诸多数据备份方案中&#xff0c…

Opencv高级图像处理

文章目录 Opencv高级图像处理图像坐标二值化滤波高斯滤波中值滤波 开闭运算检测霍夫圆检测边缘检测Canny边缘检测findContours区别傅里叶变换-高/低通滤波 直线检测 相机标定视频处理视频格式 模板摄像头处理(带参调节)单图片处理(带参调节&a…

defer+recover机制处理错误

问题:多个协程工作,其中一个协程出现panic,导致程序崩溃 解决办法:利用deferrecover捕获panic进行处理,即使协程出现错误,主线程仍然不受影响可以继续执行 package mainimport ("fmt""tim…

Win32编程:第一个窗口程序(Part.1)

Win32系统编程是指在Windows操作系统上使用Win32 API进行软件开发的过程;Win32 API是Windows操作系统提供的应用程序接口,允许程序与操作系统进行交互,实现各种功能。 以下是Win32系统编程的基本概念和步骤: 环境准备 开发工具&…

Unity URP 仿原神角色渲染过程记录

想学一下NPR渲染,话不多说,先搞一只芙再说,边做边学 一、资源整理 终于是把东西全都集齐了 1、纹理设置 首先要把将Diffuse和Lightmap的压缩改成"无"或"高质量"。 法线贴图的纹理类型改成"法线贴图"。 除颜…

Go语言RPC开发深度指南:net/rpc包的实战技巧和优化策略

Go语言RPC开发深度指南:net/rpc包的实战技巧和优化策略 概览理解net/rpc的核心概念RPC的基本原理net/rpc的工作模式关键特性 快速开始准备RPC服务和客户端的基础环境构建一个基础的RPC服务端构建一个基础的RPC客户端 开发一个实际的RPC服务设计服务接口实现服务客户…

pdf怎么压缩到2m以内或5m以内的方法

PDF作为一种广泛使用的文档格式,已经成为我们工作和生活中不可或缺的一部分。然而,有时候PDF文件内存会比较大,给我们的存储和传输带来了很大的不便。因此,学会压缩 PDF 文件是非常必要的。 打开"轻云处理pdf官网"&…

隐藏element的DateTimePicker组件自带的清空按钮

管理台页面使用到el-date-picker,type datetimerange 但是组件自带了清空按钮,实际上这个控件业务上代表开始时间和结束时间是一个必填选项,所有想要把清空按钮隐藏掉。 查看了文档https://element.eleme.io/#/zh-CN/component/datetime-p…

react 自定义鼠标右键点击事件

功能:鼠标右键点击节点时,出现“复制”功能,点击其他部位,隐藏“复制”;鼠标右键事件的文案,始终在鼠标点击位置的右下方;点击复制,提示复制成功 效果图: 代码&#xff1…

win11 之下载安装 allure

1. 下载 https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.25.0/allure-commandline-2.25.0.zip 2. 配置系统变量 path 下添加解压后的bin目录 3. 验证是否安装成功 输入 allure

git使用摘樱桃的方式,实现特定需求进行提交合并

文章目录 先checkOut到主要的分支(需求提交到这) 然后双击点别的需求分支,对提交内容选定 进行摘樱桃操作 然后双击回到主要分支,会发现那2个提交内容代码已经在主要分支的本地里,选中其 右键选择Squash Commits进行合并 标注自己的需求标题提交名更改后, 最后进行push推送到…

利用AI云防护实现高效负载均衡

在当今高度数字化的世界里,保证网站和应用的高可用性和响应速度对企业的业务连续性和用户体验至关重要。传统的负载均衡技术虽然能够分发流量,但在面对突发流量、DDoS攻击或资源动态调整时往往力不从心。本文将探讨如何借助AI云防护服务,不仅…

问题解决:局域网下多台电脑实现共享打印机

看了很多篇解决措施,都没有解决,自己鼓弄了好久,终于解决了,如下步骤所示,实测好用。 首先先保证本电脑已打开网络共享 其次关闭防火墙(有时会出现奇怪问题,最好关闭) 接着访问IP…

Chatgpt教我打游戏攻略

宝可梦朱 我在玩宝可梦朱的时候,我的同行队伍里有黏美儿,等级为65,遇到了下雨天但是没有进化,为什么呢? 黏美儿(Goomy)要进化为黏美龙(Goodra),需要满足以下…

【贪吃蛇】C语言教程

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

音频处理软件adobe audition使用教程

教程1笔记 基本操作 点击文件-》新建-》多轨会话: 编辑-》首选项,设置自动保存时间: 导入素材,文件-》导入素材,或者直接拖动进来文件! 导出多轨混音: 更改为需要导出的格式wav,mp3等格式&am…

Netty中Reactor线程的运行逻辑

Netty中的Reactor线程主要干三件事情: 轮询注册在Reactor上的所有Channel感兴趣的IO就绪事件。 处理Channel上的IO就绪事件。 执行Netty中的异步任务。 正是这三个部分组成了Reactor的运行框架,那么我们现在来看下这个运行框架具体是怎么运转的~~ 这…

Windows 命令行界面常用命令

Windows 命令行界面常用命令 首先我们通过WIN R,输入cmd进入命令行界面。 1. dir - 列出当前目录下的文件和子目录 用法: dir2. cd - 切换目录 用法: cd 目录路径返回上一级目录: C:\Users\YourUsername\Documents> cd …