Python 中二维离散余弦变换的实现问题
Issiue with implementation of 2D Discrete Cosine Transform in Python
我正在尝试将 Zhao Koch 隐写术方法从 matlab 重写为 python,但我一开始就卡住了。
matlab中的前两个程序:
第 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
但是,当我尝试执行代码时出现以下错误:
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
您的代码工作正常,但它被设计为仅接受二维数组,就像 Matlab 中的 dct2()
一样。因为你的 arr
是一个 3D 数组,所以你想做
D = dct2(arr[...,2])
正如我在评论中提到的,使用 scipy 包中的(快速)内置 dct()
代替或重新发明轮子。
我评论中 link 中的代码有效地为您提供了以下内容:
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 的变换一致。
我正在尝试将 Zhao Koch 隐写术方法从 matlab 重写为 python,但我一开始就卡住了。
matlab中的前两个程序:
第 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
但是,当我尝试执行代码时出现以下错误:
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
您的代码工作正常,但它被设计为仅接受二维数组,就像 Matlab 中的 dct2()
一样。因为你的 arr
是一个 3D 数组,所以你想做
D = dct2(arr[...,2])
正如我在评论中提到的,使用 scipy 包中的(快速)内置 dct()
代替或重新发明轮子。
我评论中 link 中的代码有效地为您提供了以下内容:
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 的变换一致。