搜索
bottom↓
回复: 26

Python如何判定两幅图片完全一样?

[复制链接]

出0入0汤圆

发表于 2020-4-9 22:36:28 | 显示全部楼层 |阅读模式
主要两种比对:1:png与png对比 2:svg与svg对比
我的实现办法如下,但是不够准确,各位有没有更好的Python实现方法,请教一下,谢谢。

#判断文件大小一样
def checkImgIsSameBySize(img1, img2):
    nSize1 = os.path.getsize(img1)
    nSize2 = os.path.getsize(img2)
    if nSize1 == nSize2:
        return True
    else:
        return False


def checkImgIsSameByImageChops(img1, img2):
    #两个图像之间逐像素差异的绝对值
    image_one = Image.open(img1)
    image_two = Image.open(img2)
    try:   
        diff = ImageChops.difference(image_one, image_two)
        # 图片间没有任何不同则直接退出(只是轮廓相同)
        if diff.getbbox() is None:
            return True
        else:
            return False
    except ValueError:
        #表示图片大小和box对应的宽度不一致
        return False
        

#判断两个图像文件是否相同()
def checkImgIsSameByCV(img1, img2):
    image1=cv2.imread(img1)
    image2=cv2.imread(img2)
    try:
        check=cv2.subtract(image1, image2)
        out=not numpy.any(check)
        if out==True:
            return True
        else:
            return False
    except ValueError:
        return False


def checkImgIsSame(img1,img2):
    if checkImgIsSameBySize(img1,img2):
        if checkImgIsSameByImageChops(img1,img2):
            if checkImgIsSameByCV(img1,img2):
                return True
            else:
                return False
        else:
            return False
    else:
        return False

if __name__ == "__main__":
        checkImgIsSame("d:/test1.png","d:/test2.png")

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入25汤圆

发表于 2020-4-9 22:52:16 | 显示全部楼层
校验 md5  是否可行?

出40入514汤圆

发表于 2020-4-9 23:14:06 来自手机 | 显示全部楼层
如果lz是用来查重实际应用的,可以搜索  文件查重  软件,速度很快很方便可以选很多个目录。如果只是出于学习编程搞研究的当我没说

出0入984汤圆

发表于 2020-4-9 23:17:53 | 显示全部楼层
完全相同:比hash
内容相同格式画质不同:ssim

出0入121汤圆

发表于 2020-4-9 23:38:22 | 显示全部楼层
本帖最后由 nokia007 于 2020-4-9 23:43 编辑

楼主说的图片完全一样不知道是给人的感觉完全一样还是像素级匹配。

出0入0汤圆

 楼主| 发表于 2020-4-10 08:42:29 | 显示全部楼层
nokia007 发表于 2020-4-9 23:38
楼主说的图片完全一样不知道是给人的感觉完全一样还是像素级匹配。

肉眼看起来一样的

出0入0汤圆

发表于 2020-4-10 11:30:33 来自手机 | 显示全部楼层
首先LZ要用程序或者数学的语言定义什么是标题中的“完全一样”,然后才可能有解决方案

出0入0汤圆

 楼主| 发表于 2020-4-10 13:40:31 | 显示全部楼层
fnems 发表于 2020-4-10 11:30
首先LZ要用程序或者数学的语言定义什么是标题中的“完全一样”,然后才可能有解决方案 ...

完全一样,如一张图复制一份,这两张图片才算一样。其他的,如缩放,背景不一致等都不是一样

出0入4汤圆

发表于 2020-4-10 14:23:55 | 显示全部楼层
同样的图,文件格式不一样,这算一样吗?

出0入0汤圆

发表于 2020-4-10 16:41:19 | 显示全部楼层
ly674496415 发表于 2020-4-10 13:40
完全一样,如一张图复制一份,这两张图片才算一样。其他的,如缩放,背景不一致等都不是一样 ...

你既然把完全一样定义为如同复制粘贴,那就比较hash简单有效。

出0入0汤圆

发表于 2020-4-10 20:20:07 | 显示全部楼层
简单比较文件相同不是md5吗  网上下载都是附带这个人证

出0入0汤圆

发表于 2020-4-10 21:52:03 | 显示全部楼层
本帖最后由 fnems 于 2020-4-10 22:00 编辑
ly674496415 发表于 2020-4-10 13:40
完全一样,如一张图复制一份,这两张图片才算一样。其他的,如缩放,背景不一致等都不是一样 ...

仔细看了你的定义和楼主位的代码,我觉得写得挺好的。
让我写大概也是这个思路,先比较色域、尺寸,如果都一致就进行像素比对。

那么,楼主位的代码,有什么不满意的地方呢?

另外checkImgIsSame函数可以这样写:
  1. def checkImgIsSame(img1,img2):
  2.     return checkImgIsSameBySize(img1,img2) \
  3.           and checkImgIsSameByImageChops(img1,img2) \
  4.           and checkImgIsSameByCV(img1,img2)
  5. # end checkImgIsSame()
复制代码

and逻辑是有顺序的。当从左往右出现第一个False时就得到False,后面的函数并不运行。跟你原始代码的效果是一样的


