栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python写Bicubic方法,跑数据集Set5和Set14,保存PSNR和SSIM的值

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python写Bicubic方法,跑数据集Set5和Set14,保存PSNR和SSIM的值

作业描述:python写Bicubic方法,跑数据集Set5和Set14,两个数据集都把放到倍数×2,×3,×4,×8跑一遍,最后把图像质量评估指标 PSNR 和 SSIM 保存在表格里面。

实现思路:

  1. 实现Bicubic方法,通过循环将数据集Set5 和 Set14 进行放大。
  2. 使用opencv 中的 resize()将放大后的图像进行缩放,缩放到与源图像大小一致
  3. 使用 PSNR 和 SSIM 对原图像和放大的图像进行图像质量评估
  4. 利用list将结果保存到excel表中

目录
  • 1. Bicubic(双三次插值)对图像进行缩放
  • 2. 使用cv2 中的 resize() 将放大的图片进行缩放
  • 3. 图像质量评估指标:PSNR和SSIM
  • 4. 将运行后生成的psnr和ssim的值进行保存,生成excel表

1. Bicubic(双三次插值)对图像进行缩放

双三次插值法数学原理参照这里:算法原理链接

代码为总结 前人的代码 进行改进:

from PIL import Image
import numpy as np
import math
import os
"""
作业:用python写Bicubic方法保存PSNR和SSIM,跑数据集Set5和Set14,两个数据集都把放到倍数×2,×3,×4,×8跑一遍,
     最后把PSNR和SSIM保存在表格里面。这个作业完成时间6.26 晚上12:00前。
Bicubic是双三插值法
"""
# 产生16个像素点不同的权重
def BiBubic(x):
    # 根据参考的公式 S(x) ,将其转换成代码样式
    x = abs(x)
    if x <= 1:
        return 1-2*(x**2)+(x**3)
    elif x < 2:
        return 4-8*x+5*(x**2)-(x**3)
    else:
        return 0

# 双三次插值算法
# dstH为目标图像的高,dstW为目标图像的宽
def BiCubic_interpolation(img, dstH, dstW):
    scrH, scrW, _= img.shape
    retimg = np.zeros((dstH, dstW, 3), dtype=np.uint8)
    for i in range(dstH):
        for j in range(dstW):
            scrx = i*(scrH/dstH)
            scry = j*(scrW/dstW)
            x = math.floor(scrx)    # floor向下取整
            y = math.floor(scry)
            u = scrx-x
            v = scry-y
            tmp = 0
            for ii in range(-1, 2):
                for jj in range(-1, 2):
                    if x+ii < 0 or y+jj < 0 or x+ii >= scrH or y+jj >= scrW:
                        continue
                    tmp += img[x+ii, y+jj] * BiBubic(ii-u) * BiBubic(jj-v)
            retimg[i, j] = np.clip(tmp, 0, 255)
    return retimg


if __name__ == '__main__':
    times = [2, 3, 4, 8]
    """ 
    	此处可以封装成函数,鉴于自己使用,就偷懒了
        Set5
    """
    im_path = r"./input/Set5/"
    out_path = r'./output/Set5/'  #事先建立好文件夹
    files = os.listdir(im_path)
    for i in times:
        for spl_file in files:
            file_name = spl_file.strip('./input/Set5,.')
            print('bicl:', file_name)
            image = np.array((Image.open(im_path + spl_file)))
            image3 = BiCubic_interpolation(image, image.shape[0] * i, image.shape[1] * i)    # i 为放大倍数
            # 因为图片在imread过程中,cv2读取的结果图片形式为BRG 需要转化RGB
            image3 = Image.fromarray(image3.astype('uint8')).convert('RGB')
            image3.save(out_path + file_name + '_' + str(i) + '.png')
    """ 
        Set14
    """
    im_path = r"./input/Set14/"
    out_path = r'./output/Set14/'  #事先建立好文件夹
    files = os.listdir(im_path)
    for i in times:
        for spl_file in files:
            file_name = spl_file.strip('./input/Set14,.')
            print('bicl:', file_name)
            image = np.array((Image.open(im_path + spl_file)))
            image4 = BiCubic_interpolation(image, image.shape[0] * i, image.shape[1] * i)    # i为放大倍数
            # 因为图片在imread过程中,cv2读取的结果图片形式为BRG 需要转化RGB
            image4 = Image.fromarray(image4.astype('uint8')).convert('RGB')
            image4.save(out_path + file_name + '_' + str(i) + '.png')

