python语句现实下列功能1、循环将后缀为.b m p灰度图像分割成8X8的小块, 2、并对每个像素值减去128 3、对每个小块进行DCT正向变换其中每个小块的第一个系数为直流系数,其余63个系数为交流系数 4、使用量化矩阵对每个小块进行量化。 5、对量化后的小块进行Z字形重排序编码 6、将编码后的数据保存为abc.my 7、对编码后的数据进行解码反Z字形排序 8、对解码后的小块进行反量化,可以使用量化矩阵实现。 9、对反量化后的小块进行IDCT反向变换, 10、使用循环将反变换后的小块合并成原始图像。 11、最后计算PSNR要大于30 要求详细的代码注释
时间: 2023-03-30 20:03:34 浏览: 109
以下是 Python 代码,实现了上述功能,注释详细:
```python
import numpy as np
from PIL import Image
# 定义量化矩阵
Q = np.array([[16, 11, 10, 16, 24, 40, 51, 61],
[12, 12, 14, 19, 26, 58, 60, 55],
[14, 13, 16, 24, 40, 57, 69, 56],
[14, 17, 22, 29, 51, 87, 80, 62],
[18, 22, 37, 56, 68, 109, 103, 77],
[24, 35, 55, 64, 81, 104, 113, 92],
[49, 64, 78, 87, 103, 121, 120, 101],
[72, 92, 95, 98, 112, 100, 103, 99]])
# 定义 Z 字形重排序的顺序
order = np.array([[, 1, 5, 6, 14, 15, 27, 28],
[2, 4, 7, 13, 16, 26, 29, 42],
[3, 8, 12, 17, 25, 30, 41, 43],
[9, 11, 18, 24, 31, 40, 44, 53],
[10, 19, 23, 32, 39, 45, 52, 54],
[20, 22, 33, 38, 46, 51, 55, 60],
[21, 34, 37, 47, 50, 56, 59, 61],
[35, 36, 48, 49, 57, 58, 62, 63]])
# 定义 DCT 变换矩阵
def dct_matrix(N):
dct_mat = np.zeros((N, N))
for i in range(N):
for j in range(N):
if i == :
dct_mat[i][j] = np.sqrt(1/N)
else:
dct_mat[i][j] = np.sqrt(2/N) * np.cos((2*j+1)*i*np.pi/(2*N))
return dct_mat
# 定义 IDCT 变换矩阵
def idct_matrix(N):
idct_mat = np.zeros((N, N))
for i in range(N):
for j in range(N):
if i == :
idct_mat[i][j] = np.sqrt(1/N)
else:
idct_mat[i][j] = np.sqrt(2/N) * np.cos((2*i+1)*j*np.pi/(2*N))
return idct_mat
# 定义 Z 字形重排序函数
def zigzag_reorder(block):
return np.array([block[order[i][j]//8][order[i][j]%8] for i in range(8) for j in range(8)])
# 定义反 Z 字形重排序函数
def zigzag_restore(block):
restore = np.zeros((8, 8))
for i in range(8):
for j in range(8):
restore[order[i][j]//8][order[i][j]%8] = block[i*8+j]
return restore
# 定义量化函数
def quantize(block):
return np.round(block / Q)
# 定义反量化函数
def dequantize(block):
return block * Q
# 定义计算 PSNR 的函数
def psnr(img1, img2):
mse = np.mean((img1 - img2) ** 2)
if mse == :
return 100
PIXEL_MAX = 255.
return 20 * np.log10(PIXEL_MAX / np.sqrt(mse))
# 读取图像并转换为灰度图像
img = Image.open('test.bmp').convert('L')
width, height = img.size
# 循环将图像分割成 8x8 的小块,并对每个像素值减去 128
blocks = []
for i in range(, height, 8):
for j in range(, width, 8):
block = np.array(img.crop((j, i, j+8, i+8))) - 128
blocks.append(block)
# 对每个小块进行 DCT 正向变换,并量化
dct_mat = dct_matrix(8)
quantized_blocks = []
for block in blocks:
dct = np.dot(np.dot(dct_mat, block), dct_mat.T)
quantized = quantize(dct)
quantized_blocks.append(quantized)
# 对量化后的小块进行 Z 字形重排序并编码保存
encoded = []
for block in quantized_blocks:
reordered = zigzag_reorder(block)
encoded.extend(reordered)
encoded = np.array(encoded, dtype=np.int16)
encoded.tofile('abc.my')
# 读取编码后的数据并解码反 Z 字形重排序
encoded = np.fromfile('abc.my', dtype=np.int16)
decoded_blocks = []
for i in range(, len(encoded), 64):
block = encoded[i:i+64]
restored = zigzag_restore(block)
decoded_blocks.append(restored)
# 对解码后的小块进行反量化和 IDCT 反向变换
idct_mat = idct_matrix(8)
restored_img = np.zeros((height, width))
for i in range(, height, 8):
for j in range(, width, 8):
block = dequantize(decoded_blocks[i//8*width//8+j//8])
idct = np.dot(np.dot(idct_mat, block), idct_mat.T)
restored = idct + 128
restored_img[i:i+8, j:j+8] = restored
# 将反变换后的小块合并成原始图像,并计算 PSNR
restored_img = Image.fromarray(np.uint8(restored_img))
restored_img.save('restored.bmp')
psnr_value = psnr(np.array(img), np.array(restored_img))
print('PSNR:', psnr_value)
```
希望这个代码能够帮助你实现你的需求。