另外,你在前面回帖中提到“肉眼看起来一样的”,这个“一样”的要求就放宽了很多。
像素色彩的微小差异人眼是看不出来的,正因这样这样才有了压缩算法,JPEG可以忽略DCT变换后的高频分量。
所以举个例子,JPEG对图片的8级压缩和9级压缩是“肉眼看起来一样的”,但在像素数据上可能会差很多

出0入71汤圆

发表于 2020-4-10 22:02:57 | 显示全部楼层
直接获取文件的CRC32

出0入0汤圆

发表于 2020-4-10 22:06:01 | 显示全部楼层


楼上那些说比对文件的,是不行的,PNG里面可能包含meta信息。meta信息的不同可能导致文件内容不同,但图像完全相同。如果连meta信息是什么都不知道,就别给LZ添乱了。

另外还想问LZ,如果一个图像是灰度色域,另一个图像是24位色域,但是都存储了相同的黑白图像,举个极端的例子两个图片都是同尺寸纯白色,应该要判断是相同的吧?

出0入121汤圆

发表于 2020-4-11 02:10:32 来自手机 | 显示全部楼层
py我不会,但是如果用c的话我会考虑像素比较,像素的rgba不用100%一样,可以给个范围。

出0入0汤圆

 楼主| 发表于 2020-4-11 09:34:35 | 显示全部楼层
本帖最后由 ly674496415 于 2020-4-11 09:40 编辑
rei1984 发表于 2020-4-9 22:52
校验 md5  是否可行?


高手,MD5这个方法确实达到了要求,谢啦

出0入0汤圆

 楼主| 发表于 2020-4-11 09:35:24 | 显示全部楼层
hz_fujian 发表于 2020-4-10 14:23
同样的图,文件格式不一样,这算一样吗?

现在比对格式是一样的呐

出0入0汤圆

 楼主| 发表于 2020-4-11 09:35:42 | 显示全部楼层
本帖最后由 ly674496415 于 2020-4-11 09:40 编辑
huangqi412 发表于 2020-4-10 20:20
简单比较文件相同不是md5吗  网上下载都是附带这个人证


高手,MD5这个方法确实达到了要求,谢啦

出0入0汤圆

 楼主| 发表于 2020-4-11 09:36:11 | 显示全部楼层
本帖最后由 ly674496415 于 2020-4-11 09:37 编辑

多谢各位大师指点,MD5能达到了要求(附带自己的实现)

#使用加密hash判定图片是否完全一样
def checkImgIsSameByMD5Hash(img1,img2):
    img_data1 = numpy.array(Image.open(img1))
    img_data2 = numpy.array(Image.open(img2))
    imgMD51 = hashlib.md5(img_data1).hexdigest()
    imgMD52 = hashlib.md5(img_data2).hexdigest()
    if imgMD51==imgMD52:
        return True
    else:
        return False

出0入0汤圆

发表于 2020-4-11 10:49:44 来自手机 | 显示全部楼层
本帖最后由 fnems 于 2020-4-11 10:51 编辑
ly674496415 发表于 2020-4-11 09:36
多谢各位大师指点,MD5能达到了要求(附带自己的实现)

#使用加密hash判定图片是否完全一样


判断哈希只是程序写起来方便,代码上偷懒。

但是哈希也是对完整数据的计算,背后运算量明显大很多,速度上讲看似笨办法的逐字节比对其实是最快运算量最少的。

当然如果LZ不关心速度就当我没说

出0入0汤圆

发表于 2020-4-15 22:30:58 来自手机 | 显示全部楼层
fnems 发表于 2020-4-11 10:49
判断哈希只是程序写起来方便,代码上偷懒。

但是哈希也是对完整数据的计算,背后运算量明显大很多,速度 ...

如果再考虑大文件读取速度的话,分开读两个文件应该比同时读两个文件快吧?

出0入0汤圆

发表于 2020-4-15 22:36:35 | 显示全部楼层
考虑缩放的影响,把大尺寸的先缩放到跟小尺寸的一致,然后把所有像素点之间的方差加和进行比较,差值过大则认为不一致,否则认为一致(类似)

出0入134汤圆

发表于 2020-4-15 22:42:27 | 显示全部楼层
参考这个
https://www.cnblogs.com/botoo/p/8416315.html

出0入0汤圆

发表于 2020-4-15 23:25:44 | 显示全部楼层
brentcao 发表于 2020-4-15 22:30
如果再考虑大文件读取速度的话,分开读两个文件应该比同时读两个文件快吧? ...

cv2.imread(img1)
这句执行完之后图像就加载到内存了。不存在同时读两个文件。

出0入0汤圆

 楼主| 发表于 2020-4-17 13:35:19 | 显示全部楼层
fnems 发表于 2020-4-11 10:49
判断哈希只是程序写起来方便,代码上偷懒。

但是哈希也是对完整数据的计算,背后运算量明显大很多,速度 ...

大师的做法简单高效,采用了你的建议。谢谢

出0入0汤圆

 楼主| 发表于 2020-4-17 13:36:16 | 显示全部楼层
elecfun 发表于 2020-4-15 22:42
参考这个
https://www.cnblogs.com/botoo/p/8416315.html

谢谢大师指点

出80入0汤圆

发表于 2020-4-26 13:33:26 | 显示全部楼层
如果用PIL可以对一个一个像素比较,如果hash的话,文件meta不一样就怎么都是不一样的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 17:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表