图片数据清洗

一、清理非图片数据

        分析数据集信息。遍历data目录中所有图片,对于每个图片,通过 is_image() 函数来确定是否为图片文件,将不是的直接删除,统计图片文件的数量。通过尝试打开每个图片文件,使用 Image.open()img.load() 方法来检测文件是否完好,如果文件无法打开则将其视为破损图片,最终返回数据集图片数量和破损图片的数量。

# 定义函数,获取指定目录下的数据集信息
def get_data_info(dir_path):
    size = 0  # 初始化数据集总大小变量
    number = 0  # 初始化图片数量变量
    bad_number = 0  # 初始化破损图片数量变量

    # 遍历指定目录及其子目录下的所有文件和文件夹
    for root, dirs, files in os.walk(dir_path):
        # 筛选出当前目录中的所有图片文件
        img_files = [file_name for file_name in files if is_image(file_name)]

        # 计算当前目录中所有图片文件的总大小
        files_size = sum([os.path.getsize(os.path.join(root, file_name)) for file_name in img_files])

        # 统计当前目录中的图片文件数量
        files_number = len(img_files)

        # 累加总大小和图片数量
        size += files_size
        number += files_number

        # 检查每个图片文件的完整性
        for file in img_files:
            try:
                # 尝试打开并加载图片数据
                img = Image.open(os.path.join(root, file))
                img.load()
            except OSError:
                # 如果捕获到 OSError 异常,则增加破损图片数量计数
                bad_number += 1

    # 返回结果:图片数量、破损图片数量
    return size / 1024 / 1024, number, bad_number

二、去除损坏图片

        检测并移除损坏图片文件。通过递归所有的图片文件,对每个图片文件,通过尝试打开并加载图像数据的方式,使用 PIL.Image.open().load() 方法来验证文件是否完好。如果打开过程中出现异常,则将该图片文件移动到损坏文件新目录中,同时记录损坏图片的数量。最终返回筛选出的损坏图片数量。

# 定义函数,用于去除已损坏的图片文件
def filter_bad(dir_path):
    # 创建用于存放筛选后图片的目录
    filter_dir = os.path.join(os.path.dirname(dir_path), 'filter_bad')
    # 如果目录不存在,则创建它
    if not os.path.exists(filter_dir):
        os.mkdir(filter_dir)
    # 初始化筛选计数器
    filter_number = 0
    # 遍历目录及其子目录下的所有文件和文件夹
    for root, dirs, files in os.walk(dir_path):
        # 筛选出当前目录下的所有图片文件
        img_files = [file_name for file_name in files if is_image(file_name)]
        # 遍历每个图片文件
        for file in img_files:
            # 获取图片文件的完整路径
            file_path = os.path.join(root, file)
            try:
                # 尝试打开并加载图片文件,用于检测其是否损坏
                Image.open(file_path).load()
            except OSError:
                # 如果损坏,则将其移动到损坏目录中
                shutil.move(file_path, filter_dir)
                # 增加筛选计数器
                filter_number += 1
    # 返回被筛选出的损坏图片数量
    return filter_number

三、去除过于模糊图片

        从数据集中识别和移除过于模糊的图片文件。首先递归遍历目录树,筛选出所有的图片文件。对于每个图片文件,使用 OpenCV 的 imdecode 函数读取图片数据,并计算图片的拉普拉斯变换方差,根据拉普拉斯变换方差判断图片模糊性,模糊图片被移动到模糊图片的新目录中,并且记录移除的模糊图片数量。

