亮度直方图局域化

≡放荡痞女 提交于 2020-03-07 02:55:42

工作中涉及到对图像压缩算法的评价,需要衡量图像压缩前后图像的差异,经典的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!!!-----------")

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!