python 图片数据清洗,图片去重,去掉模糊图片,去掉结构性相似的图片

2023-05-16

1、python代码去掉完全相同的图片,  重复的图片移动到另一文件夹保存

import shutil
import numpy as np
from PIL import Image
import os


def 比较图片大小(dir_image1, dir_image2):
    with open(dir_image1, "rb") as f1:
        size1 = len(f1.read())
    with open(dir_image2, "rb") as f2:
        size2 = len(f2.read())
    if (size1 == size2):
        result = "大小相同"
    else:
        result = "大小不同"
    return result


def 比较图片尺寸(dir_image1, dir_image2):
    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):
    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


if __name__ == '__main__':

    load_path = r'D:\data\imgs_dir'  # 要去重的文件夹
    save_path = r'D:\data\imgs_dir_repeat'  # 空文件夹,用于存储检测到的重复的照片
    os.makedirs(save_path, exist_ok=True)

    # 获取图片列表 file_map,字典{文件路径filename : 文件大小image_size}
    file_map = {}
    image_size = 0
    # 遍历filePath下的文件、文件夹(包括子目录)
    for parent, dirnames, filenames in os.walk(load_path):
        # for dirname in dirnames:
        # print('parent is %s, dirname is %s' % (parent, dirname))
        for filename in filenames:
            # print('parent is %s, filename is %s' % (parent, filename))
            # print('the full name of the file is %s' % os.path.join(parent, filename))
            image_size = os.path.getsize(os.path.join(parent, filename))
            file_map.setdefault(os.path.join(parent, filename), image_size)

    # 获取的图片列表按 文件大小image_size 排序
    file_map = sorted(file_map.items(), key=lambda d: d[1], reverse=False)
    file_list = []
    for filename, image_size in file_map:
        file_list.append(filename)

    # 取出重复的图片
    file_repeat = []
    for currIndex, _ in enumerate(file_list):
        dir_image1 = file_list[currIndex]
        dir_image2 = file_list[currIndex + 1]
        result = 比较两张图片是否相同(dir_image1, dir_image2)
        if (result == "两张图相同"):
            file_repeat.append(file_list[currIndex + 1])
            print("\n相同的图片:", file_list[currIndex], file_list[currIndex + 1])
        else:
            print('\n不同的图片:', file_list[currIndex], file_list[currIndex + 1])
        currIndex += 1
        if currIndex >= len(file_list) - 1:
            break

    # 将重复的图片移动到新的文件夹,实现对原文件夹降重
    for image in file_repeat:
        shutil.move(image, save_path)
        print("正在移除重复照片:", image)

2. python 代码 去掉模糊图片

import os
import cv2
import shutil
class item:  # (图片, 图片清晰度) 结构体
    def __init__(self):
        self.name = ''     # 图片名称
        self.val = 10     # 图片清晰度 也就是 getImageVar(img)

#利用拉普拉斯   利用拉普拉斯算子计算图片的二阶导数,反映图片的边缘信息,同样事物的图片,清晰度高的,相对应的经过拉普拉斯算子滤波后的图片的方差也就越大
def getImageVar(imgPath):
    image = cv2.imread(imgPath)
    img2gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var()
    return imageVar


if __name__ == "__main__":
    src_img_dir = r"D:\data\img_dir"
    move_img_dir = r"D:\data\img_dir_blur"
    os.makedirs(move_img_dir, exist_ok=True)
    img_files = os.listdir(src_img_dir)
    print("len(img_files): ", len(img_files))
    a_list = []
    for i in range(len(img_files)):
        img_file_path = os.path.join(src_img_dir, img_files[i])
        imageVar = getImageVar(img_file_path)
        # print(imageVar)
        a = item()
        a.val = imageVar
        a.name = img_files[i]
        a_list.append(a)
    print("len(a_list): ", len(a_list))

    a_list.sort(key=lambda ita: ita.val, reverse=False) # 对 (图片, 图片清晰度) 结构体 列表 按照 图片清晰度排序, 模糊的放在列表头部, 清晰的放在列表尾部

    count = 0
    for i in range(int(len(a_list)*0.1)): # 移除最模糊的 %10 的图片
        print(a_list[i].name, a_list[i].val)
        src_path = os.path.join(src_img_dir, a_list[i].name)
        dest_path = os.path.join(move_img_dir, a_list[i].name)
        shutil.move(src_path, dest_path)
        count += 1
        # break
    print("count: ", count)

