同态滤波器

在同态滤波器,通过对数变换将图像中的乘性信号转换为加性信号,之后便可以使用线性滤波方法进行处理(基于傅里叶变换)。同态滤波器的处理流程大致如下:

  1. 对数变换
  2. 傅里叶变换
  3. 滤波(比如高通滤波)
  4. 傅里叶反变换
  5. 对数反变换
  6. 归一化

代码如下:

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

# image: 灰度图像
# cutoff_low \ cutoff_high: 低频和高频滤波器的截止频率
# gamma_l \ gamma_h: 低频和高频区域的增益
def homomorphic_filter(image, cutoff_low=0.3, cutoff_high=0.7, gamma_l=1, gamma_h=3.0):
    # 转换为浮动32位类型
    image = np.float32(image)
    # 对数变换(乘性转为加性,然后使用线性滤波方法处理)
    log_image = np.log1p(image)  # np.log1p(x) = log(1 + x)
    # 傅里叶变换
    fft_image = np.fft.fft2(log_image)
    fft_shift = np.fft.fftshift(fft_image)
    # 生成同态滤波器
    rows, cols = image.shape
    crow, ccol = rows // 2, cols // 2  # 中心坐标
    # 创建带通滤波器
    filter_ = np.ones((rows, cols), dtype=np.float32)
    for i in range(rows):
        for j in range(cols):
            # 计算每个点到图像中心的距离
            distance = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)
            # 创建带通滤波器:低频部分被抑制,高频部分被增强
            if distance < cutoff_low * min(rows, cols)/2:
                filter_[i, j] = gamma_l
            elif distance > cutoff_high * min(rows, cols)/2:
                filter_[i, j] = gamma_h
            else:
                filter_[i, j] = 1
    # 滤波
    filtered_fft = fft_shift * filter_

    # 逆傅里叶变换
    inverse_fft_shift = np.fft.ifftshift(filtered_fft)
    inverse_fft_image = np.fft.ifft2(inverse_fft_shift)
    # 对数反变换
    # inverse_fft_image为复数表示,取模
    enhanced_image = np.expm1(np.abs(inverse_fft_image))  # np.expm1(x) = exp(x) - 1
    
    # 归一化到 0-255 范围
    # np.clip()用于限制元素值的范围
    enhanced_image = np.uint8(np.clip(enhanced_image, 0, 255))
    # 整体缩放不可取
#     enhanced_image = (enhanced_image - enhanced_image.min()) / (enhanced_image.max() - enhanced_image.min()) * 255
    return enhanced_image

# 读取图像并转换为灰度图像
# image = cv2.imread('dai.jpg', cv2.IMREAD_GRAYSCALE)
image = cv2.imread('dai.jpg')

# 使用同态滤波器增强图像
enhanced_image = np.zeros(image.shape, dtype=np.uint8)
enhanced_image[:, :, 0] = homomorphic_filter(image[:, :, 0])
enhanced_image[:, :, 1] = homomorphic_filter(image[:, :, 1])
enhanced_image[:, :, 2] = homomorphic_filter(image[:, :, 2])
enhanced_image_last = cv2.addWeighted(image, 1, enhanced_image, 5, 0)

# 单个通道的对比图
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
plt.imshow(image1, cmap='gray')
plt.title('image1')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(enhanced_image[:, :, 0], cmap='gray')
plt.title('enhanced_image[:, :, 0]')
plt.axis('off')

# 显示原始图像和增强后的图像
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
# plt.imshow(image, cmap='gray')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(enhanced_image, cv2.COLOR_BGR2RGB))
plt.title('enhanced_image')
plt.axis('off')

plt.show()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值