基于Python OpenCV库的图像处理[1]图像变换DFT、DCT、DHT

离散傅里叶变换DFT

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读入原始lena图像
img = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)
#cv2.imshow('Original Image', img)
#cv2.waitKey(0)
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Original Image')

# 进行傅里叶变换
fft = np.fft.fft2(img)

# 将零频率分量移到图像中心
fft_shifted = np.fft.fftshift(fft)

# 计算幅度谱
magnitude_spectrum = 20 * np.log(np.abs(fft_shifted))

# 显示傅里叶变换后的频谱
plt.subplot(132)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.xticks([]), plt.yticks([])

# 计算阈值
threshold = np.percentile(np.abs(fft_shifted), 95)

# 将低值系数置零
fft_shifted[np.abs(fft_shifted) < threshold] = 0

# 进行逆变换
ifft_shifted = np.fft.ifftshift(fft_shifted)
ifft = np.fft.ifft2(ifft_shifted)
reconstructed_image = np.abs(ifft)

# 转换为8比特表示
reconstructed_image = np.uint8(reconstructed_image)

# 显示逆变换后的图像
plt.subplot(133)
plt.imshow(reconstructed_image, cmap='gray')
plt.title('IFFT Image')
plt.xticks([]), plt.yticks([])
plt.show()

# 计算原始图像与逆变换后图像的PSNR
def psnr(img1, img2):
    mse = np.mean((img1 - img2) ** 2)
    if mse == 0:
        return 100
    PIXEL_MAX = 255.0
    return 20 * np.log10(PIXEL_MAX / np.sqrt(mse))

# 计算逆变换后图像的峰值信噪比(PSNR)
psnr_fft = psnr(img, reconstructed_image)
print('PSNR:', psnr_fft)

离散余弦变换DCT

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读入原始lena图像
img = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)
#cv2.imshow('Original Image', img)
#cv2.waitKey(0)
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Original Image')

# 进行离散余弦变换
dct = cv2.dct(np.float32(img))

# 计算幅度谱
magnitude_spectrum = 20 * np.log(np.abs(dct))

# 显示离散余弦变换后的频谱
plt.subplot(132)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.xticks([]), plt.yticks([])

# 计算阈值
threshold = np.percentile(np.abs(dct), 95)

# 将低值系数置零
dct[np.abs(dct) < threshold] = 0

# 进行逆变换
idct = cv2.idct(dct)

# 转换为8比特表示
reconstructed_image = np.uint8(idct)

# 显示逆变换后的图像
plt.subplot(133)
plt.imshow(reconstructed_image, cmap='gray')
plt.title('IDCT Image')
plt.xticks([]), plt.yticks([])
plt.show()

# 计算原始图像与逆变换后图像的PSNR
def psnr(img1, img2):
    mse = np.mean((img1 - img2) ** 2)
    if mse == 0:
        return 100
    PIXEL_MAX = 255.0
    return 20 * np.log10(PIXEL_MAX / np.sqrt(mse))

# 计算逆变换后图像的峰值信噪比(PSNR)
psnr_dct = psnr(img, reconstructed_image)
print('PSNR:', psnr_dct)

离散哈达玛变换DHT

import cv2
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import hadamard
from skimage import img_as_ubyte
import math

# 读入原始lena图像
img = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)
#cv2.imshow('Original Image', img)
#cv2.waitKey(0)
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Original Image')

# 必须对读取的图像的双取值归一化到0~1之间
out = cv2.normalize(img.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)

# 生成512x512哈达玛矩阵,输入的值必须是 2 的幂,且要跟图像的长和宽对应。
Hada=hadamard(512)
Hada_pic = np.matmul(np.matmul(Hada,out),Hada)
# 沃尔什哈达玛变换记得/(N*N=512*512),此处只除512是为了频谱图效果好看
Hada_pic2=Hada_pic/(512)
plt.subplot(132)
plt.imshow(Hada_pic2, cmap='gray')
plt.title('Magnitude Spectrum')
plt.xticks([]), plt.yticks([])

rows, cols = Hada_pic2.shape
# 设置不同阈值 (高频部分能量低)
thresh = 0.05
num_coeffs = rows * cols
flat = Hada_pic2.flatten()
flat_sorted = np.sort(np.abs(flat))
thresh_idx = int(np.floor(thresh*num_coeffs))

thresh_val = flat_sorted[thresh_idx]
flat[np.abs(flat) < thresh_val] = 0
Hada_pic2 = flat.reshape(rows, cols)
# Hadamard逆变换,使用转置矩阵
IHada_pic = np.matmul(np.matmul(Hada.T, Hada_pic2), Hada.T)

# 沃尔什哈达玛变换记得/(N*N=512*512),此处只除512是为了频谱图效果好看
IHada_pic = IHada_pic/512
IHada_pic = np.clip(IHada_pic, -1, 1)

# 将灰度级转换为255级
IHada_pic = img_as_ubyte(IHada_pic)
IHada_pic = np.uint8(np.abs(IHada_pic))
plt.subplot(133)
plt.imshow(IHada_pic, cmap='gray')
plt.title('IHT Image')
plt.xticks([]), plt.yticks([])
plt.show()


# 计算原始图像与逆变换后图像的PSNR
def psnr(img1, img2):
    mse = np.mean((img1 - img2) ** 2)
    if mse == 0:
        return 100
    PIXEL_MAX = 255.0
    return 20 * np.log10(PIXEL_MAX / np.sqrt(mse))

# 计算逆变换后图像的峰值信噪比(PSNR)
psnr_ht = psnr(img, IHada_pic)
print('PSNR:', psnr_ht)

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值