3. python代码,设置阈值,去掉结构性相似的图片。后续还要从每组结构性相似的图片,手动筛选一张图片放回原文件夹。

# coding: utf-8
import os
import cv2
# from skimage.measure import compare_ssim
# from skimage.metrics import _structural_similarity
from skimage.metrics import structural_similarity as ssim
import shutil

# def delete(filename1):
#     os.remove(filename1)




def list_all_files(root):
    files = []
    list = os.listdir(root)
    # os.listdir()方法:返回指定文件夹包含的文件或子文件夹名字的列表。该列表顺序以字母排序
    for i in range(len(list)):
        element = os.path.join(root, list[i])
        # 需要先使用python路径拼接os.path.join()函数,将os.listdir()返回的名称拼接成文件或目录的绝对路径再传入os.path.isdir()和os.path.isfile().
        if os.path.isdir(element):  # os.path.isdir()用于判断某一对象(需提供绝对路径)是否为目录
            # temp_dir = os.path.split(element)[-1]
            # os.path.split分割文件名与路径,分割为data_dir和此路径下的文件名,[-1]表示只取data_dir下的文件名
            files.append(list_all_files(element))

        elif os.path.isfile(element):
            files.append(element)
    # print('2',files)
    return files


def ssim_compare(img_files):
    imgs_n = []
    count = 0
    # thresh_lis = [0.9, 0.8, 0.7, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35]
    # for thresh in thresh_lis:
    for currIndex, _ in enumerate(img_files):
        if not os.path.exists(img_files[currIndex]):
            print('not exist', img_files[currIndex])
            break
        img = cv2.imread(img_files[currIndex])
        img1 = cv2.imread(img_files[currIndex + 1])
        # 进行结构性相似度判断
        # ssim_value = _structural_similarity.structural_similarity(img,img1,multichannel=True)
        ssim_value = ssim(img, img1, multichannel=True)
        thresh = 0.9
        if ssim_value > thresh:
            # 基数
            count += 1
            imgs_n.append(img_files[currIndex + 1])
            imgs_n.append(img_files[currIndex])
            print('big_ssim:', img_files[currIndex], img_files[currIndex + 1], ssim_value)
        # 避免数组越界
        if currIndex + 1 >= len(img_files) - 1:
            break
    save_dir = r"D:\data\img_dir_sim_"+str(thresh)
    os.makedirs(save_dir, exist_ok=True)

    for file in list(set(imgs_n)): # 去掉重复的路径,再遍历 剪切
        shutil.move(file, os.path.join(save_dir, os.path.basename(file)))
    return count


