python DWT图像压缩
时间: 2023-12-07 15:39:46 浏览: 338
离散小波变换(DWT)是一种常用的图像压缩技术,可以将图像分解为多个频带,从而实现对图像的压缩。下面是一个使用Python实现DWT图像压缩的例子:
```python
import pywt
import cv2
# 读取图像
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
# 进行二维离散小波变换
coeffs = pywt.dwt2(img, 'haar')
# 将小波系数进行量化
coeffs = list(map(lambda x: pywt.threshold(x, 10, 'soft'), coeffs))
# 进行二维离散小波反变换
img_dwt = pywt.idwt2(coeffs, 'haar')
# 显示原图和压缩后的图像
cv2.imshow('Original Image', img)
cv2.imshow('DWT Compressed Image', img_dwt)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在上面的代码中,我们首先使用OpenCV库读取了一张灰度图像,然后使用PyWavelets库进行了二维离散小波变换。接着,我们对小波系数进行了量化,并使用PyWavelets库进行了二维离散小波反变换,得到了压缩后的图像。最后,我们使用OpenCV库将原图和压缩后的图像显示出来。
相关问题
dwt小波变换图像压缩python
### 使用Python实现基于DWT的小波变换图像压缩
#### 导入必要的库
为了实现小波变换的图像压缩,需要导入一些常用的科学计算和图像处理库。
```python
import numpy as np
import pywt
from PIL import Image
import matplotlib.pyplot as plt
```
#### 加载并预处理图像
加载待压缩的图像,并将其转换为灰度图以便简化操作。
```python
def load_image(image_path):
img = Image.open(image_path).convert('L') # 转换为灰度图
img_array = np.array(img, dtype=np.float32)
return img_array / 255.0 # 归一化至[0,1]
image = load_image("example.jpg") # 替换为实际路径
plt.imshow(image, cmap='gray')
plt.title("Original Image")
plt.show()
```
#### 执行离散小波变换(DWT)
应用PyWavelets库中的`wavedec2()`函数执行二维离散小波分解。这里可以选择不同的小波基函数以及指定分解层数。
```python
wavelet = 'haar' # 或者尝试其他如'db4', 'sym8'
level = 3 # 分解层次数
coeffs = pywt.wavedec2(image, wavelet=wavelet, level=level)
cA = coeffs[0] # 近似系数 (低频部分)
details = coeffs[1:] # 细节系数列表 [(水平高频, 垂直高频, 对角线高频)]
```
#### 设置阈值进行量化
通过设定一个合适的阈值来舍弃较小幅度的小波系数,从而达到数据量减少的目的。
```python
threshold = 0.1 * np.max(np.abs(coeffs)) # 阈值设置为例最大绝对值的10%
for i in range(1, len(coeffs)):
cH, cV, cD = details[i-1]
mask_H = abs(cH) >= threshold
mask_V = abs(cV) >= threshold
mask_D = abs(cD) >= threshold
cH *= mask_H.astype(float)
cV *= mask_V.astype(float)
cD *= mask_D.astype(float)
details[i-1] = (cH, cV, cD)
```
#### 重构图像
利用修改后的近似系数与细节系数重建原始图片。
```python
reconstructed_img = pywt.waverec2([cA]+details, wavelet=wavelet)
reconstructed_img = reconstructed_img[:image.shape[0], :image.shape[1]] # 裁剪回原尺寸
normalized_reconstruced_img = ((reconstructed_img - reconstructed_img.min()) /
(reconstructed_img.max() - reconstructed_img.min()))
```
#### 显示结果对比
最后展示压缩前后的两幅图像及其差异。
```python
fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(15, 5))
ax[0].imshow(image, cmap='gray')
ax[0].set_title("Original")
ax[1].imshow(normalized_reconstruced_img, cmap='gray')
ax[1].set_title(f"Compressed with {wavelet} Wavelet")
difference = normalized_reconstruced_img - image
mse = np.mean(difference ** 2)
psnr = 10 * np.log10((1.0 ** 2) / mse)
ax[2].imshow(difference, cmap='seismic', vmin=-np.abs(difference).max(), vmax=np.abs(difference).max())
ax[2].set_title(f"Difference\nMSE={mse:.4f}, PSNR={psnr:.2f}")
plt.tight_layout()
plt.show()
```
上述过程展示了如何使用Python完成一次简单的小波变换图像压缩实验[^1]。值得注意的是,在实际应用场景中可能还需要考虑更多因素,比如不同类型的噪声影响、更复杂的阈值选取策略等。
对一张彩色图像进行DWT图像压缩,并计算压缩率,在jupyter notebooks上实现
好的,实现DWT图像压缩的步骤如下:
1. 读取彩色图像,并将其转换为灰度图像。
2. 使用 PyWavelets 库进行 DWT 变换,得到低频系数和高频系数。
3. 对高频系数进行量化和熵编码,将其压缩,得到压缩后的高频系数。
4. 将低频系数和压缩后的高频系数进行 IDWT 反变换,得到压缩后的图像。
5. 计算压缩率。
下面是实现代码:
```python
import pywt
import numpy as np
from scipy import fftpack
from PIL import Image
import matplotlib.pyplot as plt
def compress_image_DWT(image, threshold, quantization_factor):
# 将图像转换为灰度图像
gray_image = image.convert('L')
# 将灰度图像转换为 numpy 数组
image_array = np.array(gray_image)
# 使用 Haar 小波进行两级 DWT 变换
coeffs = pywt.wavedec2(image_array, 'haar', mode='periodization', level=2)
# 对高频系数进行量化
quant_coeffs = []
for i in range(1, len(coeffs)):
quant_coeffs.append(np.round(coeffs[i] / quantization_factor))
# 对高频系数进行熵编码
compressed_coeffs = []
for i in range(len(quant_coeffs)):
compressed_coeffs.append(fftpack.dct(quant_coeffs[i].ravel(), norm='ortho'))
# 根据阈值将高频系数进行压缩
compressed_coeffs = [c for c in compressed_coeffs if np.abs(c) > threshold]
# 将高频系数进行 IDCT 反变换
decompressed_coeffs = []
for i in range(len(compressed_coeffs)):
decompressed_coeffs.append(fftpack.idct(compressed_coeffs[i], norm='ortho').reshape(quant_coeffs[i].shape))
# 将低频系数和反变换后的高频系数进行 IDWT 反变换
coeffs[0] = pywt.threshold(coeffs[0], threshold)
coeffs[1:] = decompressed_coeffs
compressed_image = pywt.waverec2(coeffs, 'haar', mode='periodization')
# 计算压缩率
compressed_size = sum([c.nbytes for c in compressed_coeffs])
original_size = image_array.nbytes
compression_ratio = compressed_size / original_size
return compressed_image, compression_ratio
# 读取图像
image = Image.open('lena.png')
# 压缩图像
threshold = 50
quantization_factor = 10
compressed_image, compression_ratio = compress_image_DWT(image, threshold, quantization_factor)
# 显示压缩前后的图像
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].imshow(image, cmap='gray')
ax[0].set_title('Original Image')
ax[1].imshow(compressed_image, cmap='gray')
ax[1].set_title('Compressed Image')
# 显示压缩率
plt.figtext(0.5, 0.9, f'Compression Ratio: {compression_ratio:.2%}', ha='center', fontsize=12)
plt.show()
```
在这个示例中,我们使用了 Haar 小波进行 DWT 变换,并对高频系数进行了量化和熵编码,然后根据阈值将高频系数进行压缩。最后将低频系数和反变换后的高频系数进行 IDWT 反变换,得到了压缩后的图像。你可以根据实际需求和喜好,选择其他小波变换方法,调整阈值和量化因子来获得更好的压缩效果。
阅读全文