当前位置:首页 > Python > 正文内容

Smart Image Organizer Assistant 图片数据集重命名、清理,去重错误文件 Python实现

chanra1n3周前 (05-01)Python287

功能主要围绕处理目录中的图片文件:识别、检查、删除非图片文件以及重命名操作。这个程序是一个很好的例子,展示了如何使用Python的os库和Pillow(PIL的升级版本)库来执行文件系统的操作。
首先,介绍一下Python的os库。这个库提供了一系列的功能,用来与操作系统进行交互,比如文件的创建、删除、遍历目录等操作。而Pillow库是Python中一个非常强大的处理图片的库,它支持打开、修改、保存多种格式的图片文件。

1. 批量获取子文件夹

我们的第一个函数 get_subfolders 的工作是获取给定根目录下的所有子文件夹路径。程序通过列表推导式,结合os.listdir() 和 os.path.join() 方法来完成这项工作。这个函数可以帮助我们完成初步的目录结构解析。

2. 删除非图片文件

delete_non_image_files 函数通过遍历给定子目录下的所有文件,并检查文件的扩展名是否属于指定的图片格式集合,如果不是,则使用 os.remove() 方法将它们删除。它使用了Python集合,这是一个高效的数据结构,用于检查元素是否存在于集合中。

3. 检查并记录问题图片

check_pic 函数尝试打开一个图片文件,如果文件不存在、有问题或者是一个"解压缩炸弹",它们会引发异常。在这种情况下,该函数会将问题文件的路径记录到一个文本文件中,并尝试删除这个图片文件。这个功能提高了数据清洗的效率。

4. 图片文件重命名

重命名部分是通过 rename_image_files_in_subfolder 函数来完成的。它首先会遍历给定子目录下的所有文件,并为图片文件生成新的文件名,新文件名包括子文件夹的名称和一个独一无二的索引。在重命名之前,它会调用 check_pic 来确保图片文件没有问题。如果需要,它也会相应地处理文件名冲突。

5. 递归处理所有文件夹

最后,我们有 rename_image_files_in_subfolders 函数,它递归地处理给定路径下的所有文件夹,对每个子文件夹调用 rename_image_files_in_subfolder 方法。
我想强调一下最后的测试部分。当程序作为主模块运行时,会进行实际的操作,删除所有子文件夹中的非图片文件,并递归地重命名所有的图片文件。这确保了脚本在执行时不会有未预期的行为。


程序源码:

import os
from PIL import Image

# 获取指定目录下的所有子文件夹
def get_subfolders(path):
    subfolders = [os.path.join(path, o) for o in os.listdir(path)
                  if os.path.isdir(os.path.join(path, o))]
    return subfolders

# 删除指定目录下的所有子文件夹中不是图片文件的文件
def delete_non_image_files(subfolder):
    allowed_exts = {'.jpg', '.jpeg', '.png', '.bmp', '.jpe'}
    for file_name in os.listdir(subfolder):
        file_path = os.path.join(subfolder, file_name)
        if os.path.isfile(file_path):
            file_ext = os.path.splitext(file_name)[1].lower()
            if file_ext not in allowed_exts:
                os.remove(file_path)  # 如果不是图片格式,就删除这个文件

# 检查图片是否有问题并记录问题图片
def check_pic(path_pic, files_to_delete):
    try:
        img = Image.open(path_pic, 'r')
        img.load()
        return True
    except (FileNotFoundError, OSError, Image.DecompressionBombError):
        f = open('False.txt', 'a+')
        f.write(str(path_pic) + '\n')
        f.close()
        try:
            os.remove(path_pic)
        except PermissionError:
            print('File In Use:'+path_pic)
            files_to_delete.append(path_pic)
        except (FileNotFoundError, OSError) as e:
            print(f"删除文件 {path_pic} 失败: {e}")
        return False

# 重命名指定目录下的所有子文件夹中的图片文件
def rename_image_files_in_subfolder(subfolder, subfolder_name):
    try:
        unique_index = 0
        files_to_delete = []  # 保存需要删除的文件
        for index, file_name in enumerate(os.listdir(subfolder)):
            file_path = os.path.join(subfolder, file_name)
            if os.path.isfile(file_path):
                file_ext = os.path.splitext(file_name)[1].lower()
                if file_ext in ['.jpg', '.jpeg', '.png', '.bmp', '.jpe']:
                    # 在重命名之前检查图片是否有问题
                    if check_pic(file_path, files_to_delete):
                        # 如果图片没问题,进行重命名
                        new_file_name = f"{subfolder_name}_{index+1}{file_ext}"
                        new_file_path = os.path.join(subfolder, new_file_name)
                        while os.path.exists(new_file_path):
                            unique_index += 1
                            new_file_name = f"{subfolder_name}_{index+1}_{unique_index}{file_ext}"
                            new_file_path = os.path.join(subfolder, new_file_name)
                        os.rename(file_path, new_file_path)
    except PermissionError:
        print(f"Error: failed to rename files in subfolder {subfolder}.")

# 递归处理所有文件夹
def rename_image_files_in_subfolders(path):
    for root, dirs, files in os.walk(path):
        for subfolder in dirs:
            subfolder_path = os.path.join(root, subfolder)
            rename_image_files_in_subfolder(subfolder_path, subfolder)

# 测试
if __name__ == '__main__':
    for root, dirs, files in os.walk("."):
        for subfolder in dirs:
            subfolder_path = os.path.join(root, subfolder)
            delete_non_image_files(subfolder_path)
            rename_image_files_in_subfolders(subfolder_path)


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

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:https://world.myfpga.cn/index.php/post/421.html

分享给朋友:

“Smart Image Organizer Assistant 图片数据集重命名、清理,去重错误文件 Python实现” 的相关文章

1.Python基本的使用

1.Python基本的使用

我们打开python或者通过运行python也可以,请复制如下代码,然后按下Enter键,看看会发生什么?print('\n'.join([''.join([('MyFpga'[(x-y) % len('MyFpga'...

for循环

for循环

range()函数range(start,end,step)range()函数返回一个可迭代对象(可理解为一个序列,序列中的数包括start,不包括end)例如range(1,101),返回1-100的序列。range(101),范围0-100的序列。range(1,100,2),返回1,3,5.....

  索引运算符【】

索引运算符【】

选择字符串的子序列语法【start:finish】        start:子序列开始位置的索引值        finish:子序列结束位置的下一个字符的索引值如果不提供start或者finish,默认start为第一个字符,finish为最后一个字符。例如>>>my_str=...

搜索字符串

搜索字符串

常用搜索字符串中子串的方法str.count(substring)      返回str中substring子串出现的无覆盖的次数str.find(s1)                    返回s1在这个字符串的最低下标,如果字符串中不存在s1,则返回-1str.rfind(s1)       ...

列表作为函数参数

列表作为函数参数

列表作为函数参数,函数中可以修改原列表def multiply(values,factor):     for i in range(len(values)):        values[i]*=factor          aList=[1,2,3,4,5]  multiply(aL...

一文快速搞定基本Python

一文快速搞定基本Python

本文适宜有熟练其他高级语言编程基础的同行参阅,或复习用,转载请保留作者信息 Myfpga.cn Chanra1n输入输出#input输入命令,中间的即提示语,左面的a为输入的值存到哪里 a=input("请输入a的值:") #print()可以直接print("He...