Python 之图片对比

转自:https://testerhome.com/topics/4539

在2年前我发过一个帖子,就是说图片相似度的。总体来讲,最近工作上绕了一圈又回到了这里。所以就开个帖子再来说下,让更多的同学能够去使用。

在图片处理上其实还是需要用到一个库,前两天社区还有朋友说到——PILLOW。聊下PILLOW吧,前身是PIL,PIL可以非常简单的将一个图 片直接转换成像素点的一个集合。就比如Python中提供简单的API可以直接将一张300*200的图转换成由300*200个RGBA数据组成的 tuple。我们拿到像素点之后想怎么比较就是可以自定义以及算法的事儿了。

这里直接切入主题就来说方法了,也推荐大家一个github库参考。
直方图的话是将图片转换成一个队列,通过这个队列的相似度来判断图片的相似度的。但是直方图本身优点缺点都很明显。优点的话就是对比的结果很直观,而且天 生支持模糊对比。但是缺点就是直方图其实不够智能,因为大多都是像素点上的颜色分布来做对比的,却没有任何算法和模型上的支持,导致精准度其实不高(但其 实也是比较特殊的情况下才可能被误导)
比如下面的两张图:

我们调用如下的代码能够直观的看到两张图的直方图的对比的结果:

import matplotlib.pyplot as plt 
from pylab import * from PIL
import
Image import math
import operator
image1
= Image.open('1.JPG')
image2 = Image.open('2.JPG')
plot
(image1.histogram(),linewidth=2)
plot(image2.histogram(),linewidth=2)
show()

结果就很直观了。


我们还是说下缺点,这个图你们也看到了,几乎可以说是差不多了,所以直方图的结果曲线吻合度还是很高的。但是同样的,这张图是蓝色和绿色偏多,如果说是一个穿着天蓝色内裤,绿色大衣的姑娘的图片,也许直方图出来的结果差不多。so,你们明白啥意思了吧

直方图方法一:
这个也是我最常用的,Google出来的方法:


#sudo pip install PIL

def pil_image_similarity(filepath1, filepath2):

    from PIL import Image

    import math

    import operator

 

    image1 = Image.open(filepath1)

    image2 = Image.open(filepath2)

 

#    image1 = get_thumbnail(img1)

#    image2 = get_thumbnail(img2)

 

    h1 = image1.histogram()

    h2 = image2.histogram()

 

    rms = math.sqrt(reduce(operator.add,  list(map(lambda a,b: (a-b)**2, h1, h2)))/len(h1) )

    return rms


直方图方法二:

fromPILimportImage
def
classfiy_histogram(image1,image2,size=(256,256)):    
image1=image1.resize(size).convert("RGB")  
 
g=image1.histogram()    
image2
=image2.resize(size).convert("RGB")  
 
s=image2.histogram()    
assert
len(g)==len(s),"error"    
data
=[]   
 
forindexinrange(0,len(g)):       
ifg[index]!=s[index]:           
data
.append(1-abs(g[index]-s[index])/max(g[index],s[index]))      
 
else:           
data
.append(1)   
 
returnsum(data)/len(g)

直方图方法三:



fromPILimportImage  
def
calculate(image1,image2):   
g
=image1.histogram()  
 
s=image2.histogram()  
 
assertlen(g)==len(s),"error"   
 
data=[]    
forindexinrange(0,len(g)):       
ifg[index]!=s[index]:           
data
.append(1-abs(g[index]-s[index])/max(g[index],s[index]))       
else:           
data
.append(1)    
returnsum(data)/len(g) 
 
defsplit_imgae(image,part_size):   
pw
,ph=part_size   
w
,h=image.size   
 
sub_image_list=[]   
 
assertw%pw==h%ph==0,"error"    
foriinrange(0,w,pw):       
forjinrange(0,h,ph):           
sub_image
=image.crop((i,j,i+pw,j+ph)).copy()           
sub_image_list
.append(sub_image)    
return
sub_image_list
defclassfiy_histogram_with_split(image1,image2,size=(256,256),part_size=(64,64)):     
image1
=image1.resize(size).convert("RGB")   
sub_image1=split_imgae(image1,part_size)    
image2
=image2.resize(size).convert("RGB")   
sub_image2
=split_imgae(image2,part_size)   
 
sub_data=0;   
for
im1,im2inzip(sub_image1,sub_image2):      
 
sub_data+=calculate(im1,im2)    
x
=size[0]/part_size[0]   
y=size[1]/part_size[1]    
pre
=round((sub_data/(x*y)),3)  
 
return  pre __all__=[classfiy_histogram_with_split]

更多的方法可见:https://github.com/monkeytest15/Learn-to-identify-similar-images。这个也是前几天找到的,感谢作者


原文地址:https://www.cnblogs.com/eagleking0318/p/6520733.html