일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Embedded System
- preprocessing
- Machine Vision
- cross compile
- porting
- tf.saver()
- OpenCV
- tf.train.string_input_producer()
- IOT
- Machine learning
- tf.train.match_filenames_once()
- ARM Processor
- Data Load
- deep-learning
- Python
- I.MX6Q
- Facial expression recognition
- Homomorphic Filter
- CNN
- TensorFlow
- VGGnet
- Raspberry Pi
- Today
- Total
Austin's_Lab
[Image processing] Homomorphic Filter 구현 in python 본문
[Image processing] Homomorphic Filter 구현 in python
Ausome_(Austin_is_Awesome) 2017. 7. 10. 21:35딥러닝을 이용해 병충해를 검출하는 과제를 하면서 직면한 문제 중 하나가 빛이었다. 이미지에 따라 빛이 노출되는 방향이나 세기 정도가 제각기 너무 달라서 이미지에 노출되는 빛을 normalize해야할 필요성을 느꼈다. 그에 관련해서 쓴 논문이 있는데 거기서 사용한 방법 중 하나가 Homomorphic filter이다. 이 필터는 이미지의 조명을 제거해주는 역할을 한다.
간단하게 설명하자면, 하나의 디지털 이미지는 illumination element와 reflectance element의 곱으로 표현할 수 있다. 이 중 illumination element는 이미지에 노출된 조명을 나타내고(low frequency), reflectance element는 이미지에 존재하는 object들의 edge를 나타낸다(high frequency). 그렇다면 우리는 이미지에 log를 취함으로써 곱셈을 덧셈연산으로 나눌 수가 있다. 여기에 HPF(high pass filter)를 씌우고 다시 exp 연산을 통해 log를 지워주면 조명이 제거된 이미지를 얻을 수 있다. high pass filtering은 이미지를 FFT를 수행해 frequency domain으로 가져가서 수행한 뒤 다시 iFFT를 수행해 이미지 도메인으로 넘어오도록 한다.
http://gromit2.blogspot.kr/2016/08/homomorphic-filtering.html 이 블로그에서 많이 도움을 받았다.
여기서 필요한 부분만 가져다 컬러이미지에 적용할 수 있도록 고쳐서 썼다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import cv2 import numpy as np ### homomorphic filter는 gray scale image에 대해서 밖에 안 되므로 ### YUV color space로 converting한 뒤 Y에 대해 연산을 진행 img = cv2.imread( 'file path' ) img_YUV = cv2.cvtColor(img, cv2.COLOR_BGR2YUV) y = img_YUV[:: 0 ] rows = y.shape[ 0 ] cols = y.shape[ 1 ] ### illumination elements와 reflectance elements를 분리하기 위해 log를 취함 imgLog = np.log1p(np.array(y, dtype = 'float' ) / 255 ) # y값을 0~1사이로 조정한 뒤 log(x+1) ### frequency를 이미지로 나타내면 4분면에 대칭적으로 나타나므로 ### 4분면 중 하나에 이미지를 대응시키기 위해 row와 column을 2배씩 늘려줌 M = 2 * rows + 1 N = 2 * cols + 1 ### gaussian mask 생성 sigma = 10 sigma = 10 (X, Y) = np.meshgrid(np.linspace( 0 , N - 1 , N), np.linspace( 0 , M - 1 , M)) # 0~N-1(and M-1) 까지 1단위로 space를 만듬 Xc = np.ceil(N / 2 ) # 올림 연산 Yc = np.ceil(M / 2 ) gaussianNumerator = (X - Xc) * * 2 + (Y - Yc) * * 2 # 가우시안 분자 생성 ### low pass filter와 high pass filter 생성 LPF = np.exp( - gaussianNumerator / ( 2 * sigma * sigma)) HPF = 1 - LPF ### LPF랑 HPF를 0이 가운데로 오도록iFFT함. ### 사실 이 부분이 잘 이해가 안 가는데 plt로 이미지를 띄워보니 shuffling을 수행한 효과가 났음 ### 에너지를 각 귀퉁이로 모아 줌 LPF_shift = np.fft.ifftshift(LPF.copy()) HPF_shift = np.fft.ifftshift(HPF.copy()) ### Log를 씌운 이미지를 FFT해서 LPF와 HPF를 곱해 LF성분과 HF성분을 나눔 img_FFT = np.fft.fft2(imgLog.copy(), (M, N)) img_LF = np.real(np.fft.ifft2(img_FFT.copy() * LPF_shift, (M, N)) # low frequency 성분 img_HF = np.real(np.fft.ifft2(img_FFT.copy() * HPF_shift, (M, N)) # high frequency 성분 ### 각 LF, HF 성분에 scaling factor를 곱해주어 조명값과 반사값을 조절함 gamma1 = 0.3 gamma2 = 1.5 img_adjusting = gamma1 * img_LF[ 0 :rows, 0 :cols] + gamma2 * img_HF[ 0 :rows, 0 :cols] ### 조정된 데이터를 이제 exp 연산을 통해 이미지로 만들어줌 img_exp = np.expm1(img_adjusting) # exp(x) + 1 img_exp = (img_exp - np. min (img_exp)) / (np. max (img_exp) - np. min (img_exp)) # 0~1사이로 정규화 img_out = np.array( 255 * img_exp, dtype = 'uint8' ) # 255를 곱해서 intensity값을 만들어줌 ### 마지막으로 YUV에서 Y space를 filtering된 이미지로 교체해주고 RGB space로 converting img_YUV[:,:, 0 ] = img_out result = cv2.cvtColor(img_YUV, cv2.COLOR_YUV2BGR) cv2.imshow( 'homomorphic' , result) |
결과적으로 아래 사진처럼 심하게 반사된 빛을 어느정도 감소시킨 것을 볼 수 있다. gamma값을 조절함으로써 본인의 application에 맞게 반사광을 제거할 수 있다.