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-29 12:03:58 浏览: 96
以下是Python代码,实现了将后缀为.b m p灰度图像分割成8X8的小块,对每个小块中的像素值减去128,对每个小块进行DCT正向变换,使用量化矩阵对每个小块进行量化,对量化后的小块进行Z字形重排序编码,将编码后的数据保存为abc.my,对编码后的数据进行解码反Z字形排序,对解码后的小块进行反量化,对反量化后的小块进行IDCT反向变换,使用循环将反变换后的小块合并成原始图像,并计算PSNR是否大于30。
```python
import numpy as np
import cv2
# 读取图像
img = cv2.imread('test.bmp', cv2.IMREAD_GRAYSCALE)
# 将图像分割成8x8的小块
blocks = [img[j:j+8, i:i+8] for (j, i) in np.ndindex(img.shape[]//8, img.shape[1]//8)]
# 对每个小块中的像素值减去128
blocks = [block - 128 for block in blocks]
# 对每个小块进行DCT正向变换
dct_blocks = [cv2.dct(np.float32(block)) for block in blocks]
# 量化矩阵
quant_matrix = 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]])
# 对每个小块进行量化
quant_blocks = [np.round(dct_block / quant_matrix) for dct_block in dct_blocks]
# 对量化后的小块进行Z字形重排序编码
zigzag_blocks = [np.zeros(64) for _ in range(len(quant_blocks))]
for i, quant_block in enumerate(quant_blocks):
for j in range(8):
if j % 2 == :
zigzag_blocks[i][j*(j+1)//2:(j+1)*(j+2)//2] = np.diag(quant_block, j)[::-1]
else:
zigzag_blocks[i][j*(j+1)//2:(j+1)*(j+2)//2] = np.diag(quant_block, j)
# 将编码后的数据保存为abc.my
with open('abc.my', 'wb') as f:
for zigzag_block in zigzag_blocks:
f.write(zigzag_block.astype(np.int16).tobytes())
# 对编码后的数据进行解码反Z字形排序
with open('abc.my', 'rb') as f:
zigzag_blocks = np.frombuffer(f.read(), dtype=np.int16).reshape(-1, 64)
quant_blocks = [np.zeros((8, 8)) for _ in range(len(zigzag_blocks))]
for i, zigzag_block in enumerate(zigzag_blocks):
for j in range(8):
if j % 2 == :
quant_blocks[i][j, :j+1] = np.diag(zigzag_block[::-1], j)
else:
quant_blocks[i][:j+1, j] = np.diag(zigzag_block, j)
# 对解码后的小块进行反量化
dct_blocks = [quant_block * quant_matrix for quant_block in quant_blocks]
# 对反量化后的小块进行IDCT反向变换
blocks = [cv2.idct(np.float32(dct_block)) for dct_block in dct_blocks]
# 使用循环将反变换后的小块合并成原始图像
reconstructed_img = np.zeros(img.shape)
for (j, i), block in zip(np.ndindex(img.shape[]//8, img.shape[1]//8), blocks):
reconstructed_img[j*8:(j+1)*8, i*8:(i+1)*8] = block
# 计算PSNR是否大于30
mse = np.mean((img - reconstructed_img)**2)
psnr = 10 * np.log10(255**2 / mse)
if psnr > 30:
print('PSNR:', psnr)
else:
print('PSNR is too low:', psnr)
```
注释:
1. 读取图像
2. 将图像分割成8x8的小块
3. 对每个小块中的像素值减去128
4. 对每个小块进行DCT正向变换
5. 量化矩阵
6. 对每个小块进行量化
7. 对量化后的小块进行Z字形重排序编码
8. 将编码后的数据保存为abc.my
9. 对编码后的数据进行解码反Z字形排序
10. 对解码后的小块进行反量化
11. 对反量化后的小块进行IDCT反向变换
12. 使用循环将反变换后的小块合并成原始图像
13. 计算PSNR是否大于30
阅读全文