# 去除过于模糊图片
def filter_blurred(dir_path):
    # 创建一个目录用于存放被移除的模糊图片
    filter_dir = os.path.join(os.path.dirname(dir_path), 'filter_blurred')
    if not os.path.exists(filter_dir):
        os.mkdir(filter_dir)
    
    # 初始化计数器,用于统计被移除的模糊图片数量
    filter_number = 0
    
    # 使用os.walk递归遍历指定目录dir_path及其子目录
    for root, dirs, files in os.walk(dir_path):
        # 获取当前目录下的所有图片文件名
        img_files = [file_name for file_name in files if is_image(file_name)]
        
        # 遍历每个图片文件
        for file in img_files:
            # 构建图片文件的完整路径
            file_path = os.path.join(root, file)
            
            # 使用OpenCV的imdecode函数读取图片
            img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
            
            # 计算图片的拉普拉斯变换方差,用来衡量图片的清晰度
            image_var = cv2.Laplacian(img, cv2.CV_64F).var()
            
            # 如果图片的拉普拉斯方差小于100,认为图片过于模糊
            if image_var < 100:
                # 将该图片移动到filter_blurred目录中
                shutil.move(file_path, filter_dir)
                
                # 增加过滤掉的模糊图片数量计数
                filter_number += 1
    
    # 返回过滤掉的模糊图片数量
    return filter_number

四、去除重复图片

        经过观察,数据集中存在部分重复图片信息,影响训练效率和准确度。比较两张图片在大小、尺寸和内容上是否完全相同,如果大小、尺寸和内容都相同,则去除一张图片;否则返回两张图片。

def 比较图片大小(dir_image1, dir_image2):
    # 读取图片文件1的字节大小
    with open(dir_image1, "rb") as f1:
        size1 = len(f1.read())
    
    # 读取图片文件2的字节大小
    with open(dir_image2, "rb") as f2:
        size2 = len(f2.read())
    
    # 比较两张图片的字节大小是否相同
    if size1 == size2:
        result = "大小相同"
    else:
        result = "大小不同"
    
    return result

def 比较图片尺寸(dir_image1, dir_image2):
    # 使用PIL库打开图片1和图片2
    image1 = Image.open(dir_image1)
    image2 = Image.open(dir_image2)
    
    # 比较两张图片的尺寸是否相同
    if image1.size == image2.size:
        result = "尺寸相同"
    else:
        result = "尺寸不同"
    
    return result

def 比较图片内容(dir_image1, dir_image2):
    # 使用PIL库和numpy打开并转换图片1和图片2为数组
    image1 = np.array(Image.open(dir_image1))
    image2 = np.array(Image.open(dir_image2))
    
    # 比较两张图片的内容(每个像素是否相同)
    if np.array_equal(image1, image2):
        result = "内容相同"
    else:
        result = "内容不同"
    
    return result

def 比较两张图片是否相同(dir_image1, dir_image2):
    # 比较两张图片是否相同的主函数
    result = "两张图不同"
    
    # 第一步:比较大小是否相同
    大小 = 比较图片大小(dir_image1, dir_image2)
    if 大小 == "大小相同":
        # 第二步:比较尺寸是否相同
        尺寸 = 比较图片尺寸(dir_image1, dir_image2)
        if 尺寸 == "尺寸相同":
            # 第三步:比较内容是否相同
            内容 = 比较图片内容(dir_image1, dir_image2)
            if 内容 == "内容相同":
                result = "两张图相同"
    
    return result

五、去除无字体图片

        部分图片因为截取问题与旋转问题,并未包含需要识别字体部分,我们对这部分内容进行删除,从而提高模型训练效率和准确度。

# 定义一个函数,判断图片是否包含文字
def contains_text(image_path):
    try:
        text = pytesseract.image_to_string(Image.open(image_path))
        return len(text.strip()) > 0  # 如果识别出文字,则返回 True
    except:
        return False  # 出现任何异常(包括无法打开图片),则返回 False

# 定义一个函数,遍历目录下的所有图片文件,并删除识别不出文字的图片
def delete_images_without_text(dir_path):
    for root, dirs, files in os.walk(dir_path):
        for file in files:
            if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
                image_path = os.path.join(root, file)
                if not contains_text(image_path):
                    os.remove(image_path)  # 删除没有文字的图片
                    print(f"Deleted: {image_path}")  # 打印已删除的图片路径
清理后图片数据

六、总结

        经过以上数据清洗工作,删去了大量无用图片,实现了对图片数据集的降维,有利于提高模型训练的效率和准确度,获得更好识别效果。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值