728x90
# 1) 필요한 모듈 임포트
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# lenna 영상에 대한 잡음 제거
# 2) 원본 영상과 잡음 영상 읽음
org1 = cv.imread('data/lenna.tif')
org1 = cv.cvtColor(org1, cv.COLOR_BGR2GRAY)          # 원본 영상 읽음

img1 = cv.imread('data/lenna.tif_patterned.png')
img1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)          # 잡음 영상 읽음

# 3) 잡음 영상 출력
plt.figure('lenna')
plt.subplot(231)
plt.imshow(img1, cmap='gray')
plt.title('patterned source')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 4) 푸리에 변환
f1 = np.fft.fft2(img1)

# 5) 스펙트럼 구함
plt.subplot(232)
fshift1 = np.fft.fftshift(f1)
spectrum1 = 20*np.log(np.abs(fshift1)+1)
cv.imwrite('data/spectrum1.png',spectrum1)
plt.imshow(spectrum1, cmap='gray')
plt.title('spectrum of source')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 6, 7) 스펙트럼에서 잡음 제거한 이미지 읽어 binary mask 생성
plt.subplot(233)
mask1 = cv.imread('data/mask1.png')
mask1 = cv.cvtColor(mask1, cv.COLOR_BGR2GRAY)
plt.imshow(mask1, cmap='gray')
plt.title('mask')
plt.axis('off')
plt.xticks([]), plt.yticks([])

mask1[np.where(mask1!=np.amin(mask1))] = 255
mask1[np.where(mask1==np.amin(mask1))] = 0
mask_blr1 = cv.GaussianBlur(mask1, (21, 21), 5)

# 8) (스펙트럼 * 마스크) 영상 출력
plt.subplot(234)
fshift_mb1 = fshift1 * mask_blr1      # 마스크를 블러링한 것
spectrum_mb1 = 20 * np.log(np.abs(fshift_mb1)+1)
plt.imshow(spectrum_mb1, cmap='gray')
plt.title('spectrum * mask')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 9) 블러링 시킨 binary mask 영상 출력
plt.subplot(235)
plt.imshow(mask_blr1, cmap='gray')
plt.title('binary_mask')
plt.xticks([]), plt.yticks([])

# 10) 마스크 처리된 푸리에 변환 결과를 재배치
f_ishift_mb1 = np.fft.ifftshift(fshift_mb1)

# 11) 다시 푸리에 변환 후 잡음 제거된 영상 출력
plt.subplot(236)
img_mb1 = np.fft.ifft2(f_ishift_mb1)
result1 = np.abs(img_mb1)
plt.imshow(result1, cmap='gray')
plt.title('result')
plt.axis('off')
plt.xticks([]), plt.yticks([])

plt.show()

# 12) psnr 출력
result1 = (((result1/np.amax(result1))*255).astype('uint8'))
psnr_lenna = cv.PSNR(org1, np.clip(result1, 0, 255).astype('uint8'))
print('PSNR of Lenna =', psnr_lenna)



# monarch영상에 대한 잡음 제거
# 2) 원본 영상과 잡음 영상 읽음
org2 = cv.imread('data/monarch.png')
org2 = cv.cvtColor(org2, cv.COLOR_BGR2GRAY)          # 원본 영상 읽음

img2 = cv.imread('data/monarch.bmp_patterned.png')
img2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)          # 잡음 영상 읽음

# 3) 잡음 영상 출력
plt.figure('monarch')
plt.subplot(231)
plt.imshow(img2, cmap='gray')
plt.title('patterned source')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 4) 푸리에 변환
f2 = np.fft.fft2(img2)