使用时,注意路径和 输出的 图片格式。

2. 使用cv2 中的 resize() 将放大的图片进行缩放

为什么要做这一步?

因为在使用PSNR进行评估时所传入的image1和image2需要保持大小一致,不然会报错。

代码中,size_2,size_1为原图像的尺寸,使用时需要更改路径。

如果电脑未安装cv2,在cmd中执行以下语句即可安装(等待时间有点儿长):

pip --default-timeout=500 install -U opencv-contrib-python
import cv2
import os

if __name__ == '__main__':
    #path = './input/Set14/'
    #tar_path = './output/Set14/'
    path = './input/Set5/'
    tar_path = './output/Set5/'
    folders = os.listdir(path)
    print(folders)
    nums = [2, 3, 4, 8]
    for folder in folders:
        folder_path = os.path.join(path, folder)
        # print(folder_path)
        img = cv2.imread(folder_path)
        size_1 = img.shape[0]
        size_2 = img.shape[1]
        for i in nums:
            out_img = folder + '_' + str(i) + '.png'
            folder_tar_path = os.path.join(tar_path, out_img)
            print(i)
            print(folder_tar_path)
            tar_img = cv2.imread(folder_tar_path)
            resize = cv2.resize(tar_img, (size_2, size_1), interpolation=cv2.INTER_CUBIC)  # 定尺寸的缩放
            print(resize.shape)
            # cv2.imwrite(r'./SetOfScale/Set14/'+ out_img, resize)
            cv2.imwrite(r'./SetOfScale/Set5/' + out_img, resize)

缩放完成后,我们就得到了经过双三次插值法放大的图片与原图片一样大小的图片。
接下来就对图片进行比对,得出PSNR和SSIM的值。

3. 图像质量评估指标:PSNR和SSIM

图像质量评估 PSNR 和 SSIM 原理 参照此文章

代码实现主要使用了 skimage库,代码实现参考了这篇文章

实现中参杂着 将数据保存到excel中的代码,使用的是 xlwt库

import xlwt     # excel表
import numpy as np
import skimage.io as io
from skimage.metrics import peak_signal_noise_ratio # PSNR
from skimage.metrics import structural_similarity   # SSIM
from skimage.color import rgb2ycbcr                 # RGB三通道使用
import os

# 单通道    img.dtype 为 uint8 范围0-255
def Dan_PSNR_and_SSIM(path, tar_path):
    folders = os.listdir(path)
    nums = [2, 3, 4, 8]
    results = []
    print(folders)
    for folder in folders:
        folder_path = os.path.join(path, folder)
        img = io.imread(folder_path)[..., 0]
        for i in nums:
            out_img = folder + '_' + str(i) + '.png'
            folder_tar_path = os.path.join(tar_path, out_img)
            tar_img = io.imread(folder_tar_path)[..., 0]
            psnr_val = peak_signal_noise_ratio(img, tar_img)
            ssim_val = structural_similarity(img, tar_img)
            re = [folder, out_img, psnr_val, ssim_val]
            results.append(re)
    return results

