项目地址:https://github.com/Alexkkir/pyiqa-sal/tree/main
这是一个纯python和pytorch编写的图像质量评估工具箱,提供了许多主流全参考(FR)和无参考(NR)指标的重新实现(如果有的话,结果会用官方matlab脚本校准)。借助GPU加速,我们的大多数实现都比Matlab快得多。同时也比torch实现的方法在调用上更加方便。

1、基本简介
1.1 安装库
安装代码
# Install with pip
pip install pyiqa
# Install latest github version
pip uninstall pyiqa # if have older version installed already 
pip install git+https://github.com/chaofengc/IQA-PyTorch.git
# Install with git clone
git clone https://github.com/chaofengc/IQA-PyTorch.git
cd IQA-PyTorch
pip install -r requirements.txt
python setup.py develop
1.2 使用案例
基本使用案例
import pyiqa
import torch
# list all available metrics
print(pyiqa.list_models())
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
# create metric with default setting
iqa_metric = pyiqa.create_metric('lpips', device=device)
# Note that gradient propagation is disabled by default. set as_loss=True to enable it as a loss function.
iqa_loss = pyiqa.create_metric('lpips', device=device, as_loss=True)
# create metric with custom setting
iqa_metric = pyiqa.create_metric('psnr', test_y_channel=True, color_space='ycbcr').to(device)
# check if lower better or higher better
print(iqa_metric.lower_better)
# example for iqa score inference
# Tensor inputs, img_tensor_x/y: (N, 3, H, W), RGB, 0 ~ 1
score_fr = iqa_metric(img_tensor_x, img_tensor_y)
score_nr = iqa_metric(img_tensor_x)
# img path as inputs.
score_fr = iqa_metric('./ResultsCalibra/dist_dir/I03.bmp', './ResultsCalibra/ref_dir/I03.bmp')
# For FID metric, use directory or precomputed statistics as inputs
# refer to clean-fid for more details: https://github.com/GaParmar/clean-fid
fid_metric = pyiqa.create_metric('fid')
score = fid_metric('./ResultsCalibra/dist_dir/', './ResultsCalibra/ref_dir')
score = fid_metric('./ResultsCalibra/dist_dir/', dataset_name="FFHQ", dataset_res=1024, dataset_split="trainval70k")
1.3 一次性评价多个指标
代码地址:https://github.com/wyf0912/SinSR/blob/main/evaluate.py
 所依赖的 utils库地址为:https://github.com/wyf0912/SinSR/tree/main/utils
import pyiqa
import os
import argparse
from pathlib import Path
import torch
from utils import util_image
import tqdm
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
def evaluate(in_path, ref_path, ntest):
    metric_dict = {}
    metric_dict["clipiqa"] = pyiqa.create_metric('clipiqa').to(device)
    metric_dict["musiq"] = pyiqa.create_metric('musiq').to(device)
    metric_paired_dict = {}
    
    in_path = Path(in_path) if not isinstance(in_path, Path) else in_path
    assert in_path.is_dir()
    
    ref_path_list = None
    if ref_path is not None:
        ref_path = Path(ref_path) if not isinstance(ref_path, Path) else ref_path
        ref_path_list = sorted([x for x in ref_path.glob("*.[jpJP][pnPN]*[gG]")])
        if ntest is not None: ref_path_list = ref_path_list[:ntest]
        
        metric_paired_dict["psnr"]=pyiqa.create_metric('psnr', test_y_channel=True, color_space='ycbcr').to(device)
        metric_paired_dict["lpips"]=pyiqa.create_metric('lpips').to(device)
        metric_paired_dict["ssim"]=pyiqa.create_metric('ssim', test_y_channel=True, color_space='ycbcr' ).to(device)
        
    lr_path_list = sorted([x for x in in_path.glob("*.[jpJP][pnPN]*[gG]")])
    if ntest is not None: lr_path_list = lr_path_list[:ntest]
    
    print(f'Find {len(lr_path_list)} images in {in_path}')
    result = {}
    for i in tqdm.tqdm(range(len(lr_path_list))):
        in_path = lr_path_list[i]
        ref_path = ref_path_list[i] if ref_path_list is not None else None
        
        im_in = util_image.imread(in_path, chn='rgb', dtype='float32')  # h x w x c
        im_in_tensor = util_image.img2tensor(im_in).cuda()              # 1 x c x h x w
        for key, metric in metric_dict.items():
            with torch.cuda.amp.autocast():
                result[key] = result.get(key, 0) + metric(im_in_tensor).item()
        
        if ref_path is not None:
            im_ref = util_image.imread(ref_path, chn='rgb', dtype='float32')  # h x w x c
            im_ref_tensor = util_image.img2tensor(im_ref).cuda()    
            for key, metric in metric_paired_dict.items():
                result[key] = result.get(key, 0) + metric(im_in_tensor, im_ref_tensor).item()
                
    for key, res in result.items():
        print(f"{key}: {res/len(lr_path_list):.5f}")
        
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-i',"--in_path", type=str, required=True)
    parser.add_argument("-r", "--ref_path", type=str, default=None)
    parser.add_argument("--ntest", type=int, default=None)
    args = parser.parse_args()
    evaluate(args.in_path, args.ref_path, args.ntest)
    
