Pythonによるデータ処理13 ~ ウェーブレット変換6
今回は多段のウェーブレット変換による画像サイズとメモリ削減の効果について検証してみる。
1. 準備
前回までと同様に標準画像データベースのboatを読み込み、変数をgray
とする。さらに型をint16に変換してgray2
とする。
import numpy as np from scipy import signal import matplotlib.pyplot as plt %matplotlib inline import pywt from scipy.sparse import csr_matrix from google.colab import files uploaded_file = files.upload() uploaded_file_name = next(iter(uploaded_file)) orig = cv2.imread(uploaded_file_name) gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY) gray2 = gray.astype(np.int16)
2. 多段の2Dウェーブレット変換
前回まで2Dウェーブレット変換はpywt.idwt2
を使用していた多段の2Dウェーブレット変換の場合はpywt.wavedec2(gray2, 'haar', level=2)
を使用する。引数のlevel
で段数を指定するが今回は2段とする。
coeffs = pywt.wavedec2(gray2, 'haar', level=2) LL = coeffs[0] (LH, HL, HH) = coeffs[1] (LH2, HL2, HH2) = coeffs[2] plt.figure(figsize=(12,5)) plt.subplot(2,4,1) plt.imshow(LL,cmap='gray') plt.subplot(2,4,2) plt.imshow(LH,cmap='gray') plt.subplot(2,4,3) plt.imshow(HL,cmap='gray') plt.subplot(2,4,4) plt.imshow(HH,cmap='gray') plt.subplot(2,4,5) plt.imshow(LH2,cmap='gray') plt.subplot(2,4,6) plt.imshow(HL2,cmap='gray') plt.subplot(2,4,7) plt.imshow(HH2,cmap='gray')
係数の階層も増え、coeffs[0]
はApproximation, coeffs[1]
は高次情報でサイズは64x64になっている。次にcoeffs[2]
も同様の高次情報だがサイズは128x128。ここで画像のベースになるApproximationのサイズが2Dウェーブレット変換では128x128が2段では64x64になっている効果分だけ圧縮率が上がることが期待できる。
前回と同様に高次情報は適当な閾値のマスクをかける。今回は高次情報の行列が増えるため、高次情報の型もfloat64からint16に変換した。
LL2 = LL.astype(np.int16) MLH=(np.abs(LH)>20) MHL=(np.abs(HL)>20) MHH=(np.abs(HH)>20) MLH2=(np.abs(LH2)>20) MHL2=(np.abs(HL2)>20) MHH2=(np.abs(HH2)>20) LHn=LH*MLH HLn=HL*MHL HHn=HH*MHH LH2n=LH2*MLH2 HL2n=HL2*MHL2 HH2n=HH2*MHH2 LHn=LHn.astype(np.int16) HLn=HLn.astype(np.int16) HHn=HHn.astype(np.int16) LH2n=LH2n.astype(np.int16) HL2n=HL2n.astype(np.int16) HH2n=HH2n.astype(np.int16) plt.figure(figsize=(12,5)) plt.subplot(2,4,1) plt.imshow(LL2,cmap='gray') plt.subplot(2,4,2) plt.imshow(LHn,cmap='gray') plt.subplot(2,4,3) plt.imshow(HLn,cmap='gray') plt.subplot(2,4,4) plt.imshow(HHn,cmap='gray') plt.subplot(2,4,5) plt.imshow(LH2n,cmap='gray') plt.subplot(2,4,6) plt.imshow(HL2n,cmap='gray') plt.subplot(2,4,7) plt.imshow(HH2n,cmap='gray')
3. メモリ削減の効果
スパース行列により非ゼロの要素のみを保持したときのサイズ、メモリサイズを前回と同様に算出する。
def get_size_csr(csr): return csr.data.nbytes+csr.indices.nbytes+csr.indptr.nbytes cLH = csr_matrix(LHn) cHL = csr_matrix(HLn) cHH = csr_matrix(HHn) cLH2 = csr_matrix(LH2n) cHL2 = csr_matrix(HL2n) cHH2 = csr_matrix(HH2n) csize=np.size(cLH)+np.size(cHL)+np.size(cHH)+np.size(LL2)+np.size(cLH2)+np.size(cHL2)+np.size(cHH2) print('Original size: ',np.size(gray2)) print('Compressed size: ',csize) print('Original memory: ',gray2.nbytes) sparse_mem = get_size_csr(cLH)+get_size_csr(cHH)+get_size_csr(cHL)+LL2.nbytes+get_size_csr(cLH2)+get_size_csr(cHH2)+get_size_csr(cHL2) print('Compressed memory: ',sparse_mem) >Original size: 65536 >Compressed size: 9215 >Original memory: 131072 >Compressed memory: 41234
元の画像に対しては、要素数で1/6、メモリで1/3程度の圧縮になっている。2Dウェーブレット変換では要素数は18677でメモリは46034 (前回float64の場合71456)なので、要素数で1/2、メモリでは10%減の効果になっている。
3. 多段2D逆ウェーブレット変換による復元
スパース行列をアレイに戻して、多段の逆2Dウェーブレット変換を実行して画像を復元する。多段の逆2Dウェーブレット変換はpywt.waverec2
を用いる。
rLH = cLH.toarray() rHL = cHL.toarray() rHH = cHH.toarray() rLH2 = cLH2.toarray() rHL2 = cHL2.toarray() rHH2 = cHH2.toarray()
recovm2=pywt.waverec2([LL2,(rLH,rHL,rHH),(rLH2,rHL2,rHH2)],'haar') plt.figure(figsize=(14,8)) plt.subplot(1,3,1) plt.imshow(gray2,cmap='gray',vmax=255,vmin=0) plt.title('original') plt.subplot(1,3,2) plt.imshow(LL,cmap='gray') plt.title('Approximation') plt.subplot(1,3,3) plt.imshow(recovm2,cmap='gray',vmax=255,vmin=0) plt.title('Recovered')
画像が復元できていることが確認できる。ベース画像のApproximationと比較すると高次情報によりクリアになっていることがわかる。
128x128の高次情報を省略することができれば、さらにメモリの削減効果が期待できる。とりあえず128x128の高次情報なしで復元すると少し画質が荒くなってしまい、綺麗に再現するには128x128の高次情報が必要になる。
tt=np.zeros([128,128]) recovm3=pywt.waverec2([LL2,(rLH,rHL,rHH),(tt,tt,tt)],'haar') plt.figure(figsize=(10,5)) plt.subplot(1,2,1) plt.imshow(recovm2,cmap='gray',vmax=255,vmin=0) plt.title('Recovered') plt.subplot(1,2,2) plt.imshow(recovm3,cmap='gray',vmax=255,vmin=0) plt.title('Only 1st decomp')
4. まとめ
今回は2段の2Dウェーブレット変換を用いた画像圧縮の効果を確認した。要素数としては削減できるが、2Dウェーブレット変換と比較するとメモリの圧縮効果は小さいことがわかった。