이미지 처리 --- 역 필터링 및 Wiener 필터링


머리말

본 논문에서는 열화된 영상 복원의 두 가지 방법인 역필터링과 위너필터링을 주로 소개한다.


1. 역 필터링

이미지 저하 표현:
g ( x , y ) = h ( x , y ) ⊙ f ( x , y ) + η ( x , y ) \begin{aligned} g(x,y)=h(x,y )\odot f(x,y)+\eta(x,y) \end{정렬}g ( x ,)=시간 ( x ,)에프 ( 엑스 ,)+( 엑스 ,y )
f ( x , y ) : f(x,y):에프 ( 엑스 ,): 입력 이미지
h ( x , y ): h(x,y):시간 ( x ,): 퇴화 함수
η ( x , y ) : \eta(x,y):( 엑스 ,): 노이즈 항
g : g:g: 저하된 이미지

컨벌루션 정리에 의해 주파수 영역으로 변환:
G ( u , v ) = H ( u , v ) ∗ F ( u , v ) + N ( u , v ) \begin{aligned} G(u,v)=H (u,v)*F(u,v)+N(u,v) \end{정렬}( ,브이 )=H ( ,브이 )에프 ( ,브이 )+N ( ,v )

역 필터링 작업은 축퇴 함수를 제거하는 것입니다
. } \ hat{F}=\displaystyle\frac{G(u,v)}{H(u,v)}=F(u,v)+\frac{N(u,v)}{H(u, v) } \end{정렬}에프^^=H ( ,브이 )( ,v )=에프 ( ,브이 )+H ( ,브이 )N ( ,v ).

위 공식에 따르면 역 필터링에는 두 가지 주요 문제가 있습니다.

  1. 퇴화 함수 H ( u , v ) H(u,v)H ( ,v ) 의 추정치 가 실제로 정확할수록 복구가 더 명확해집니다.
  2. 열화 함수 H ( u , v ) H(u,v)H ( ,v ) 가 0에 가까워지면 후자의 값이 너무 커지며 최종 공식은 잡음 항N (u , v ) N(u,v)N ( ,v ) 영향력이 증가합니다.

1.1 추정 열화함수 H(u,v) H(u,v)H ( ,브이 )

주로 3가지 방법이 있습니다:
( 1 ) (1)( 1 ) : 관찰 방법( 2 ) (2)( 2 ) : 시험방법( 3 ) (3)( 3 ) : 수학적 모델링 방법
이 방법들은 모두 주파수 영역에서 처리된다.

1.1.1 관찰 방법

신호 내용이 강한 영역( 고대비 영역 )을 찾아 노이즈 항의 영향을 무시합니다. 즉,
Hs(u,v) = Gs(u,v)Fs^(u,v) \begin {정렬된 } {H_{s}(u,v)}=\displaystyle\frac{G_{s}(u,v)}{\hat{F_{s}}(u,v)} \end{정렬}시간에스( ,브이 )=에프에스^( ,브이 )G에스( ,v ).
G s ( u , v ) : {G_{s}}(u,v):G에스( ,브이 ): 현재 복원할 이미지의 푸리에 변환입니다.
F s ^ ( u , v ) : {\hat{F_{s}}(u,v)}:에프에스^( ,브이 ): 처리(샤프닝, 평균 필터링 등) 후 복원된 이미지입니다.

1.1.2 시험방법

요컨대, 실제 열화 과정을 시뮬레이션하기 위한 실험을 수행한 후 다음 공식에 따라 열화 함수를 구하는 것입니다.
H ( u , v ) = G ( u , v ) A \begin{aligned} {H(u,v)}=\displaystyle\frac{G(u,v)}{A} \end{aligned}H ( ,브이 )=( ,v ).
열화된 이미지와 매우 유사한 이미지를 얻을 수 있는 어떤 장치가 있다고 가정하고 임펄스(작은 광점, 작은 광점은 노이즈의 영향을 줄일 수 있을 만큼 충분히 밝아야 함)를 이미지화한 후 FFT를 얻습니다. 임펄스 변성(위의 G ( u , v ) G(u,v) 에 해당)( ,v ) ), 임펄스의 FFT는 상수aaA. _

1.1.3 모델링 방법 \bigstar

