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 22:04:16 浏览: 93
以下是实现上述功能的Python代码,代码中包含详细的注释:
```python
import numpy as np
import cv2
# 定义量化矩阵
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字形重排序矩阵
zigzag = 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] = 1 / np.sqrt(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] = 1 / np.sqrt(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_scan(block):
return np.array([block[zigzag[i, j]] for i in range(8) for j in range(8)])
# 定义反Z字形重排序函数
def inverse_zigzag_scan(block):
inverse_zigzag = np.zeros((8, 8), dtype=int)
for i in range(8):
for j in range(8):
inverse_zigzag[zigzag[i, j] // 8, zigzag[i, j] % 8] = i * 8 + j
return np.array([block[inverse_zigzag[i, j]] for i in range(8) for j in range(8)])
# 定义量化函数
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 float('inf')
else:
return 10 * np.log10(255 ** 2 / mse)
# 读取灰度图像
img = cv2.imread('test.bmp', cv2.IMREAD_GRAYSCALE)
# 将图像分割成8x8的小块,并对每个像素值减去128
blocks = np.array([img[i:i+8, j:j+8] - 128 for i in range(, img.shape[], 8) for j in range(, img.shape[1], 8)])
# 对每个小块进行DCT正向变换,并量化
dct_mat = dct_matrix(8)
quantized_blocks = np.array([quantize(dct_mat @ block @ dct_mat.T) for block in blocks])
# 对量化后的小块进行Z字形重排序编码,并保存为abc.my
encoded_blocks = np.array([zigzag_scan(block) for block in quantized_blocks])
np.savetxt('abc.my', encoded_blocks, fmt='%d')
# 读取编码后的数据,并进行解码反Z字形排序
encoded_blocks = np.loadtxt('abc.my', dtype=int)
decoded_blocks = np.array([inverse_zigzag_scan(block) for block in encoded_blocks])
# 对解码后的小块进行反量化和IDCT反向变换
dequantized_blocks = np.array([dequantize(block) for block in decoded_blocks])
idct_mat = idct_matrix(8)
idct_blocks = np.array([idct_mat @ block @ idct_mat.T for block in dequantized_blocks])
# 将反变换后的小块合并成原始图像,并计算PSNR
reconstructed_img = np.zeros_like(img)
for i in range(, img.shape[], 8):
for j in range(, img.shape[1], 8):
reconstructed_img[i:i+8, j:j+8] = idct_blocks[i//8*(img.shape[1]//8)+j//8]
print('PSNR:', psnr(img, reconstructed_img))
# 显示原始图像和重构图像
cv2.imshow('Original Image', img)
cv2.imshow('Reconstructed Image', reconstructed_img)
cv2.waitKey()
cv2.destroyAllWindows()
```
阅读全文