728x90
반응형

Image Denoising


영상처리 분야에서 중요한 부분이며 가장 많이 쓰이게 되는 부분중 하나로 이미지 노이즈 제거를 뽑을 수 있겠다. 이미 opencv에 이미지 노이즈를 제거하는 많은 알고리즘들과 함수들이 존재한다. 그 중 알아볼 것은 Non-local means Denoising 알고리즘이다.


이 전에 나왔던 기술들인 Gaussian blurring, Median Blurring 등과 같은 많은 이미지 평활화 기법을 보았으며, 노이즈가 조금 있는 영상에 대해 어느정도 효과를 보일 수 있었다. 또한 이러한 기능에서 각 픽셀 주변 작은 이웃 화소를 통해 중심요소를 대체해버리는 등 가우시안 기법, 평균, 중앙값 등을 이용한 연산을 수행해 왔다. 즉, 픽셀에서 노이즈 제거는 그 근처에 국한되었다는 것이다.


이 함수는 몇 초 동안 고정된 카메라를 이용하여 동일한 장면의 프레임을 얻고, 모든 프레임의 평균을 찾는다. 그리고서 첫 프레임과 마지막 프레임을 비교하여 노이즈를 제거할 수 있는데 이는 카메라가 움직일 경우나 프레임 안에서 객체가 움직이는 경우 강건하지 않다는 단점이 있다.


(그림 1) Image Denoising 방법


그래서 [그림 1]을 참고해보면, 노이즈를 평균화 하기 위해 유사한 이미지들이 필요한데, 이 함수들에서는 이미지에서 픽셀을 가져온 뒤, 그 주위에 작은 윈도우를 가져와 이미지의 비슷한 윈도우를 검색하고 모든 창을 평균 처리하며 픽셀은 얻은 결과로 대체하게 된다. 즉, [그림 1]에서 파란색 사각형들을 찾고 유사하다고 판단 되는 부분의 노이즈를 파란색 사각형으로 대체한다. 초록색 사각형도 마찬가지로 비슷한 부분으로 판단된다면 픽셀을 대체해버린다. 


즉 전역적이라는 특징이 있다. 이 방법이 Non-Local Means Denoising 방법이다. 이전에 나오게 된 블러링 기법보다는 더 많은 시간이 걸린다는 단점이 있지만 매우 흡족한 결과를 볼 수 있다. 정확성이 높은 결과가 요구된다면 이 방법이 괜찮은 듯! 특히나 인물 사진에 쓰기 좋은 것 같다. 원래는 뎁스 이미지의 노이즈를 제거하려고 찾아봤던 결과인데 한번 뎁스맵에도 적용을 해봐야 겠다. 


(그림 2) Denoising result 




OpenCV에 내장되어있는 함수는 아래와 같다.


1. fastNIMeansDenosing() - 단일 그레이 스케일 이미지를 씀


C++: void fastNlMeansDenoising(InputArray src, OutputArray dst, float h=3, int templateWindowSize=7, int searchWindowSize=21 )



2. fastNIMeansDenoisingColored() - 컬러이미지와 작동


C++: void fastNlMeansDenoisingColored(InputArray src, OutputArray dst, float h=3, float hColor=3, int templateWindowSize=7, int searchWindowSize=21 )



3. fastNIMeansDenosingMulti() - 단시간 내에 캡처 된 이미지 시퀀스와 함께 작동 (회색 음영 이미지)


C++: void fastNlMeansDenoisingMulti(InputArrayOfArrays srcImgs, OutputArray dst, int imgToDenoiseIndex, int temporalWindowSize, float h=3, int templateWindowSize=7, int searchWindowSize=21 )



4. fastNIMeansDenoisingCOloredMulti() - 위 함수와 같고 컬러 이미지를 씀


C++: void fastNlMeansDenoisingColoredMulti(InputArrayOfArrays srcImgs, OutputArray dst, int imgToDenoiseIndex, int temporalWindowSize, float h=3, float hColor=3, int templateWindowSize=7, int searchWindowSize=21 )



함수의 공통 인수는 다음과 같다.

- h : 필터의 강도, 클수록 노이즈가 잘 제거됨, 이미지 세부사항도 지워질 수 있음 ( 10 정도가 괜찮음)

- hForColorComponents : h 와 같지만 컬러이미지에만 사용됨 

- templateWindowSize : 홀수, 권장사항 7

- searchWindowSize : 홀수, 권장사항 21



실행 결과는 다음과 같다. 


(그림 3) 원본 이미지


(그림 4) 실행결과




(그림 5) 원본 이미지



(그림 6) Gaussian Blurring 결과 이미지 



(그림 7) fastNIMeansDenoising 결과 이미지



(그림 8) 실행 시간 측정 결과



꽤나 시간이 오래 걸린다...




소스코드 


 
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void main(){

	Mat src = imread("image/noise.jpg",1);
	Mat dst;
	// 수행시간 측정
	double duration;
	duration = static_cast<double> (getTickCount());

	resize(src, src, Size(src.cols *2, src.rows*2));

	imshow("image", src);
	fastNlMeansDenoising(src, dst, 7.0, 7, 21);
	
	duration = static_cast<double>(getTickCount()) - duration;
	duration /= getTickFrequency();
	
	imshow("result", dst);

	cout << "fastNIMeanDenosing : " << duration << " ms " << endl;

	// 수행시간 측정
	double duration1;
	duration1 = static_cast<double> (getTickCount());

	GaussianBlur(dst, dst, Size(7, 7), 1.5, 1.5);
	imshow("GaussianBlur", dst);
	duration1 = static_cast<double>(getTickCount()) - duration1;
	duration1 /= getTickFrequency();
	cout << "GaussianBlur : " << duration1 << " ms " << endl;

	waitKey(0);
}



참고자료 1 : http://docs.opencv.org/trunk/d5/d69/tutorial_py_non_local_means.html

참고자료 2 : http://docs.opencv.org/2.4/modules/photo/doc/denoising.html

728x90
반응형