Python scipy 图像上较小块的 DCT 不起作用
Python scipy DCT on smaller block on image not working
我将 scipy.fftpack.dct 和 scipy.fftpack.idct 用于 python 中的图像数组。然而,我不想将它应用于整个图像,而是应用于图像中的单个 8x8 块。这是我写给测试这个
的简单class
from PIL import Image
import numpy as np
from scipy.fftpack import dct, idct
class ImageController():
def __init__(self, image_name):
im = np.asarray(Image.open(image_name))
self.origional_size = im.shape
im_x_dim, im_y_dim = self.origional_size
self.image = im
if not self.image.flags.writeable:
self.image.flags.writeable = True
def get(self):
return self.image
def display(self):
Image.fromarray(self.image).show()
return self
def apply_dct(self):
# self.image = dct(self.image, norm='ortho')
self.loop_through_8_x_8(dct)
return self
def apply_idct(self):
# self.image = idct(self.image, norm='ortho')
self.loop_through_8_x_8(idct)
return self
def loop_through_8_x_8(self, appyFunc):
print appyFunc
row = 0
while row < len(self.image):
col = 0
while col < len(self.image[row]):
self.image[row:row+8, self.get_list(col)] = appyFunc(self.image[row:row+8, self.get_list(col)] , norm='ortho')
col += 8
row += 8
print row, col
return self;
def get_list(self, index):
x = []
for i in range(index, index + 8):
x.append(i)
return x
我遇到的问题是,当我将 DCT 应用于 8x8 块时,然后立即进行 IDCT,所有信息都丢失了,图像看起来一团糟。我只打电话
ImageController('lena.jpg').apply_dct().apply_idct().display()
当我运行这个的时候,图像都是噪点。但是,如果您在 apply_dct() 和 apply_idct() 中看到我有一些注释掉了,那是我在整个图像上而不是在 8x8 块上尝试 DCT 和 IDCT 的地方。当我这样做时它完美地工作,当我尝试 8x8 块时它不起作用,我需要将它应用于 8x8 块而不是整个图像。
如有需要,请提供额外信息,图像为灰度,因此只有 1 个通道。
检查图像数组的数据类型 (self.image.dtype
)。它可能是 8 位无符号整数。 DCT 将是浮点值,但是当您将 DCT 的结果分配给 8x8 块 in place 时,浮点值将转换为 8 位整数。当你应用 IDCT 时,同样的事情会发生。
避免此问题的一种方法是在 __init__()
中将图像转换为 64 位浮点数,例如 im = np.asarray(Image.open(image_name), dtype=np.float64)
。这是否有意义取决于您要对数组执行的其他操作。
我将 scipy.fftpack.dct 和 scipy.fftpack.idct 用于 python 中的图像数组。然而,我不想将它应用于整个图像,而是应用于图像中的单个 8x8 块。这是我写给测试这个
的简单classfrom PIL import Image
import numpy as np
from scipy.fftpack import dct, idct
class ImageController():
def __init__(self, image_name):
im = np.asarray(Image.open(image_name))
self.origional_size = im.shape
im_x_dim, im_y_dim = self.origional_size
self.image = im
if not self.image.flags.writeable:
self.image.flags.writeable = True
def get(self):
return self.image
def display(self):
Image.fromarray(self.image).show()
return self
def apply_dct(self):
# self.image = dct(self.image, norm='ortho')
self.loop_through_8_x_8(dct)
return self
def apply_idct(self):
# self.image = idct(self.image, norm='ortho')
self.loop_through_8_x_8(idct)
return self
def loop_through_8_x_8(self, appyFunc):
print appyFunc
row = 0
while row < len(self.image):
col = 0
while col < len(self.image[row]):
self.image[row:row+8, self.get_list(col)] = appyFunc(self.image[row:row+8, self.get_list(col)] , norm='ortho')
col += 8
row += 8
print row, col
return self;
def get_list(self, index):
x = []
for i in range(index, index + 8):
x.append(i)
return x
我遇到的问题是,当我将 DCT 应用于 8x8 块时,然后立即进行 IDCT,所有信息都丢失了,图像看起来一团糟。我只打电话
ImageController('lena.jpg').apply_dct().apply_idct().display()
当我运行这个的时候,图像都是噪点。但是,如果您在 apply_dct() 和 apply_idct() 中看到我有一些注释掉了,那是我在整个图像上而不是在 8x8 块上尝试 DCT 和 IDCT 的地方。当我这样做时它完美地工作,当我尝试 8x8 块时它不起作用,我需要将它应用于 8x8 块而不是整个图像。
如有需要,请提供额外信息,图像为灰度,因此只有 1 个通道。
检查图像数组的数据类型 (self.image.dtype
)。它可能是 8 位无符号整数。 DCT 将是浮点值,但是当您将 DCT 的结果分配给 8x8 块 in place 时,浮点值将转换为 8 位整数。当你应用 IDCT 时,同样的事情会发生。
避免此问题的一种方法是在 __init__()
中将图像转换为 64 位浮点数,例如 im = np.asarray(Image.open(image_name), dtype=np.float64)
。这是否有意义取决于您要对数组执行的其他操作。