if __name__ == '__main__':
    path = r'D:\data\img_dir'

    all_files = list_all_files(path)  # 返回包含完整路径的所有图片名的列表
    print('len: ', len(all_files))
    count = ssim_compare(all_files)
    print(count)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 图片数据清洗,图片去重,去掉模糊图片,去掉结构性相似的图片 的相关文章

  • FreeRTOS可视化追踪软件 —— 破解Tracealyzer 4.2.12

    方法一 愚人节破解Tracealyzer 4 2 12 xff08 若发这里不妥 xff0c 可通知删贴 xff09 http www stmcu org cn module forum thread 620069 1 1 html 4 3
  • tensorflow2(GPU)显卡版安装

    准备工作 硬件 xff1a 一张算力3 5以上的NVIDIA显卡 查询链接 link 软件 xff1a Miniconda3 pycharm NVIDIA显卡驱动 30系列以前 xff1a cuda 10 1 cudnn 10 1 v7 6
  • elasticsearch底层引擎替换之索引创建+文档添加

    最近在改elasticsearch的源码 xff0c 真的蛋疼 xff0c 现在先记录一下遇到的问题 首先 xff0c 我们在做的是替换掉elasticsearch的底层引擎 xff0c 也就是把lucene替换成我们自己的引擎 这个工作起
  • Winform 集成零散dll进exe的方法

    Winform程序经常需要引用一些第三方控件 xff0c 这些控件大多以DLL的形式提供 另外 xff0c 一般USB桥芯片的官方提供 net操作类库也都是DLL形式提供的 因此一个稍大的项目中往往有一大堆的零散的DLL文件 xff0c 而
  • vncserver 使用遇到的问题

    今天使用vncserver遇到了几个问题 xff0c 如下 xff1a 1 使用普通账户无法修改该账户下的vncpasswd xff1a 解决方法 xff1a 打开 vnc目录 xff0c ls l看一下发现 passwd这个文件的用户和用
  • slf4j的MDC对象和ThreadLocal简单分析

    MDC xff08 Mapped Diagnostic Context xff0c 映射调试上下文 xff09 是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能 某些应用程序采用多线程的方式来处理多个用户的请求
  • springboot中@bean的lite模式

    当 64 Beans相互依赖时 xff0c 表示依赖关系就像一个bean方法调用另一个方法一样简 单 xff1a 64 Configuration public class AppConfig 64 Bean public Foo foo
  • spring bean解析源码分析

    转自https www jianshu com p 19e01388ccc5 前言 Spring源码分析是一个系列 xff0c 源码是Spring 4 X xff0c 本系列主要分析Spring的代码执行流程 xff0c 过于细节的内容将不
  • springboot remote shell简单实例

    springboot项目可以使用远程shell进行监控和管理 xff08 在2 0版本就不可以使用了 xff0c 此处要注意 xff09 使用时先添加spring boot remote shell 的依赖 xff0c gradle项目自己
  • 2021-08-30 创建tensor时,注意不要让梯度消失了

    下面这种是错误的 xff0c 梯度会消失 data span class token operator 61 span torch span class token punctuation span tensor span class to
  • 嵌入式学习项目实战 --- 在线词典

    目录 一 前言 二 项目功能 三 程序流程 1 客户端 2 服务器 四 代码实现 1 客户端代码 2 服务器代码 3 Makefile 一 前言 本文学习自 华清远见 的一个开源嵌入式项目在线词典综合实战 xff0c 涵盖了网络编程 文件I
  • hexo博客的制作

    安装Hexo 首先来看看我的hexo的博客演示 地址 xff1a http 91lyj xyz 我的ssm博客地址 xff1a www iclyj cn a target blank href http 91lyj xyz http 91l
  • win10系统CUDA10.0安装教程(for tensorflow2.0)

    前言 xff1a 目前最新的CUDA版本是10 1 xff0c 但是出于某种神秘的原因 xff0c 目前tensorflow2 0仅支持CUDA10 0 这个已经在我的电脑与一部分网友的反馈中得到了证实 tensorflow2 0不仅绑定了
  • 数学学习——Borel-Cantelli 引理证明

  • linux中的设备名称和设备号

    看赵炯博士的 linux 0 11 源代码注释 已经两三周了 xff0c 从今天起开始将一些个人总结和感悟分小标题写出来 xff0c 聊作记忆以供后来查看 在linux0 11源码的 linux boot bootsect s中 xff0c
  • python学习——numpy savetxt 追加模式

    因为savetxt的第一个参数f xff0c 可以是file handle xff0c 也可以是file name 所以用以下的这个代码就可以 xff1a span class token keyword with span span cl
  • 量化投资学习——A股H股套利年化100%

    一 交易对象选取 首先是选取数据 xff0c 选取数据的来源是wind xff1a 从wind中的交易数据 AH比较 里面可以看到历史收盘价和A H溢价率 xff0c 考虑到在2008年金融危机之后 xff0c 全球市场发生了较大的变化 x
  • C++学习——介绍一些C++内存检测工具

    1 C C 43 43 内存治理神器 Google Sanitizers Santizers是由Google开发的开源工具 xff0c 集成在LLVM项目中 xff0c 来检查内存泄漏和其他内存错误 Sanitize工具是一组用于检测内存错
  • C++学习——如何增加堆栈大小来避免内存分配的问题

    为了避免程序在运行过程中内存分配不足的问题 xff0c 你可以增加程序分配的内存量 在CMake中 xff0c 你可以通过在CMakeLists txt文件中添加设定来实现 你可以通过添加以下代码来增加程序分配的内存量 xff1a set
  • C++学习——解决一个double free or corruption (!prev)错误

    在我的场景下 xff0c 出现问题的地方是一个for循环 xff0c 代码如下所示 xff1a span class token keyword for span span class token punctuation span span

随机推荐