在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  

defcalculate(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)     

returnsub_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;    

forim1,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