当前位置:首页 > python代码 > 正文内容

python代码实现图片人脸识别以及一键覆盖图片~

本文介绍一款基于Python的人脸检测与图像处理工具,支持透明图片覆盖、动态尺寸调整及实时预览功能,适用于图像编辑、隐私保护等场景。

核心功能

  1. 精准人脸检测
    采用OpenCV Haar级联检测算法,自动识别图片中的人脸并标记红色圆圈。支持多人脸同步检测,适应不同角度和尺寸。

  2. 透明图片覆盖
    支持带Alpha通道的PNG文件,通过Alpha混合算法实现无白边覆盖。可自定义覆盖位置,自动适配人脸中心区域。

  3. 动态尺寸调节
    提供0.5x-3.0x实时缩放滑块,覆盖尺寸动态调整。智能处理边界溢出,确保放大后图片居中显示。

  4. 可视化操作界面
    集成Tkinter图形界面,支持一键导入/导出、实时双屏对比预览(原始图与效果图),操作反馈直观。

技术亮点

  • 多线程混合计算:结合OpenCV矩阵运算与PIL图像处理,兼顾效率与精度

  • 自适应显示优化:自动按600px宽度等比缩放预览图,保持画面比例

  • 异常处理机制:自动检测文件缺失、尺寸超限等问题并弹窗提示

操作流程

  1. 导入基础图片 → 2. 滑动调节覆盖尺寸 → 3. 点击"覆盖"应用效果 → 4. 实时预览 → 5. 导出结果图

该工具将人脸检测与图像编辑功能结合,通过简洁的交互设计满足快速打码、创意合成等需求,可广泛应用于自媒体制作、隐私数据处理等领域。代码已开源,支持二次开发扩展。

效果如图

效果图

代码如下

import tkinter as tk
from tkinter import filedialog, ttk, messagebox
import cv2
import numpy as np
from PIL import Image, ImageTk