# RGB 三通道  img.dtype 为 float64 需要归一化到 0-1.0
def RGB_PSNR_and_SSIM(path, tar_path):
    folders = os.listdir(path)
    nums = [2, 3, 4, 8]
    results = []
    print(folders)
    # rgb2ycbcr的输入需要归一化到0-1.0的float
    # 这个在上一篇blog中讲过了rgb2ycbcr输出为浮点型且范围是0-255.0 所以需要再次归一化0-1
    for folder in folders:
        folder_path = os.path.join(path, folder)
        img = io.imread(folder_path)
        img = img/255.0
        img = rgb2ycbcr(img)[:, :, 0:1]
        img = img/255.0
        for i in nums:
            out_img = folder + '_' + str(i) + '.png'
            folder_tar_path = os.path.join(tar_path, out_img)
            tar_img = io.imread(folder_tar_path)
            tar_img = tar_img / 255.0
            tar_img = rgb2ycbcr(tar_img)[:, :, 0:1]
            tar_img = tar_img / 255.0
            psnr_val = peak_signal_noise_ratio(img, tar_img)
            ssim_val = structural_similarity(img, tar_img,win_size=11,gaussian_weights=True,multichannel=True,data_range=1.0,K1=0.01,K2=0.03,sigma=1.5)
            re = [folder, out_img, psnr_val, ssim_val]
            results.append(re)
    return results

4. 将运行后生成的psnr和ssim的值进行保存,生成excel表

main方法,接上面代码。

def save_excel(col, set5_dan, set5_RGB, set14_dan, set14_RGB):
    # 创建excel表格
    book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    # 奖励一张sheet表单
    sheet1 = book.add_sheet('Set5_单通道', cell_overwrite_ok=True)
    sheet2 = book.add_sheet('Set5_RGB三通道', cell_overwrite_ok=True)
    sheet3 = book.add_sheet('Set14_单通道', cell_overwrite_ok=True)
    sheet4 = book.add_sheet('Set14_RGB三通道', cell_overwrite_ok=True)
    # 将列属性元组col写进 sheet表单中
    for i in range(len(col)):
        sheet1.write(0, i, col[i])  # 参数:行、列、col元组值
        sheet2.write(0, i, col[i])  
        sheet3.write(0, i, col[i]) 
        sheet4.write(0, i, col[i])  
    # 写数据
    # sheet1
    for i in range(len(set5_dan)):
        data = set5_dan[i]
        for j in range(len(set5_dan[0])):
            sheet1.write(i + 1, j, data[j])
    # sheet2
    for i in range(len(set5_RGB)):
        data = set5_RGB[i]
        for j in range(len(set5_RGB[0])):
            sheet2.write(i + 1, j, data[j])
    # sheet3
    for i in range(len(set14_dan)):
        data = set14_dan[i]
        for j in range(len(set14_dan[0])):
            sheet3.write(i + 1, j, data[j])
    # sheet4
    for i in range(len(set14_RGB)):
        data = set14_RGB[i]
        for j in range(len(set14_RGB[0])):
            sheet4.write(i + 1, j, data[j])
    # 保存
    savepath = './excel表格.xls'
    book.save(savepath)

if __name__ == '__main__':

    """ 循环遍历出 每个缩放后的图片的 与原图片的 PSNR 和 SSIM 值,并保存到excel中"""
    path = './input/Set5/'
    tar_path = './SetOfScale/Set5/'

    # 单通道
    Set5_dan = Dan_PSNR_and_SSIM(path,tar_path)
    print("Set5_dann",Set5_dan)
    Set14_dan = Dan_PSNR_and_SSIM('./input/Set14', './SetOfScale/Set14/')
    print("Set14_dann",Set14_dan)
    # RGB三通道
    Set5_RGB= RGB_PSNR_and_SSIM(path,tar_path)
    print("Set5_RGBn",Set5_RGB)
    Set14_RGB = RGB_PSNR_and_SSIM('./input/Set14', './SetOfScale/Set14/')
    print("Set14_RGBn",Set14_RGB)

    # 自定义列名
    col = ('原图片', '放大图片', 'PSNR值', 'SSIM值')
    save_excel(col, Set5_dan, Set5_RGB, Set14_dan, Set14_RGB)

生成的excel表格如图:


set14数据集中,baboon.png 原图

双三次插值法 放大2倍图像:

双三次插值法放大 3倍图像:

通过对比,可以明显的看出,放大倍数越大,照片表面的像素颗粒越明显,看着就像生活中的刺绣一样。

本次的作业中,对于Bicubic方法的原理,以及使用的PSNR和SSIM评估方法公式的理解不够,下来再继续努力 --20220626

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/994447.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号