영상의 픽셀 강도는 크게 두가지 영향을 받는다고 가정한다.
첫번째로는, 조명과 같은 직접적인 광원 빛 i
두번째로는, 객체로 부터 반사된 빛 r
우리는 첫번째의 조명과 같은 직접적인 광원 빛을 없애는 데 집중할 것이다!
디지털 영상은 f(x,y)=i(x,y),r(x,y)로 표현 가능한데
이땨ㅐ 푸리에로 계산을 할때
곱하기가 성립이 되지 않는다!
이때 자연 로그를 이용한다.
자연로그를 사용하면 곱이 합으로 표현되기 때문이다!
여기서 빛 i와 반사광 r의 특징에 따라 (그림참고)
빛 i는 천천히 바뀜을 가정하여
이러한 그래프를 더해줌으로써 빛 i의 영향력을 빼준당
준동형 필터의 변환 과정
한 픽셀(저주파) 가우시안? 형태로 나타내기 위해?
이해한바로는 가장자리갈수록 값은 커지지만 ,, 가운데 값으로 갈수록 값은 점점 작아지는 부분을 표현하기 위해서,,,
아! 위의 가우시안 형태와 같은 H 필터를 사용하기 위함
for (int u = 0; u < F.rows; u++) {
for(int v=0;v<F.cols;v++){
float D2 = 0;
if (u < F.rows / 2) { D2 += u * u; }
else { D2 += (F.rows - u) * (F.rows - u); }
if (u < F.cols / 2) { D2 += u * u; }
else { D2 += (F.cols - u) * (F.cols - u); }
float D = u * u + v * v;
F.at<float>(u, v) = ((gammaH - gammaL) * (1 - exp(-c * (D * D / D0 / D0))) + gammaL)*F.at<float>(u,v);
}
void homomorphicFilter(InputArray input, OutputArray output, float D0, float gammaH, float gammaL)
{
const Mat& src = input.getMat();
output.create(input.size(), CV_32FC1);
Mat dst = output.getMat();
Mat F,srcLn;
cv::log(src + 1,srcLn);
// 1.푸리에 변환, 로그를 취해줌
dft(srcLn, F, DFT_COMPLEX_OUTPUT);
float c = 1;
//2. 필터링 H
for (int u = 0; u < F.rows; u++) {
for(int v=0;v<F.cols;v++){
float D2 = 0;
if (u < F.rows / 2) { D2 += u * u; }
else { D2 += (F.rows - u) * (F.rows - u); }
if (u < F.cols / 2) { D2 += u * u; }
else { D2 += (F.cols - u) * (F.cols - u); }
float D = u * u + v * v;
F.at<float>(u, v) = ((gammaH - gammaL) * (1 - exp(-c * (D * D / D0 / D0))) + gammaL)*F.at<float>(u,v);
}
}
F.at<float>(0, 0) = F.rows * F.cols * 0.5;
imshow("F", F);
// 3. 역푸리에 변환
idft(F, dst, DFT_REAL_OUTPUT | DFT_SCALE);
// 4. 지수 변환
exp(dst, dst);
dst -= 1;
}
글을 마치면서,,
교수님의 수업을 들으면서 신현준 교수님 수업 코드는 다 블로그에 남기자는 생각을 했다.
이렇게 코드로 정리하고 어떤 개념을 이런 코드에 적용했는지 가시적으로 표현하니 훨씬 더 이해가 잘간다.
신 교수님 최고!