天天看點

壓縮感覺圖像重建品質與JPEG2000(kakadu)的批量比較壓縮感覺JPEG2000處理腳本

本腳本适合于壓縮感覺的研究者,将自己的算法與JPEG2000進行比較,批量得出結果。

具體見我的github:compressed_sensing-batch-JPEG2000-kakadu-PSNR-SSIM

壓縮感覺

壓縮感覺(CS)是一類圖像壓縮重建的算法,其流程為:

壓縮感覺圖像重建品質與JPEG2000(kakadu)的批量比較壓縮感覺JPEG2000處理腳本

編碼後儲存的資料為經過熵編碼的測量值y。

總壓縮倍數R為:

R = c r ∗ 8 b ∗ S R=cr*\frac{8}{b}*S R=cr∗b8​∗S

其中cr為測量率(原圖與測量值的資料數量比例,比如壓縮20倍則cr為20),b為量化比特,S為測量值y的熵編碼倍數。

熵編碼算法主要為算術編碼和霍夫曼編碼,但不同的實作方式效率有所差別,他們的最終目标都是達到香農極限,在這種情況下,壓縮倍數R為:

R ′ = c r ∗ 8 e n t r o p y    o f    y ′ {R}'=cr*\frac{8}{entropy\;of\;{y}'} R′=cr∗entropyofy′8​

其中 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)的批量比較壓縮感覺JPEG2000處理腳本

将本腳本與我的另一篇博文:圖像PSNR和SSIM批量比較,适用于圖像重建

中的腳本相結合,就能友善得對比自己的算法與JPEG2000的效果。

繼續閱讀