# 5) 스펙트럼 구함
plt.subplot(232)
fshift2 = np.fft.fftshift(f2)
spectrum2 = 20*np.log(np.abs(fshift2)+1)
cv.imwrite('data/spectrum2.png',spectrum2)
plt.imshow(spectrum2, cmap='gray')
plt.title('spectrum of source')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 6, 7) 스펙트럼에서 잡음 제거한 이미지 읽어 binary mask 생성
plt.subplot(233)
mask2 = cv.imread('data/mask2.png')
mask2 = cv.cvtColor(mask2, cv.COLOR_BGR2GRAY)
plt.imshow(mask2, cmap='gray')
plt.title('mask')
plt.axis('off')
plt.xticks([]), plt.yticks([])

mask2[np.where(mask2!=np.amin(mask2))] = 255
mask2[np.where(mask2==np.amin(mask2))] = 0
mask_blr2 = cv.GaussianBlur(mask2, (21, 21), 5)

# 8) (스펙트럼 * 마스크) 영상 출력
plt.subplot(234)
fshift_mb2 = fshift2 * mask_blr2      # 마스크를 블러링한 것
spectrum_mb2 = 20 * np.log(np.abs(fshift_mb2)+1)
plt.imshow(spectrum_mb2, cmap='gray')
plt.title('spectrum * mask')
plt.axis('off')
plt.xticks([]), plt.yticks([])

# 9) 블러링 시킨 binary mask 영상 출력
plt.subplot(235)
plt.imshow(mask_blr2, cmap='gray')
plt.title('binary_mask')
plt.xticks([]), plt.yticks([])

# 10) 마스크 처리된 푸리에 변환 결과를 재배치
f_ishift_mb2 = np.fft.ifftshift(fshift_mb2)

# 11) 다시 푸리에 변환 후 잡음 제거된 영상 출력
plt.subplot(236)
img_mb2 = np.fft.ifft2(f_ishift_mb2)
result2 = np.abs(img_mb2)
plt.imshow(result2, cmap='gray')
plt.title('result')
plt.axis('off')
plt.xticks([]), plt.yticks([])
plt.show()

# 12) psnr 출력
result2 = (((result2/np.amax(result2))*255).astype('uint8'))
psnr_monarch = cv.PSNR(org2, np.clip(result2, 0, 255).astype('uint8'))
print('PSNR of monarch =', psnr_monarch)

- 푸리에 변환을 이용한 규칙적 잡음 제거 과정을 보이는 프로그램

 

# 잡음 영상

# 잡음 영상의 스펙트럼

# 그림판으로 스펙트럼에 잡음 제거

- 저장한 스펙트럼 이미지에 그림판으로 잡음 부분을 제거하여 이미지로 저장함

- 각각 ‘mask1.png’, ‘mask2.png’ 로 저장함

 

# binary mask 생성하여 블러링 시킴

- 그림판으로 스펙트럼에서 잡음을 제거한 이미지를 읽어 제거한 부분(영상의 최솟값)0으로 만들고 나머지 부분을 255로 만들어 binary mask(mask_blr1,2) 생성함

- np.where() 함수와 np.amin() 함수 이용

- 가우시안 블러링 함수를 이용하여 binary mask를 블러링 시킴

- 각각 ‘binary_mask1.png’, ‘binary_mask2.png’로 저장함

 

# 스펙트럼 * 마스크

- 스펙트럼과 mask를 곱합

 

# 잡음 제거 영상

# psnr 출력

# 실행 결과

1. lenna 영상 잡음 제거 과정 출력

2. monarch 영상 잡음 제거 과정

# 느낀 점

binary_mask를 생성하는 작업에서 시간이 꽤 걸림. 인덱싱 방법, np.where(), cv.inRange() 등 여러 가지 방법을 사용하여 작업할 수 있다는 것을 알게 되었음. 이번 과제를 하면서 np.where() 함수에 대하여 공부를 하게 됨. 파이썬에 많은 내장 함수가 있다는 것을 느낌. 직접 그림판으로 잡음을 제거하는 작업을 해보니 생각보다 잡음 제거하는 것이 어려웠음. 잘 제거된 예시가 궁금함.

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기