Python用哈希算法查找相似图片(包括不同分辨率,不同大小,不同格式的图片)

这篇具有很好参考价值的文章主要介绍了Python用哈希算法查找相似图片(包括不同分辨率,不同大小,不同格式的图片)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

# -*- coding: utf-8 -*-
'''
Python用哈希算法查找相似图片并放入[_df]的文件夹中

相似图片包括不同分辨率,不同大小,不同格式,只要图片相似就会算重复文件


安装cv2
pip install opencv-python

'''
import os
import cv2
import numpy as np
import shutil
import random

class DuplicateFiles (object): 
    dir = ''
    def __init__(self, dir):
        self.dir = dir  # 实例属性

    # 均值哈希算法
    def aHash(self,img,shape=(10,10)):
        # 缩放为10*10
        img = cv2.resize(img, shape)
        # 转换为灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # s为像素和初值为0,hash_str为hash值初值为''
        s = 0
        hash_str = ''
        # 遍历累加求像素和
        for i in range(shape[0]):
            for j in range(shape[1]):
                s = s + gray[i, j]
        # 求平均灰度
        avg = s / 100
        # 灰度大于平均值为1相反为0生成图片的hash值
        for i in range(shape[0]):
            for j in range(shape[1]):
                if gray[i, j] > avg:
                    hash_str = hash_str + '1'
                else:
                    hash_str = hash_str + '0'
        return hash_str

    # 差值感知算法
    def dHash(self,img,shape=(10,10)):
        # 缩放10*11
        img = cv2.resize(img, (shape[0]+1, shape[1]))
        # 转换灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        hash_str = ''
        # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
        for i in range(shape[0]):
            for j in range(shape[1]):
                if gray[i, j] > gray[i, j + 1]:
                    hash_str = hash_str + '1'
                else:
                    hash_str = hash_str + '0'
        return hash_str

    # 感知哈希算法(pHash)
    def pHash(self,img,shape=(10,10)):
        # 缩放32*32
        img = cv2.resize(img, (32, 32))  # , interpolation=cv2.INTER_CUBIC

        # 转换为灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 将灰度图转为浮点型,再进行dct变换
        dct = cv2.dct(np.float32(gray))
        # opencv实现的掩码操作
        dct_roi = dct[0:10, 0:10]

        hash = []
        avreage = np.mean(dct_roi)
        for i in range(dct_roi.shape[0]):
            for j in range(dct_roi.shape[1]):
                if dct_roi[i, j] > avreage:
                    hash.append(1)
                else:
                    hash.append(0)
        return hash

    # 通过得到RGB每个通道的直方图来计算相似度
    def classify_hist_with_split(self,image1, image2, size=(256, 256)):
        # 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值
        image1 = cv2.resize(image1, size)
        image2 = cv2.resize(image2, size)
        sub_image1 = cv2.split(image1)
        sub_image2 = cv2.split(image2)
        sub_data = 0
        for im1, im2 in zip(sub_image1, sub_image2):
            sub_data += self.calculate(im1, im2)
        sub_data = sub_data / 3
        return sub_data

    # 计算单通道的直方图的相似值
    def calculate(self,image1, image2):
        hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
        hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
        # 计算直方图的重合度
        degree = 0
        for i in range(len(hist1)):
            if hist1[i] != hist2[i]:
                degree = degree + (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
            else:
                degree = degree + 1
        degree = degree / len(hist1)
        return degree

    # Hash值对比
    def cmpHash(self,hash1, hash2,shape=(10,10)):
        n = 0
        # hash长度不同则返回-1代表传参出错
        if len(hash1)!=len(hash2):
            return -1
        # 遍历判断
        for i in range(len(hash1)):
            # 相等则n计数+1,n最终为相似度
            if hash1[i] == hash2[i]:
                n = n + 1
        return n/(shape[0]*shape[1])

    def mymovefile(self,srcfile,dstpath,ffname):           # 移动函数
        if not os.path.isfile(srcfile):
            print ("%s not exist!"%(srcfile))
        else:
            fpath,fname=os.path.split(srcfile)             # 分离文件名和路径
            if(ffname):fname=ffname
            if not os.path.exists(dstpath):
                os.makedirs(dstpath)                       # 创建路径
            shutil.move(srcfile, dstpath + fname)          # 移动文件
            #print ("move %s -> %s"%(srcfile, dstpath + fname))

    # 定义函数
    def list_all_files(self,rootdir):
        _files = []
    	# 列出文件夹下所有的目录与文件
        list = os.listdir(rootdir)
        for i in range(0, len(list)):
    		# 构造路径
            path = os.path.join(rootdir, list[i])
    		# 判断路径是否为文件目录或者文件
    		# 如果是目录则继续递归
            if os.path.isdir(path):
                _files.extend(list_all_files(path))
            if os.path.isfile(path):
                _files.append(path)
        return _files

    #处理文件
    def mvPhoto(self):
        
        photoList = self.list_all_files(self.dir)
        #print(photoList)

        for i,photo in enumerate(photoList):
            mvPhoto = False #是否移动主文件
            #如果不是文件则跳出
            if(not os.path.isfile(photo)):
                continue
            fpath,fname=os.path.split(photo)
            print('Master:'+fname)
            ffname = fname.split('.')

            #不是下列文件形式跳出
            if(ffname[1] not in {'jpg', 'bmp', 'png', 'jpeg', 'gif'}):
                continue

            img1 = cv2.imdecode(np.fromfile(photo,dtype=np.uint8),cv2.IMREAD_COLOR)
            for j in range(i+1,len(photoList)):
                #print('  ',j,photoList[j])
                if(not os.path.isfile(photo) or not os.path.isfile(photoList[j])):
                    continue
                spath,sname=os.path.split(photoList[j])
                #print(sname)
                ssname = sname.split('.')
                if(ssname[1] not in {'jpg', 'bmp', 'png', 'jpeg', 'jfif'}):
                    continue
                
                #img1 = cv2.imread(photo)
                img2 = cv2.imdecode(np.fromfile(photoList[j],dtype=np.uint8),cv2.IMREAD_COLOR)
                
                #hash1 = aHash(img1)
                #hash2 = aHash(img2)
                n1 = self.cmpHash(self.aHash(img1), self.aHash(img2))
                n2 = self.cmpHash(self.dHash(img1), self.dHash(img2))
                n3 = self.cmpHash(self.pHash(img1), self.pHash(img2))
                n4 = self.classify_hist_with_split(img1, img2)
                n5 = self.calculate(img1, img2)
                #print('    ',n1,n2,n3,n4,n5)
                if(n1>0.90 or n2>0.90 or n3>0.90 or n4>0.90 or n5>0.90):
                    mvPhoto = True
                    print('    move file:'+photoList[j])
                    if(os.path.isfile(photoList[j])):
                        print('ffname[0]:'+ffname[0])
                        #mymovefile(photoList[j],dir+'_重复'+'/',ffname[0]+'_'+str(random.randint(10,99))+'.'+ffname[1])
                        self.mymovefile(photoList[j],dir+'_df'+'/',ffname[0]+'_'+sname)
            
            #最后移动主文件
            if(mvPhoto==True):    
                self.mymovefile(photo,dir+'_df'+'/',fname)

if __name__ == "__main__":
    #指定路径
    #dir = r'E:\python\photoCompare\328' #指定目录地址
    dir = os.getcwd()                    #当前文件所在目录
    duplicateFiles = DuplicateFiles(dir)
    duplicateFiles.mvPhoto()

  文章来源地址https://www.toymoban.com/news/detail-420472.html

到了这里,关于Python用哈希算法查找相似图片(包括不同分辨率,不同大小,不同格式的图片)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 语言哈希查找算法实现

    哈希查找,也称为散列查找,是一种高效的查找算法。它利用哈希函数将映射到数组中的一个位置,通过直接访问该位置来获取元素,从而实现快速查找。Java语言提供了一些类和接口,例如 HashMap 和 HashTable ,使得我们可以方便地使用哈希查找算法。本文将详细介绍

    2024年02月10日
    浏览(32)
  • 数据结构,查找算法(二分,分块,哈希)

    一、查找算法         1、二分查找:(前提条件: 必须有序的序列) 2、分块查找:(块间有序,块内无序)     索引表  +  源数据表     思路:     (1)先在索引表中确定在哪一块中     (2)再遍历这一块进行查找 //索引表 typedef  struct  {     int max; //块中最大值

    2024年02月11日
    浏览(41)
  • Python 不同分辨率图像峰值信噪比[PSNR]

    PNNR:全称为“Peak Signal-to-Noise Ratio”,中文直译为峰值信噪比 前言 一、定义 二、Python代码 1.自定义 2.Tensorflow 总结 峰值信噪比是一种衡量图像质量的指标,描述的是最大值信号与背景噪音之间的关系。 一般来说,PSNR高于40dB说明图像质量极好(即非常接近原始图像);在

    2024年02月01日
    浏览(38)
  • 基于直方图相似性的图像分类算法FPGA实现,包括tb测试文件和MATLAB辅助验证

    目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 MATLAB测试结果: FPGA测试结果: 上述仿真图中,红色XX表示图像读取完毕。因此输出XX。当图像输出完成之后,最下面的相似性指标 same1输出为11226,same2输出为67584.即图1和图

    2024年04月09日
    浏览(30)
  • 哈希(Hash)查找算法详解之C语言版

    哈希查找是一种快速查找算法,该算法不需要对进行比较,而是以为自变量,以该在存储空间中的地址为因变量,建立某种函数关系,称为哈希函数,这样在查找某一的时候,就可以通过哈希函数直接得到其地址,有效的提高了查找效率。 选取哈希

    2024年01月19日
    浏览(25)
  • python求不同分辨率图像的峰值信噪比,一文搞懂

    可以使用 Python 的 NumPy 和 OpenCV 库来实现这个任务。提前准备一张图片作为素材。 峰值信噪比(Peak Signal to Noise Ratio,PSNR)是衡量图像质量的常用指标,它表示图像中信号和噪声的比值。通常,较高的 PSNR 值表示图像质量较高。 PSNR 的公式如下: 其中, MAX 是图像的最大亮度

    2024年02月05日
    浏览(32)
  • 如何在Python中获取图片分辨率?——Python实现获取图片分辨率的代码及详解。

    如何在Python中获取图片分辨率?——Python实现获取图片分辨率的代码及详解。 在进行图片处理或者图片分析的时候,获取图片的分辨率信息是必不可少的。Python提供了许多库可以方便地获取图片的分辨率信息。在本文中,我们将详细介绍如何使用Python实现获取图片分辨率的功

    2024年02月07日
    浏览(33)
  • 查找算法【哈希表】 - 处理冲突的方法:开放地址法-线性探测法

    查找算法【哈希表】 - 处理冲突的方法 无论如何设计散列函数,都 无法避免 发生冲突。 如果发生冲突,就需要处理冲突。 处理冲突的方法分为3种: 开放地址法 链地址法 建立公共溢出区。 【开放地址法】 开放地址法是线性存储空间上的解决方案,也被称为闭散列。 当发

    2024年02月12日
    浏览(24)
  • OpenCV书签 #结构相似性SSIM算法的原理与图片相似性实验

    结构相似性(Structural Similarity,简称SSIM算法) ,主要用于检测两张相同尺寸的图像的相似度、或者检测图像的失真程度,是一种衡量两幅图像相似度的指标。 给定两个图像 x 和 y,两张图像的结构相似性可按照以下方式求出: 结构相似性的范围为 -1 到 1。当两张图像一模一

    2024年01月24日
    浏览(30)
  • 对比多张图片相似度(PYTHON)

    可以使用图像处理软件或者编程语言进行相似度对比。常用的指标有:      1. 均方误差(MSE): 计算每个像素的差异,再求平均值。公式:MSE = 1/nΣ(i=1,n)(I1(i)-I2(i))^2,其中I1和I2是两张图片对应像素的灰度值,n是像素数量。MSE越小,表示图片越相似。      2. 结构相似度指

    2024年02月12日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包