1.4 使用脚本
# example for FR metric with dirs
python inference_iqa.py -m LPIPS[or lpips] -i ./ResultsCalibra/dist_dir[dist_img] -r ./ResultsCalibra/ref_dir[ref_img]
# example for NR metric with single image
python inference_iqa.py -m brisque -i ./ResultsCalibra/dist_dir/I03.bmp
2、评价方法
2.1 有参考评价方法
AHIQ ✅、PieAPP ✅、LPIPS ✅、DISTS ✅、WaDIQaM ✅、CKDN1 ✅、FSIM ✅、SSIM ✅、MS-SSIM ✅、CW-SSIM ✅、PSNR ✅、VIF ✅、GMSD ✅、NLPD ✅、VSI ✅、MAD ✅
2.2 无参考评价方法
FID ✖️、CLIPIQA(+) ✅、MANIQA ✅、MUSIQ ✅、DBCNN ✅、PaQ-2-PiQ ✅、HyperIQA ✅、NIMA ✅、WaDIQaM ✅、CNNIQA ✅、NRQM(Ma)2 ✖️、PI(Perceptual Index) ✖️、BRISQUE ✅、ILNIQE ✅、NIQE ✅
2.3 指标对应的论文
无参考评价方法比较多,建议使用2020年以后提出的指标
| model | lower better ? | min | max | DATE | Link | 
|---|---|---|---|---|---|
| clipiqa | False | 0 | 1 | 2022 | https://arxiv.org/abs/2207.12396 | 
| maniqa | False | 0 | 2022 | https://arxiv.org/abs/2204.08958 | |
| hyperiqa | False | 0 | 1 | 2020 | |
| cnniqa | False | 2014 | |||
| tres | False | 2022 | https://github.com/isalirezag/TReS | ||
| musiq | False | ~0 | ~100 | 2021 | https://arxiv.org/abs/2108.05997 | 
| musiq-ava | False | ~0 | ~10 | 2021 | https://arxiv.org/abs/2108.05997 | 
| musiq-koniq | False | ~0 | ~100 | 2021 | https://arxiv.org/abs/2108.05997 | 
| paq2piq | False | 2020 | |||
| dbcnn | False | 2019 | https://arxiv.org/bas/1907.02665 | ||
| brisque | True | 2012 | |||
| pi | True | 2018 | https://arxiv.org/abs/1809.07517 | ||
| nima | False | 2018 | https://arxiv.org/abs/1709.05424 | ||
| nrqm | False | 2016 | https://arxiv.org/abs/1612.05890 | ||
| ilniqe | True | 0 | 2015 | ||
| niqe | True | 0 | 2012 | 



















