Radi_tech’s blog

Radiological technologist in Japan / MRI / AI / Deep learning / MATLAB / R / Python

【Python】画像の類似性指標(PSNR,SSIM, Jaccard係数)を一括処理する


画像の類似性指標(PSNR,SSIM, Jaccard係数)を一括処理する
環境はSpiderを使用
GANで各epoch毎の平均、また全画像の指標、それぞれを求める。

  • モジュールの読み込み
  • メインフォルダの指定
  • 各指標を求める関数を作成
  • 各関数を結合して一つの関数として一括で指標を求める
  • サブフォルダの長さでfor文
  • フォルダパスを作る
  • 内部のファイルをリスト化
  • ファイルの数でfor文
  • 画像ファイルのパス作成
  • Gray scaleで読み込み
  • 各指標を計算
  • 各指標は入れ子をあらかじめ作っておいて、そこへ格納
  • 1枚の画像ごとの指標/1epoch
  • epochごとの指標
  • それぞれをdata frame化してcsvで出力
#%% import module
import pandas as pd
import numpy as np
import pathlib
import cv2
import sys
import os
from skimage.metrics import structural_similarity as ssim

#%% identifiy main folder path

fake_fd_path ="フォルダパスを指定"
real_fd_path = "フォルダパスを指定"

#%% SSIM create function

def SSIM_calc(img1,img2):
    ssim_val = ssim(img1, img2, data_range=img1.max() - img2.min())
    return ssim_val

#%% Jaccard create function
def jaccard(x, y):
    """
    Jaccard index
    Jaccard similarity coefficient
    https://en.wikipedia.org/wiki/Jaccard_index
    """
    x = frozenset(x)
    y = frozenset(y)
    return len(x & y) / float(len(x | y))

#%% DICE create function
def dice(x, y):
    """
    Dice's coefficient
    Sørensen-Dice coefficient
    https://en.wikipedia.org/wiki/Dice%27s_coefficient
    """
    DICE_val = 2 * np.sum(((x==y)&(x==1)&(y==1)) / float(sum(map(len, (x[x==1], y[y==1])))))
    return DICE_val

#%% original function PSNR, SSIM, Jaccard を一括で求める

def similarity (x,y):
    
    PSNR_val = cv2.PSNR(x,y)
    
    SSIM_val = ssim(x, y, data_range=x.max() - y.min())
    
    Jaccard  = len(x & y) / float(len(x | y))
    
    return PSNR_val, SSIM_val, Jaccard


#%%  make list of sub fold 

# avoid ".DS_store"
fake_fd_lst = [fd_nm for fd_nm in os.listdir(fake_fd_path) if not fd_nm.startswith('.')]
real_fd_lst = [fd_nm for fd_nm in os.listdir(real_fd_path) if not fd_nm.startswith('.')]

#%%  流れ
# サブフォルダの長さでfor文>>フォルダパスを作る>>内部のファイルをリスト化>>ファイルの数でfor文>>画像ファイルのパス作成>>Gray scaleで読み込み>>各指標を計算
# 各指標は入れ子をあらかじめ作っておいて、そこへ格納>>1枚の画像ごとの指標/1epoch >>epochごとの指標
# それぞれをdata frame化してcsvで出力

#%% make adn identify save folder for each epoch
save_fd_path_each_epo = "save用のフォルダを指定"


#%% 格納用の箱をつくる
epoch_nm  = []

mean_SSIM = []
mean_PSNR = []
mean_JACC = []

for i in range(len(fake_fd_lst)):
    epoch_nm.append(fake_fd_lst[i])  #epoch名を格納
    # get file lst in each fd
    tmp_fake_fd      = os.path.join(fake_fd_path, fake_fd_lst[i])
    tmp_fake_fl_lst  = [fl_nm for fl_nm in os.listdir(tmp_fake_fd) if not fl_nm.startswith('.')]
    
    
    tmp_real_fd      = os.path.join(real_fd_path, real_fd_lst[i])
    tmp_real_fl_lst  = [fl_nm for fl_nm in os.listdir(tmp_real_fd) if not fl_nm.startswith('.')]
    
    # refresh each value 
    val_PSNR = []
    val_SSIM = []
    val_Jacc = []


    for ii in range(len(tmp_fake_fl_lst)):
        
        if tmp_fake_fl_lst[ii]==tmp_real_fl_lst[ii]:
        
            tmp_fake_img_path = os.path.join(tmp_fake_fd,tmp_fake_fl_lst[ii]) 
            tmp_real_img_path = os.path.join(tmp_real_fd,tmp_real_fl_lst[ii])
            
            # read img data as gray scale
            img_tmp_fake = cv2.imread(tmp_fake_img_path, cv2.IMREAD_GRAYSCALE)
            img_tmp_real = cv2.imread(tmp_real_img_path, cv2.IMREAD_GRAYSCALE)
            
            
            #PSNR using cv2
            tmp_PSNR, tmp_SSIM, tmp_Jacc = similarity (img_tmp_fake,img_tmp_real)
            
            val_PSNR.append(tmp_PSNR)
            val_SSIM.append(tmp_SSIM)
            val_Jacc.append(tmp_Jacc)
            
    #create df
    df_PSNR = pd.DataFrame(val_PSNR,columns=["PSNR"])
    df_SSIM = pd.DataFrame(val_SSIM,columns=["SSIM"])
    df_JACC = pd.DataFrame(val_Jacc,columns=["Jacc"])
    #dataframeの連結
    df_each_epo = pd.concat([df_PSNR, df_SSIM, df_JACC], axis=1)
 
    #save to csv
    df_each_epo.to_csv((save_fd_path_each_epo +"/" + fake_fd_lst[i] + ".csv"))     
         
    # transform list to array
    # use mean function
    ave_PSNR = np.mean(np.array(val_PSNR))
    ave_SSIM = np.mean(np.array(val_SSIM))
    ave_JACC = np.mean(np.array(val_Jacc))
    
    mean_PSNR.append(ave_PSNR)
    mean_SSIM.append(ave_SSIM)
    mean_JACC.append(ave_JACC)
           
            
#create df
df_epoch_nm  = pd.DataFrame(epoch_nm,columns=["epoch"])
df_mean_PSNR = pd.DataFrame(mean_PSNR,columns=["mean_PSNR"])
df_mean_SSIM = pd.DataFrame(mean_SSIM,columns=["mean_SSIM"])
df_mean_JACC = pd.DataFrame(mean_JACC,columns=["mean_Jacc"])           
            

#dataframeの連結
df_summary = pd.concat([df_epoch_nm, df_mean_PSNR, df_mean_SSIM, df_mean_JACC ], axis=1)
df_summary.to_csv((save_fd_path_each_epo +"/#summary.csv"))
            
〜