"""
常见IQA算法评价指标函数接口:
- 皮尔逊相关系数:PLCC
- 斯德尔曼相关系数:SROCC
- 肯德尔系数:kendall_corrcoef
- 离群率:outlier rate
- MSE
"""
import pandas
import scipy.stats as stas
from scipy.optimize import curve_fit
import numpy as np
def parse_objective_score(filename, delimiter=','):
with open(filename, 'r') as f:
lines = f.readlines()
path_list, score_list = [], []
for line in lines:
path, score = line.strip().split(delimiter)
path_list.append(path)
score_list.append(float(score))
return path_list, score_list
def parse_subjective_score(filename, imgname_col_index = [0], mos_col_index=[3],
std_index = [4]):
"""
reference: JNB and CPBD
func:
parse the xlsx file into the MOS(mean opinion score) and std_score
args:
imgname_col_index:, list of int, refer the col index of image name field
mos_col_index: list of int, refer the col index of MOS field
std_index: list of ints, refer the col index of subjetive score area
return:
list of imgname, MOS and std_value
"""
if std_index == None:
Sub_score_area = range(3,15)
sub_array = pandas.read_excel(filename,sheetname=0, parse_cols = Sub_score_area).values
std_array = np.squeeze(np.std(sub_array,axis=1,ddof=1)).tolist()
else:
Sub_score_area = std_index
std_array = pandas.read_excel(filename, sheetname=0, parse_cols = Sub_score_area).values
std_array = np.squeeze(std_array).tolist()
imgname_list = pandas.read_excel(filename,sheetname=0, parse_cols = imgname_col_index).astype('str').values
imgname_list = np.squeeze(imgname_list).tolist()
mos_array = pandas.read_excel(filename,sheetname=0, parse_cols = mos_col_index).values
mos_array = np.squeeze(mos_array).tolist()
return imgname_list, mos_array, std_array
def get_pair_item(name_obj, score_obj, name_sub):
"""
func:
Select the image score pair, filter the only-one score image item.
return:
the score list of common item
"""
class_dict = {}
for index in range(len(name_obj)):
class_dict[name_obj[index]]=score_obj[index]
filter_obj = []
for item in name_sub:
if item in class_dict:
filter_obj.append(class_dict[item])
return filter_obj
def convert_obj_score(ori_obj_score, MOS):
"""
func:
fitting the objetive score to the MOS scale.
nonlinear regression fit
"""
def logistic_fun(x, a, b, c, d):
return (a - b)/(1 + np.exp(-(x - c)/abs(d))) + b
param_init = [np.max(MOS), np.min(MOS), np.mean(ori_obj_score), 1]
popt, pcov = curve_fit(logistic_fun, ori_obj_score, MOS,
p0 = param_init, ftol =1e-8 , maxfev=2000)
obj_fit_score = logistic_fun(ori_obj_score, popt[0], popt[1], popt[2], popt[3])
return obj_fit_score
def get_outlier(obj_score, sub_score, sub_std):
"""
func: get outlier rate
args:
sub_std[i]:Standard deviation of subjective quality score of the ith image
"""
assert len(sub_score) == len(obj_score)==len(sub_std)
outlier = 0;
for i in range(len(sub_score)):
if (abs(sub_score[i] - obj_score[i]) > 2.0*sub_std[i]):
outlier = outlier + 1;
outlier_rate = 1.0*outlier/(len(sub_score)+1);
return outlier_rate
if __name__=='__main__':
name_sub, score_sub, std_sub = parse_subjective_score(r'SD_IVLMOS.xls')
name_obj, score_obj = parse_objective_score(r'.\jpeg\score.txt',delimiter=' ')
filter_obj = get_pair_item(name_obj, score_obj, name_sub)
fitting_obj = convert_obj_score(filter_obj, score_sub)
pearson_corrcoef = stas.pearsonr(fitting_obj, score_sub)[0]
spearman_corrcoef = stas.spearmanr(filter_obj, score_sub)[0]
kendall_corrcoef = stas.kendalltau(filter_obj, score_sub)[0]
outlier_rate = get_outlier(fitting_obj, score_sub, std_sub)
MSE = np.sqrt(np.mean(np.square(fitting_obj - score_sub)))
print('pearson corrcoef: {}'.format(pearson_corrcoef))
print('spearman corrcoef: {}'.format(spearman_corrcoef))
print('kendall corrcoef: {}'.format(kendall_corrcoef))
print('outlier_rate corrcoef: {}'.format(outlier_rate))
print('Mean Square Error rate: {}'.format(MSE))