pycharm写一个对一张分辨率为417*556的图片进行基于DCT的图像压缩,并能控制压缩率的代码
时间: 2024-02-20 07:59:33 浏览: 24
以下是用Python和OpenCV库实现基于DCT的图像压缩的示例代码,您可以在PyCharm中运行它:
```python
import cv2
import numpy as np
# 量化矩阵
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]])
# 量化矩阵缩放
def scale_quant_matrix(Q, scale):
return np.round(np.maximum(np.minimum(Q * scale, 255), 1))
# DCT变换
def dct2(block):
return cv2.dct(cv2.dct(block.T, norm=cv2.DCT_TYPE-II).T, norm=cv2.DCT_TYPE-II)
# 逆DCT变换
def idct2(block):
return cv2.idct(cv2.idct(block.T, norm=cv2.DCT_TYPE-II).T, norm=cv2.DCT_TYPE-II)
# 对块进行量化
def quantize(block, Q):
return np.round(np.divide(block, Q)).astype(int)
# 对块进行逆量化
def dequantize(block, Q):
return np.multiply(block, Q)
# DCT压缩
def dct_compression(img, Q_scale):
# 将图像划分为8x8块
blocks = cv2.resize(img, (np.int(np.ceil(img.shape[1]/8)*8), np.int(np.ceil(img.shape[0]/8)*8)))
blocks = cv2.cvtColor(blocks, cv2.COLOR_BGR2YCR_CB)[:,:,0] # 只对亮度分量进行压缩
blocks = np.float32(blocks)
blocks = np.array(np.split(blocks, blocks.shape[0]/8))
blocks = np.array([np.split(block, block.shape[1]/8, axis=1) for block in blocks])
# 对每个块进行DCT变换和量化
dct_blocks = np.zeros(blocks.shape)
quant_blocks = np.zeros(blocks.shape)
for i in range(blocks.shape[0]):
for j in range(blocks.shape[1]):
dct_blocks[i][j] = dct2(blocks[i][j])
quant_matrix = scale_quant_matrix(Q, Q_scale) # 根据缩放因子计算量化矩阵
quant_blocks[i][j] = quantize(dct_blocks[i][j], quant_matrix)
# 对量化后的系数进行编码
compressed = np.array([np.array([cv2.imencode('.jpg', quant_blocks[i][j])[1] for j in range(quant_blocks.shape[1])]) for i in range(quant_blocks.shape[0])])
return compressed, quant_blocks.shape
# DCT解压缩
def dct_decompression(compressed, shape, Q_scale):
# 对量化后的系数进行解码
quant_blocks = np.array([np.array([cv2.imdecode(compressed[i][j], 0) for j in range(compressed.shape[1])]) for i in range(compressed.shape[0])])
# 对每个块进行逆量化和逆DCT变换
blocks = np.zeros(shape)
for i in range(quant_blocks.shape[0]):
for j in range(quant_blocks.shape[1]):
quant_matrix = scale_quant_matrix(Q, Q_scale) # 根据缩放因子计算量化矩阵
dct_blocks = dequantize(quant_blocks[i][j], quant_matrix)
blocks[i*8:(i+1)*8, j*8:(j+1)*8] = idct2(dct_blocks)
blocks = np.uint8(np.maximum(np.minimum(blocks, 255), 0))
# 将图像转换为BGR格式
img = cv2.cvtColor(blocks, cv2.COLOR_GRAY2BGR)
return img
# 加载图像
img = cv2.imread('image.jpg')
# 压缩图像
compressed, shape = dct_compression(img, 0.5) # Q_scale = 0.5,控制压缩率
# 解压缩图像
decompressed = dct_decompression(compressed, shape, 0.5) # Q_scale = 0.5
# 显示压缩前后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Compressed Image', decompressed)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在这个示例代码中,我们使用了OpenCV库来实现DCT变换、量化、编码、解码和逆DCT变换等操作。您可以通过调整量化矩阵的缩放因子来控制压缩率。例如,如果您将缩放因子设置为0.5,则压缩率将大约为50%。