2016-10-18 31 views
0

私はZhao Kochステガノグラフィの方法をmatlabからPythonに書き直そうとしています。Pythonで2D離散コサイン変換を実装したIssiue

それらはMATLABであるように最初の2つの手順が:

ステップ1:

A = imread(casepath); # Reading stegonography case image and aquiring it's RGB values. In my case it's a 400x400 PNG image, so it gives a 400x400x3 array. 

ステップ2:

D = dct2(A(:,:,3)); # Applying 2D DCT to blue values of the image 

Pythonコードアナログ:

from scipy import misc 
from numpy import empty,arange,exp,real,imag,pi 
from numpy.fft import rfft,irfft 

arr = misc.imread('casepath')# 400x480x3 array (Step 1) 
arr[20, 30, 2] # Getting blue pixel value 

def dct(y): #Basic DCT build from numpy 
    N = len(y) 
    y2 = empty(2*N,float) 
    y2[:N] = y[:] 
    y2[N:] = y[::-1] 

    c = rfft(y2) 
    phi = exp(-1j*pi*arange(N)/(2*N)) 
    return real(phi*c[:N]) 


def dct2(y): #2D DCT bulid from numpy and using prvious DCT function 
    M = y.shape[0] 
    N = y.shape[1] 
    a = empty([M,N],float) 
    b = empty([M,N],float) 

    for i in range(M): 
     a[i,:] = dct(y[i,:]) 
    for j in range(N): 
     b[:,j] = dct(a[:,j]) 

    return b 

D = dct2(arr) # step 2 anlogue 

しかし、私はexecuしようとすると私は次のエラーが表示されます:

Traceback (most recent call last): 
File "path to .py file", line 31, in <module> 
D = dct2(arr) 
File "path to .py file", line 25, in dct2 
a[i,:] = dct(y[i,:]) 
File "path to .py file", line 10, in dct 
y2[:N] = y[:] 
ValueError: could not broadcast input array from shape (400,3) into shape (400) 

おそらく誰かが私に間違っていることを説明することができましたか?

追加情報: OS:Windowsの10プロ64ビット のPython:2.7.12 scipyのダウンロード:0.18.1 numpyの:1.11.2 枕:3.4.1

+1

numpyとscipyから、['dct()'](http://stackoverflow.com/questions/34890585/in-scipy-why-doesnt-idctdcta-equal-to-a)に直接アクセスできます。あなたは自分自身を動かすことに興味はありますか? – Reti43

+0

ありがとう、ちょうどそれを試したことを知らなかった。それはうまく動作するようだ。 –

答えて

1

あなたのコードは正常に動作しますが、それMatlabのdct2()のように、2D配列のみを受け入れるように設計されています。あなたのarrが3D配列であるので、あなたは私のコメントで述べたように

D = dct2(arr[...,2]) 

をしたい、代わりにまたは車輪の再発明、ビルトインdct() scipyのダウンロードパッケージから(高速)を使用します。

私のコメント内のリンクからコードが効果的にあなたを提供し、この:

import numpy as np 
from scipy.fftpack import dct, idct 

def dct2(block): 
    return dct(dct(block.T, norm='ortho').T, norm='ortho') 

def idct2(block): 
    return idct(idct(block.T, norm='ortho').T, norm='ortho') 

しかし、再び、私はあなたが個別に各色平面のため、この関数を呼び出す必要がありことを強調しなければなりません。 Scipyのdct()は任意のN次元配列をうまく受け入れ、最後の軸に変換を適用します。これはカラープレーンであり、ピクセルの行と列ではないため、間違った結果が得られます。はい、axis入力パラメータでこれを解決する方法がありますが、この回答を不必要に過度に複雑化することはありません。ここに関与する様々なDCT実装について


あなたは上記のスニペットからnorm='ortho'パラメータを省略した場合は、ご使​​用のバージョンとscipyのダウンロードの実装では、同じ結果を与えます。しかし、そのパラメータを含めると、scipyの変換はMatlabのものと一致します。

関連する問題