class FaceDetectionApp:
    def __init__(self, root):
        self.root = root
        self.root.title("人脸检测工具")

        # 初始化变量
        self.original_image = None
        self.processed_image = None
        self.display_width = 600
        self.faces = []
        self.scale_factor = 1.0  # 覆盖缩放比例

        # 创建界面
        self.create_widgets()

    def create_widgets(self):
        # 控制面板
        control_frame = tk.Frame(self.root)
        control_frame.pack(pady=10)

        # 第一行按钮
        btn_row1 = tk.Frame(control_frame)
        btn_row1.pack(pady=5)

        self.btn_load = ttk.Button(btn_row1, text="导入图片", command=self.load_image)
        self.btn_load.pack(side=tk.LEFT, padx=5)

        self.btn_preview = ttk.Button(btn_row1, text="预览", command=self.preview, state=tk.DISABLED)
        self.btn_preview.pack(side=tk.LEFT, padx=5)

        self.btn_overlay = ttk.Button(btn_row1, text="覆盖", command=self.overlay_faces, state=tk.DISABLED)
        self.btn_overlay.pack(side=tk.LEFT, padx=5)

        self.btn_export = ttk.Button(btn_row1, text="导出", command=self.export_image, state=tk.DISABLED)
        self.btn_export.pack(side=tk.LEFT, padx=5)

        # 第二行缩放控制
        scale_frame = tk.Frame(control_frame)
        scale_frame.pack(pady=5)

        ttk.Label(scale_frame, text="覆盖缩放:").pack(side=tk.LEFT)
        self.scale = ttk.Scale(
            scale_frame,
            from_=0.5,
            to=3.0,
            value=1.0,
            command=self.update_scale,
            orient=tk.HORIZONTAL,
            length=200
        )
        self.scale.pack(side=tk.LEFT, padx=5)
        self.scale_label = ttk.Label(scale_frame, text="1.0x")
        self.scale_label.pack(side=tk.LEFT)

        # 图片显示区域
        self.image_frame = tk.Frame(self.root)
        self.image_frame.pack(pady=10)

        self.label_original = tk.Label(self.image_frame)
        self.label_original.pack(side=tk.LEFT, padx=10)

        self.label_processed = tk.Label(self.image_frame)
        self.label_processed.pack(side=tk.LEFT, padx=10)

    def update_scale(self, value):
        """更新缩放比例"""
        self.scale_factor = round(float(value), 1)
        self.scale_label.config(text=f"{self.scale_factor:.1f}x")

    def load_image(self):
        """加载图片"""
        file_path = filedialog.askopenfilename()
        if not file_path:
            return

        try:
            image = cv2.imread(file_path)
            self.original_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            self.processed_image = self.detect_faces(self.original_image.copy())

            # 更新按钮状态
            self.btn_preview.config(state=tk.NORMAL)
            self.btn_export.config(state=tk.NORMAL)
            self.btn_overlay.config(state=tk.NORMAL if len(self.faces) > 0 else tk.DISABLED)

            # 自动预览
            self.preview()
        except Exception as e:
            messagebox.showerror("错误", f"图片加载失败: {str(e)}")

    def detect_faces(self, image):
        """人脸检测"""
        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        self.faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)

        # 绘制检测框
        for (x, y, w, h) in self.faces:
            center = (x + w // 2, y + h // 2)
            radius = int((w + h) // 4)
            cv2.circle(image, center, radius, (255, 0, 0), 2)
        return image

    def overlay_faces(self):
        """覆盖透明图片"""
        try:
            # 加载带透明通道的图片
            overlay_img = cv2.imread("0.png", cv2.IMREAD_UNCHANGED)
            if overlay_img is None:
                raise FileNotFoundError("找不到1.png文件")

            # 分离通道
            overlay_bgra = cv2.cvtColor(overlay_img, cv2.COLOR_BGRA2RGBA)
            overlay_rgb = overlay_bgra[:, :, :3]
            alpha = overlay_bgra[:, :, 3] / 255.0
        except Exception as e:
            messagebox.showerror("错误", f"覆盖图片加载失败: {str(e)}")
            return

        overlaid_image = self.original_image.copy()

        for (x, y, w, h) in self.faces:
            # 计算缩放后尺寸
            scaled_w = int(w * self.scale_factor)
            scaled_h = int(h * self.scale_factor)

            # 计算新位置(居中)
            new_x = max(0, x + (w - scaled_w) // 2)
            new_y = max(0, y + (h - scaled_h) // 2)

            # 调整覆盖图片
            resized_overlay = cv2.resize(overlay_rgb, (scaled_w, scaled_h), interpolation=cv2.INTER_AREA)
            resized_alpha = cv2.resize(alpha, (scaled_w, scaled_h), interpolation=cv2.INTER_AREA)
            resized_alpha = np.expand_dims(resized_alpha, axis=-1)

            # 获取目标区域
            target_area = overlaid_image[new_y:new_y + scaled_h, new_x:new_x + scaled_w]

            # 边界检查
            if target_area.shape[0] == 0 or target_area.shape[1] == 0:
                continue

            # 混合图像
            blended = (resized_overlay * resized_alpha) + (target_area * (1 - resized_alpha))
            overlaid_image[new_y:new_y + scaled_h, new_x:new_x + scaled_w] = blended.astype(np.uint8)

        self.processed_image = overlaid_image
        self.preview()

    def preview(self):
        """预览图片"""
        if self.original_image is None or self.processed_image is None:
            return

        # 调整图片大小
        original = self.resize_image(Image.fromarray(self.original_image))
        processed = self.resize_image(Image.fromarray(self.processed_image))

        # 更新显示
        self.label_original.imgtk = original
        self.label_original.config(image=original)
        self.label_processed.imgtk = processed
        self.label_processed.config(image=processed)

    def resize_image(self, image):
        """调整显示尺寸"""
        w, h = image.size
        ratio = self.display_width / w
        new_size = (self.display_width, int(h * ratio))
        resized = image.resize(new_size, Image.Resampling.LANCZOS)
        return ImageTk.PhotoImage(resized)

    def export_image(self):
        """导出图片"""
        if self.processed_image is None:
            return

        file_path = filedialog.asksaveasfilename(
            defaultextension=".png",
            filetypes=[("PNG文件", "*.png"), ("JPEG文件", "*.jpg"), ("所有文件", "*.*")]
        )

        if file_path:
            try:
                save_image = cv2.cvtColor(self.processed_image, cv2.COLOR_RGB2BGR)
                cv2.imwrite(file_path, save_image)
                messagebox.showinfo("成功", "图片导出成功!")
            except Exception as e:
                messagebox.showerror("错误", f"导出失败: {str(e)}")


if __name__ == "__main__":
    root = tk.Tk()
    app = FaceDetectionApp(root)
    root.mainloop()


扫描二维码推送至手机访问。

微信搜索关注王铁锹公众号或者搜索王秋风。

版权声明:本文由王铁锹个人发布,如需转载请注明出处。

本文链接:https://www.3ban.cn/?id=71

“python代码实现图片人脸识别以及一键覆盖图片~” 的相关文章

python代码实现网页在线flv播放小工具

python代码实现网页在线flv播放小工具

项目介绍项目名称:python代码实现网页在线flv播放小工具简介:FlvPlayer 是一个简单的在线FLV格式视频播放器,它利用Python语言开发,旨在提供一种轻量级的方式让用户能够直接通过网络浏览器播放FLV格式的视频文件。此工具特别适合那些需要快速查看或分享FLV格式视频而不想下载专门的媒...

利用python代码一秒完成指定IP端口扫描

利用python代码一秒完成指定IP端口扫描

引言”学习如何使用Python编写高效的端口扫描脚本,实现对指定IP地址的快速端口扫描。本教程提供详细的代码示例和解释,教你利用Python的强大功能在短短一秒钟内检测出目标主机上所有开放的端口。无论是网络安全测试、服务器管理还是渗透测试准备,这个Python端口扫描器都是不可或缺的工具。获取代码,...

巧用python代码生成网站sitemap地图

巧用python代码生成网站sitemap地图

引言如下:在互联网的世界里,拥有一个清晰、易于导航的网站地图(sitemap)对于网站的成功至关重要。网站地图不仅有助于用户更好地了解网站结构,还能极大地提升搜索引擎优化(SEO)因为它为搜索引擎爬虫提供了发现和索引页面的有效途径。通过提供一个全面且更新及时的网站地图,我们可以确保搜索引擎能够快速找...

利用python导入flv文本链接随机构造一组网页播放

利用python导入flv文本链接随机构造一组网页播放

引言如下通过导入本地文件夹内的文本,引入链接调用python代码开放5000端口进行网页的flv随机播放,这个代码常用于随机测试flv的直播播放设置,亦或者监控等领域....软件规划如下FLV Video Player 是一个基于Web的简易视频播放器应用,使用Python的Flask框架构建。为用...

巧妙调用接口来判断ip地址

巧用一个使用 Python 发起 HTTPS 请求的例子,旨在获取指定 IP 地址的相关信息!请勿用于生产测试环境!import urllib.request import ssl # 定义请求的URL、方法、应用代码(API密钥)以及查询参数 host&nb...

Python脚本实现自动检测并重命名非正常图片文件

Python脚本实现自动检测并重命名非正常图片文件

概述在日常的文件管理和数据处理中,我们可能会遇到一些文件名虽然以特定扩展名结尾,但实际内容并不符合该格式的情况。例如,某些文件可能被错误地标记为 .jpg 文件,但实际上它们可能是其他类型的文件,如视频文件。这种情况下,如果我们依赖文件扩展名来处理文件,就可能导致程序出现错误或无法正确处理文件。本文...