工作中涉及到对图像压缩算法的评价,需要衡量图像压缩前后图像的差异,经典的PSNR指标对结构性差异较敏感,但是对亮度差异不够敏感,故采用亮度直方图来反映差异,因问题大多出现于局部,故而选择在局部上进行计算,避免全局的统计降低敏感度,记录如下:
#coding=utf-8
from PIL import Image
import numpy as np
import datetime as dt
class HistogramSmilarity(object):
def __init__(self,size,gridsize):
self.size=size
self.gridsize=gridsize
self.widemount=self.size[0]//self.gridsize[0]
self.highmount=self.size[1]//self.gridsize[1]
self.gridcount=self.widemount*self.highmount
#self.gridcount=int(self.size[0]*1.0/(self.gridsize[0]-0.5)+1)*int(self.size[1]*1.0/(self.gridsize[1]-0.5)+1)
#self.gridcount=48**2
#self.rate=self.gridcount**0.5
#self.gridsize=(int(self.size[0]/self.rate),int(self.size[1]/self.rate))
def img2regular(self,img):
#将原始图像转化为规则内图像
img_ori=img.resize(self.size)
img_regular=img_ori.convert('RGB')
return img_regular
def img2grid(self,img):
#分割图像
wide,high=self.size
gridwide,gridhigh=self.gridsize
wideremain=self.size[0]%self.gridsize[0]
highremain=self.size[1]%self.gridsize[1]
wide=wide-wideremain
high=high-highremain
gridimg=[]
for i in range(0,self.widemount+1):
for j in range(0,self.highmount+1):
if i<=self.widemount and j<=self.highmount:
localimg=img.crop((i*self.gridsize[0],j*self.gridsize[1],(i+1)*self.gridsize[0],(j+1)*self.gridsize[1])).copy()
elif i==self.widemount+1 and j<=self.highmount:
localimg=img.crop((self.size[0]-self.gridsize[0],j*self.gridsize[1],self.size[0],(j+1)*self.gridsize[1])).copy()
elif i<=self.widemount and j==self.highmount+1:
localimg=img.crop((i*self.gridsize[0],self.size[1]-self.gridsize[1],(i+1)*self.gridsize[0],self.size[1])).copy()
elif i==self.widemount+1 and j==self.highmount+1:
localimg=img.crop((self.size[0]-self.gridsize[0],self.size[1]-self.gridsize[1],self.size[0],self.size[1])).copy()
gridimg.append(localimg)
return gridimg
def histogramdistance(self,histlist1,histlist2):
#计算各个局部区域亮度直方图距离
assert len(histlist1)==len(histlist2)
distance=sum(1-(0 if hist1==hist2 else float(abs(hist1-hist2))/max(hist1,hist2)) for hist1,hist2 in zip(histlist1,histlist2))/len(histlist1)
return distance
def histogramsimilarity(self,image1,image2):
#计算相似性
histsimilarity=sum(self.histogramdistance(img1.histogram(),img2.histogram()) for img1,img2 in zip(self.img2grid(image1),self.img2grid(image2)))/self.gridcount
localmaxdiff=min(self.histogramdistance(img1.histogram(),img2.histogram()) for img1,img2 in zip(self.img2grid(image1),self.img2grid(image2)))
return (histsimilarity,localmaxdiff)
def readimg(self,path1,path2):
#从硬盘读取数据,并进行相似性计算
img1=self.img2regular(Image.open(path1))
img2=self.img2regular(Image.open(path2))
histsimilarity=self.histogramsimilarity(img1,img2)
return histsimilarity
if __name__=="__main__":
size=(3648,2736)
gridsize=(30,30)
#gridcount=48**2 #2x2x2x2x3
#step=1
total=5
logfile="HistogramSmilarityLog"
path1=r'img/ori/'
path2=r'img/localdark/'
example=HistogramSmilarity(size,gridsize)
print("-----------!!!Start!!!-----------")
with open(logfile,"a+") as file:
for i in range(1,total+1):
index=str(i).zfill(3)
img1=path1+str(index)+'.jpg'
img2=path2+str(index)+'.jpg'
time=dt.datetime.now().strftime('%C-%m-%d %T')
histsimilarity,localmaxdiff=example.readimg(img1,img2)
log="["+str(time)+"] [Num."+str(index)+"] Mean:%.3f%%\tMax:%.3f%%\n"%(histsimilarity*100,localmaxdiff*100)
file.write(log)
print(log)
print("-----------!!!Finished!!!-----------")
来源:CSDN
作者:xuesuoziluoshu
链接:https://blog.csdn.net/xuesuoziluoshu/article/details/104703771