( 1 ) (1)( 1 ) 대기 난기류 모델
H ( u , v ) = e − k ( u 2 + v 2 ) 5 / 6 \begin{aligned} {H(u,v)}=e^{-k(u^{2 }+v^{2})^{5/6}} \end{정렬}H ( ,브이 )=이자형- 케이 ( 2 +v2 )5/6
k 는 난류의 강도를 반영하는 난류 상수입니다.
k = { 0.00025 약한 난류 0.001 중간 난류 0.0025 심한 난류 k= \left\{ \begin{array}{ll} 0.00025\quad\quad 약간 난류\\ 0.001\quad\quad\quad 중간 난류\\0.0025\quad\ quad\quad 심한 난기류\end{array} \right.케이= 0.00025약간의 난기류0.001적당한 난기류0.0025심한 난기류
암호:

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

# 读取图像
img = cv2.imread('A.png',0)

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

#-------------大气湍流模型-----------------
k = 0.001  #湍流程度
degeneration_img = np.zeros(fshift.shape,dtype=complex)   #一定要指定类型
for u in range(fshift.shape[0]):
    for v in range(fshift.shape[1]):
        H = np.exp(-k*np.power(np.float64((u-fshift.shape[0]//2)**2+(v-fshift.shape[1]//2)**2),5/6))
        degeneration_img[u][v] = fshift[u][v] * H
#-----------------------------------------

# 将频域图像在空域进行显示做的处理
img1  = np.fft.ifftshift(degeneration_img)
img1  = np.fft.ifft2(img1)
img1 = np.abs(img1)
img1 = cv2.normalize(img1, None, 0, 255, cv2.NORM_MINMAX)


# 显示原始图像和退化的图像
plt.figure(figsize=(20, 20))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img1, cmap='gray')
plt.title('degeneration img'), plt.xticks([]), plt.yticks([])
plt.show()

여기에 이미지 설명 삽입
참고: 개체를 초기화 할 때 degeneration_img유형을 지정해야 합니다 dtype=complex. 작성하는 과정에서 유형 지정을 잊어버려 잘못된 저하 이미지가 발생했습니다(시도 가능). 일반적으로 유형을 지정하지 않는 것은 큰 문제가 아니지만 이것은 복수형이므로 유형 을 지정하지 않으면 다음 명령문 degeneration_img[u][v] = fshift[u][v] * H할당 ! 아래 그림을 참조하십시오.

여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

전에는 동적 언어의 함정을 몰랐는데 지금은 한 번 함정에 빠졌고, 앞으로 Python으로 코드를 작성할 때 타입 주석을 추가해야 합니다 ! !

另外,也可以用矩阵的方法生成:(下面代码参考文章:https://blog.csdn.net/youcans/article/details/123027287)
def turbulenceBlur(img, k=0.001):  # 湍流模糊传递函数
        # H(u,v) = exp(-k(u^2+v^2)^5/6)
        M, N = img.shape[1], img.shape[0]
        u, v = np.meshgrid(np.arange(M), np.arange(N))
        radius = (u - M//2)**2 + (v - N//2)**2
        kernel = np.exp(-k * np.power(radius, 5/6))
        return kernel

( 2 ) (2)( 2 ) 모션 블러 모델
이미지가xxx 방향 의 속도는 x 0 ( t ) = at / T x_{0}(t) = at/T엑스0( )=a t / T yy에서 동시에 균일한 직선 운동y 방향 의 속도는 y 0 (t ) = bt / T y_{0}(t) = bt/T와이0( )=자유 정의에 의한 b t / T
H ( u , v ) = T π ( ua + vb ) sin [ π ( ua + vb ) ] e − j π ( ua + vb ) \begin{aligned} H(u, v) =\frac{T}{\pi(ua+vb)}sin[\pi(ua+vb)]e^{-j\pi(ua+vb)} \end{정렬}H ( ,브이 )=π ( 유아 _+v b )s in [ π ( _+v b )] e- ( u a + v b )

암호:

# 功能:实现运动模糊的效果
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 读取图像
img = cv2.imread('0526.tif',0)

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

#-------------运动模糊模型-----------------
a = b = 0.1
T = 1
degeneration_img = np.zeros(fshift.shape,dtype=np.complex64)   #一定要指定类型
for u in range(fshift.shape[0]):
    for v in range(fshift.shape[1]):
        uv = ((u-fshift.shape[0]//2)*a + (v-fshift.shape[1]//2)*b) * np.pi
        if uv == 0:
            degeneration_img[u][v] = fshift[u][v]
        else:
            H = T * np.sin(uv) * np.exp(np.complex64(-1j)*uv) /uv
            degeneration_img[u][v] = fshift[u][v] * H
#-----------------------------------------

# 将频域图像在空域进行显示做的处理
img1  = np.fft.ifftshift(degeneration_img)
img1  = np.fft.ifft2(img1)
img1 = np.abs(img1)
img1 = cv2.normalize(img1, None, 0, 1, cv2.NORM_MINMAX)


# 显示原始图像和退化的图像
plt.figure(figsize=(20, 20))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img1, cmap='gray')
plt.title('degeneration img'), plt.xticks([]), plt.yticks([])
plt.show()

여기에 이미지 설명 삽입

( 3 ) (3)( 3 )高斯模糊模型
H(u,v) = e-D2(u,v)/2D02D(u,v) = [(u-P/2)2+(v-Q/2 ) 2 ] 1 / 2 \begin{aligned} {H(u,v)}=e^{-D^{2}(u,v)/2D_{0}^{2}}\quad\quad\\ {D(u,v) = {[(uP/2)^{2}+(vQ/2)^{2}]^{1/2}}} \end{정렬}H ( ,브이 )=이자형- D2 (u,v)/2D02( ,브이 )=[( -P /2 )2+( v-Q /2 )2 ]1/2
암호:

import cv2
import numpy as np

# 读取输入图像
img = cv2.imread('A.png', 0)

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

# 构造高斯滤波器
rows, cols = img.shape
crow, ccol = rows//2, cols//2
d = 60  # 滤波器大小
gauss = np.zeros((rows, cols))
for i in range(rows):
    for j in range(cols):
        gauss[i, j] = np.exp(-((i-crow)**2+(j-ccol)**2)/(2*d**2))

# 将高斯滤波器应用于频域图像
filtered = np.multiply(fshift, gauss)

# 进行反傅里叶变换
f_ishift = np.fft.ifftshift(filtered)
img_back = np.fft.ifft2(f_ishift)
img_back = np.abs(img_back)
img_back = cv2.normalize(img_back, None, 0, 1, cv2.NORM_MINMAX)

# 显示结果
cv2.imshow('Input', img)
cv2.imshow('Output', img_back)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.2 직접 역 필터링

노이즈 무시:
F ^ = G ( u , v ) H ( u , v ) \begin{aligned} \hat{F}=\displaystyle\frac{G(u,v)}{H(u,v)} \ 끝{정렬}에프^^=H ( ,브이 )( ,v ).
【noise1.png】: 가우시안 블러와 가우시안 노이즈 이후의 이미지.
사전 지식 없이 대기 난류 모델을 이용하여 영상의 열화함수를 추정한 후 역 필터링 과정을 거친다.
아래와 같이 코드 쇼:

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

# 读取图像
img = cv2.imread('noise1.png',0)

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

#-------------利用大气湍流模型估计退化传递函数-----------------
k = 0.001  #湍流程度
degeneration = np.zeros(fshift.shape,dtype=complex)   
for u in range(fshift.shape[0]):
    for v in range(fshift.shape[1]):
        H = np.exp(-k*np.power(np.float64((u+fshift.shape[0]//2)**2+(v-fshift.shape[1]//2)**2),5/6))
        degeneration[u][v] =  H
#-----------------------------------------


# 逆滤波
img1 = np.divide(fshift,degeneration)

# 将频域图像在空域进行显示做的处理
img1  = np.fft.ifftshift(img1)
img1  = np.fft.ifft2(img1)
img1 = np.abs(img1)
img1 = cv2.normalize(img1, None, 0, 255, cv2.NORM_MINMAX)


# 显示原始图像和恢复后的图像
plt.figure(figsize=(20, 20))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img1, cmap='gray')
plt.title('rec img'), plt.xticks([]), plt.yticks([])
plt.show()

필터링 효과:
여기에 이미지 설명 삽입
단, 위 문장만 바꾸면 됨 degeneration[u][v] = H → \rightarrowdegeneration[u][v] = H + 0.001 0.001을 노이즈 추정치로 사용하면 특정 효과를 얻을 수 있습니다.
여기에 이미지 설명 삽입

1.3 반경 제한 역 필터링

考虑噪声:
F ^ = F ( u , v ) + N ( u , v ) H ( u , v ) \begin{aligned} \hat{F}=F(u,v)+\frac{N(u, v)}{H(u,v)} \end{정렬}에프^^=에프 ( ,브이 )+H ( ,브이 )N ( ,v ).

저역 통과 필터를 사용하여 고주파 노이즈를 필터링한 다음 H(u, v)로 나눕니다.

암호:

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

# 读取图像
img = cv2.imread('noise3.png',0)

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

#-------------大气湍流模型-----------------
k = 0.001  #湍流程度
degeneration = np.zeros(fshift.shape,dtype=complex)   #要指定类型
for u in range(fshift.shape[0]):
    for v in range(fshift.shape[1]):
        H = np.exp(-k*np.power(np.float64((u+fshift.shape[0]//2)**2+(v-fshift.shape[1]//2)**2),5/6))
        degeneration[u][v] =  H
#-----------------------------------------


# 构建低通滤波器---理想低通
# rows,cols = fshift.shape
# radius = 1
# mask = np.zeros((rows, cols),dtype=np.float64)
# for i in range(rows):
#     for j in range(cols):
#         if np.sqrt((i-rows//2)**2 + (j-cols//2)**2) <= radius:
#             mask[i, j] = 0.1
# fshift = np.multiply(fshift, mask)

# # 构建高斯低通滤波器
# rows, cols = img.shape
# crow, ccol = rows//2, cols//2
# d = 50  # 滤波器大小
# gauss = np.zeros((rows, cols))
# for i in range(rows):
#     for j in range(cols):
#         gauss[i, j] = np.exp(-((i-crow)**2+(j-ccol)**2)/(2*d**2))

# 构建巴特沃斯低通滤波器
rows, cols = img.shape
crow, ccol = rows//2, cols//2
d = 70  # 滤波器大小
butter = np.zeros((rows, cols))
for i in range(rows):
    for j in range(cols):
        butter[i, j] = 1/(1 + np.power((np.power((i-crow)**2+(j-ccol)**2,0.5)/d),20))

fshift = np.multiply(fshift, butter)
# 逆滤波
img1 = np.divide(fshift,butter)

# 将频域图像在空域进行显示做的处理
img1  = np.fft.ifftshift(img1)
img1  = np.fft.ifft2(img1)
img1 = np.abs(img1)
img1 = cv2.normalize(img1, None, 0, 1, cv2.NORM_MINMAX)


# 显示原始图像和恢复后的图像
plt.figure(figsize=(20, 20))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img1, cmap='gray')
plt.title('rec img'), plt.xticks([]), plt.yticks([])
plt.show()

cv2.imshow('org',img)
cv2.imshow('rev',img1)
cv2.waitKey(0)

필터 효과:

여기에 이미지 설명 삽입

둘째, 최소 평균 제곱 오차(Wiener) 필터

저하된 이미지의 추정된 푸리에 변환은 다음과 같습니다
. , v ) \begin{정렬} \hat{F(u,v)}=[\frac{1}{H(u,v)}\frac{|H(u,v)|^{2}} { |H(u,v)|^{2}+K}]{G(u,v)} \end{정렬}에프 ( ,브이 )^=[H ( ,브이 )1∣H ( , _v ) 2+케이∣H ( , _v ) 2] G ( ,v )

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

# 读取图像
img = cv2.imread('noise2.png',0)

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

#-------------大气湍流模型-----------------
k = 0.001  #湍流程度
degeneration = np.zeros(fshift.shape,dtype=complex)   #要指定类型
for u in range(fshift.shape[0]):
    for v in range(fshift.shape[1]):
        H = np.exp(-k*np.power(np.float64((u+fshift.shape[0]//2)**2+(v-fshift.shape[1]//2)**2),5/6))
        degeneration[u][v] =  H
#-----------------------------------------


# 维纳滤波
K = 0.001
degeneration += 0.1   #加上估计的噪声
img1 = (np.conj(degeneration)/(np.conj(degeneration)*degeneration + K)) * fshift

# 将频域图像在空域进行显示做的处理
img1  = np.fft.ifftshift(img1)
img1  = np.fft.ifft2(img1)
img1 = np.abs(img1)
img1 = cv2.normalize(img1, None, 0, 1, cv2.NORM_MINMAX)


# 显示原始图像和恢复后的图像
plt.figure(figsize=(20, 20))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img1, cmap='gray')
plt.title('rec img'), plt.xticks([]), plt.yticks([])
plt.show()

필터 효과:
여기에 이미지 설명 삽입

요약하다

위너 필터링과 역 필터링 두 가지 방법을 주로 보여주지만 필터링 효과가 뚜렷하지 않은데 이는 추정 열화함수와 실제 열화함수의 불일치 때문일 수 있다.

참조

[1] Ruan Qiuqi, Ruan Yuzhi 번역, (미국) Raphael C. Gonzalez, Richard E. Woods. 디지털 이미지 처리 외국 전자책 및 커뮤니케이션 교과서 시리즈[M] 4판. 베이징: 전자 산업 출판부, 2020

추천

출처blog.csdn.net/m0_46366547/article/details/129826768