You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python人脸灰度裁剪脚本仅生成单个文件,存在覆盖问题求助

人脸裁剪脚本文件被覆盖的修复方案

你的脚本遍历输入目录所有图片时,后续生成的文件会覆盖之前的,核心问题确实出在output_filename的命名逻辑上:当前文件名只包含人脸的序号i+1,每处理一张新图片,序号都会从1重新开始,导致不同图片里的第一张人脸都会生成Cropped_Me_Grey_1.jpg,直接覆盖之前的文件。

修复思路

给输出文件名加上原图片的名称前缀,这样不同图片生成的裁剪文件就不会重名,同时保留人脸序号区分同一张图片里的多个人脸。

具体修改步骤

  1. 提取原文件的名称(去掉后缀):用os.path.splitext(filename)[0]获取原文件名的主体部分
  2. 修改output_filename的格式,把原文件名前缀加进去:
    output_filename = f'{original_name}_Cropped_Grey_{i+1}.jpg'
    

修改后的完整代码

import cv2
import os

input_directory = r'C:\Users\Me\Desktop\Project\Python Files\TrainingPictures\Uncropped_Me'
cascades_directory = r'C:\Users\Me\Desktop\Project\Python Files\haarcascade_frontalface_default.xml'
output_directory = r'C:\Users\Me\Desktop\Project\Python Files\TrainingPictures\Cropped_Me_Grey'

if not os.path.exists(output_directory):
    os.makedirs(output_directory)

# 提前加载 Haar 级联分类器,避免每次循环重复加载
haar_cascades = cv2.CascadeClassifier(cascades_directory)

for filename in os.listdir(input_directory):
    input_path = os.path.join(input_directory, filename)
    # 跳过非图片文件(可选,避免读取报错)
    if not filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        continue
    img = cv2.imread(input_path)
    if img is None:
        print(f"无法读取图片: {filename}")
        continue
    img_grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 检测人脸
    faces = haar_cascades.detectMultiScale(img_grey, scaleFactor=1.3, minNeighbors=4)
    print(f'Detected {len(faces)} faces in {filename}')

    # 提取原文件名(去掉后缀)
    original_name = os.path.splitext(filename)[0]

    # 裁剪并保存每个人脸
    for i,(x,y,w,h) in enumerate(faces):
        # 灰度图无法显示彩色矩形,训练也不需要,注释掉绘图代码
        # cv2.rectangle(img_grey, pt1=(x,y), pt2=((x+w),(y+h)), color=(0,255,0), thickness=2)
        faces_cropped = img_grey[y: y+h , x: x+w]

        output_filename = f'{original_name}_Cropped_Grey_{i+1}.jpg'
        output_path = os.path.join(output_directory, output_filename)
        cv2.imwrite(output_path, faces_cropped)

    # 打印当前图片的检测结果
    if len(faces) > 0:
        print(f"最后一个裁剪人脸的尺寸: {faces_cropped.shape}")
        print(f"检测到的人脸坐标: {faces}")

cv2.destroyAllWindows()

额外优化点

  • 提前加载Haar级联分类器,避免每次循环重复加载,提升运行效率
  • 增加非图片文件判断和读取失败处理,避免脚本中途报错
  • 移除灰度图上的彩色矩形绘制(灰度图单通道无法显示彩色,且训练无需带框图像)
  • 将打印语句移至图片循环内,对应每张图片的检测结果,避免仅输出最后一张的信息

内容的提问来源于stack exchange,提问作者Idraq Siddiqui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:31:03