IQA客观评价算法与主观平均意见得分相关系数

# -*- coding: utf-8 -*-
"""
常见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() 
    #print(mos_array)
                                     
    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
    """
    # creat the obj name-score dict
    class_dict = {}
    for index in range(len(name_obj)):
        class_dict[name_obj[index]]=score_obj[index]
    
    # filter the obj dict pair based on name_sub
    filter_obj = []
    for item in name_sub:
        if item in class_dict:
            #print(class_dict[item])
            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
    # nolinear fit the MOSp
    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)
    #a, b, c, d = popt[0], popt[1], popt[2], popt[3]
    
    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)
   
    #print(len(obj_score))
    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_subjective_score(r'live_51_MOS.xlsx',mos_col_index=16)
    name_obj, score_obj = parse_objective_score(r'.\jpeg\score.txt',delimiter=' ')
    
    filter_obj = get_pair_item(name_obj, score_obj, name_sub)

                 
    #print(len(filter_obj),len(score_sub))
    fitting_obj = convert_obj_score(filter_obj, score_sub)
                           
    #val_list1, val_list2 = get_pair_array(score_obj + score_sub,name_obj + name_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))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值