欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

压缩感知图像重建质量与JPEG2000(kakadu)的批量比较

程序员文章站 2023-12-31 18:53:28
...

本脚本适合于压缩感知的研究者,将自己的算法与JPEG2000进行比较,批量得出结果。
具体见我的github:compressed_sensing-batch-JPEG2000-kakadu-PSNR-SSIM

压缩感知

压缩感知(CS)是一类图像压缩重建的算法,其流程为:
压缩感知图像重建质量与JPEG2000(kakadu)的批量比较
编码后保存的数据为经过熵编码的测量值y。
总压缩倍数R为:
R=cr8bSR=cr*\frac{8}{b}*S

其中cr为测量率(原图与测量值的数据数量比例,比如压缩20倍则cr为20),b为量化比特,S为测量值y的熵编码倍数。
熵编码算法主要为算术编码和霍夫曼编码,但不同的实现方式效率有所区别,他们的最终目标都是达到香农极限,在这种情况下,压缩倍数R为:
R=cr8entropy  of  y{R}'=cr*\frac{8}{entropy\;of\;{y}'}

其中y{y}'为量化后的测量值。
这是理想的情况,实际达不到这么高的压缩倍数。本脚本采用了这种方式,避免了复杂的熵编码的实现,但是使得效果偏高,需要注意。

JPEG2000

常用的JPEG2000软件是kakadu,其使用方式见我的另一篇博文:kakadu——JPEG2000图像压缩软件的安装和使用
而kakadu只能一张一张得进行压缩和解压,如果需要统计一批图像的数据,就会很麻烦,本脚本解决这个问题。

处理脚本

文件目录:
orig:原图文件夹,以orig_%d.bmp命名。
represent:kakadu得到的压缩文件夹。
recon:kakadu得到的重建图文件夹,以recon_%d.bmp命名。
注:图像格式支持:bmp,jpg,tif,png等常见格式,但orig和recon文件夹内的图像格式必须是同一种。
measurement:自己的算法得出的图像的测量值文件夹,以y_%d.txt命名。

import argparse
import numpy as np
import os
import pandas as pd
import cv2
from skimage.measure import compare_ssim
from skimage.measure import compare_psnr

parser = argparse.ArgumentParser(description='total_cr')
parser.add_argument('--y_path',help='path to y dataset', default='measurements/')
parser.add_argument('--orig_path',help='path to orig image dataset', default='orig/')
parser.add_argument('--represent_path',help='path to represent of kakadu', default='represent/')
parser.add_argument('--recon_path',help='path to recon image dataset', default='recon/')
parser.add_argument('--cr',type=int,default=20)
parser.add_argument('--coe',type=int,default=24)
parser.add_argument('--image_format',help='format of the image', default='bmp')
opt = parser.parse_args()

if not os.path.exists('%s' % (opt.represent_path)):
    os.makedirs('%s' % (opt.represent_path))
if not os.path.exists('%s' % (opt.recon_path)):
    os.makedirs('%s' % (opt.recon_path))

def calc_ent(x):
    x_value_list = set([x[i] for i in range(x.shape[0])])
    ent = 0.0
    for x_value in x_value_list:
        p = float(x[x == x_value].shape[0]) / x.shape[0]
        logp = np.log2(p)
        ent -= p * logp
    return ent

num_files = 0
for fn in os.listdir(opt.y_path):
    num_files += 1

y_number = []
total_cr_number = []
bpp_number = []
psnr_number = []
ssim_number = []
for idx in range(num_files):
    locals()['total_cr_'+str(idx)+''] = opt.cr * 8 / calc_ent(np.loadtxt('%s/y_%d.txt' %(opt.y_path,idx),dtype='int'))
    locals()['bpp_'+str(idx)+''] = opt.coe / locals()['total_cr_'+str(idx)+'']
    os.system('./kdu_compress -i %s/orig_%d.%s -o %s/out_%d.j2c -rate %.5f' %(opt.orig_path,idx,opt.image_format,opt.represent_path,idx,locals()['bpp_'+str(idx)+'']))

    y_number.append(str(idx))
    total_cr_number.append(locals()['total_cr_'+str(idx)+''])
    bpp_number.append(locals()['bpp_'+str(idx)+''])

for idx in range(num_files):
    os.system('./kdu_expand -i %s/out_%d.j2c -o %s/recon_%d.%s' %(opt.represent_path,idx,opt.recon_path,idx,opt.image_format))

for idx in range(num_files):
    locals()['orig_'+str(idx)+''] = cv2.imread('%s/orig_%d.%s' %(opt.orig_path,idx,opt.image_format))
    locals()['recon_'+str(idx)+''] = cv2.imread('%s/recon_%d.%s' %(opt.recon_path,idx,opt.image_format))
    locals()['psnr_'+str(idx)+''] = compare_psnr(locals()['orig_'+str(idx)+''],locals()['recon_'+str(idx)+''])
    locals()['ssim_'+str(idx)+''] = compare_ssim(locals()['orig_'+str(idx)+''],locals()['recon_'+str(idx)+''],multichannel=True)

    psnr_number.append(locals()['psnr_'+str(idx)+''])
    ssim_number.append(locals()['ssim_'+str(idx)+''])

dit = {'y_number':y_number, 'total_cr':total_cr_number,'bpp':bpp_number,'psnr':psnr_number,'ssim':ssim_number}
df = pd.DataFrame(dit)
df.to_csv(r'./JPEG2000_result.csv',columns=['y_number','total_cr','bpp','psnr','ssim'],index=False,sep=',')

生成汇总表格JPEG20000_results.csv:
压缩感知图像重建质量与JPEG2000(kakadu)的批量比较
将本脚本与我的另一篇博文:图像PSNR和SSIM批量比较,适用于图像重建
中的脚本相结合,就能方便得对比自己的算法与JPEG2000的效果。

上一篇:

下一篇: