opencv库(3)

图像的增强之频域增强

import cv2 as cv
import numpy as np
import math

# 图像频域增强的方法(主要针对灰度图像)
# 图像从空间域变换到频率域后,其低频分量对应图像中灰度变化比较缓慢的区域,高频分量对应物体的边缘和随机噪声等信息
# 使用低通滤波,可以消除图像的随机噪声、减弱边缘效应,达到平滑图像的作用
# 使用高通滤波,可以增强高频分量,使图像的边缘和线条更加清晰,实现图像的锐化
img = cv.imread("./img.png", cv.IMREAD_GRAYSCALE)
# 对图像进行傅里叶变换,从空域转换成频域
dft = cv.dft(np.float32(img), None, cv.DFT_COMPLEX_OUTPUT)
shift = np.fft.fftshift(dft)
# 只是用于查看该图像的频谱图像
magnitude_spectrum = 20 * np.log(cv.magnitude(shift[:, :, 0], shift[:, :, 1]))
# 用opencv自带的cv.imshow()函数显示需要修改一下图像的类型,
# 因为cv.imshow()显示float型数据的范围是[0, 1],浮点值超过1的都认为是1
magnitude_spectrum = np.uint8(magnitude_spectrum)
# 频域滤波增强
# 低通滤波
# 理想低通滤波
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
mask1 = np.zeros((rows, cols, 2), np.float32)
mask1[crow-30: crow+30, ccol-30: ccol+30] = 1
shift1 = shift * mask1
# 巴特沃斯低通滤波
rows, cols = img.shape
mask2 = np.zeros((rows, cols, 2), np.float32)
D0_2 = 80
n2 = 5
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        mask2[u, v] = 1/(1+math.pow(D/D0_2, 2*n2))
shift2 = shift * mask2
# 高斯低通滤波(类似指数低通滤波)
rows, cols = img.shape
mask3 = np.zeros((img.shape[0], img.shape[1], 2), np.float32)
D0_3 = 80
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        mask3[u, v] = math.pow(math.e, -((D/D0_3)**2)/2)
shift3 = shift * mask3
# 指数低通滤波
rows, cols = img.shape
mask4 = np.zeros((img.shape[0], img.shape[1], 2), np.float32)
D0_4 = 80
n4 = 8
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        mask4[u, v] = math.pow(math.e, -math.pow(D/D0_4, n4))
shift4 = shift * mask4
# 梯形低通滤波
rows, cols = img.shape
mask5 = np.zeros((img.shape[0], img.shape[1], 2), np.float32)
D0_5 = 20
D1_5 = 100
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D < D0_5:
            mask5[u, v] = 1
        elif D0_5 <= D <= D1_5:
            mask5[u, v] = (D-D1_5)/(D0_5-D1_5)
        else:
            mask5[u, v] = 0
shift5 = shift * mask5
# 高通滤波
# 理想高通滤波
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
mask6 = np.ones((rows, cols, 2), np.float32)
mask6[crow - 30: crow + 30, ccol - 30: ccol + 30] = 0
shift6 = shift * mask6
# 巴特沃斯高通滤波
rows, cols = img.shape
mask7 = np.ones((rows, cols, 2), np.float32)
D0_7 = 40
n7 = 4
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D != 0:
            mask7[u, v] = 1/math.pow(1+D0_7/D, 2*n7)
shift7 = shift * mask7
# 高斯高通滤波(注意与高斯低通滤波的区别)
rows, cols = img.shape
mask8 = np.ones((rows, cols, 2), np.float32)
D0_8 = 40
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        mask8[u, v] = 1-math.pow(math.e, -(D/D0_8)**2/2)
shift8 = shift * mask8
# 指数高通滤波
rows, cols = img.shape
mask9 = np.ones((rows, cols, 2), np.float32)
D0_9 = 40
n9 = 2
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D != 0:
            mask9[u, v] = math.pow(math.e, -math.pow(D0_9/D, n9))
shift9 = shift * mask9
# 梯形高通滤波
rows, cols = img.shape
mask10 = np.ones((img.shape[0], img.shape[1], 2), np.float32)
D0_10 = 100
D1_10 = 20
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D < D1_10:
            mask10[u, v] = 0
        elif D1_10 <= D <= D0_10:
            if D-D1_10 != 0:
                mask10[u, v] = (D0_10-D1_10)/(D-D1_10)
        else:
            mask10[u, v] = 1
shift10 = shift * mask10
# 带阻滤波
rows, cols = img.shape
mask11 = np.ones((img.shape[0], img.shape[1], 2), np.float32)
W_11 = 20
D0_11 = 40
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D <= D0_11-W_11/2:
            mask11[u, v] = 1
        elif D0_11-W_11/2 <= D <= D0_11+W_11/2:
            mask11[u, v] = 0
        else:
            mask11[u, v] = 1
shift11 = shift * mask11
# 带通滤波
rows, cols = img.shape
mask12 = np.zeros((img.shape[0], img.shape[1], 2), np.float32)
W_12 = 20
D0_12 = 40
for u in range(rows):
    for v in range(cols):
        D = math.sqrt((u-rows/2)**2+(v-cols/2)**2)
        if D <= D0_12-W_12/2:
            mask12[u, v] = 0
        elif D0_12-W_12/2 <= D <= D0_12+W_12/2:
            mask12[u, v] = 1
        else:
            mask12[u, v] = 0
shift12 = shift * mask12
# 对图像进行傅里叶逆变换,从频域转换成空域
ishift = np.fft.ifftshift(shift6)
idft = cv.idft(ishift)
# 将实部和虚部转换成实部
idft = cv.magnitude(idft[:, :, 0], idft[:, :, 1])
# 结果进行归一化处理,以便使用opencv进行查看
img = cv.normalize(idft, None, 0, 255, cv.NORM_MINMAX, cv.CV_8U)

Guess you like

Origin blog.csdn.net/weixin_49346755/article/details/121094203