[OpenCV] 샤프닝 – 선명한 영상 만들기

이번 글에서는 영상을 또렷하고 선명하게 만드는 기법인 샤프닝(sharpening)에 대해 알아보겠습니다.

샤프닝 처리가 된 영상은 아래 영상 중 우측 영상입니다.

이렇게 영상을 선명하게 처리 하려면 엣지 부근의 영상의 명암비가 높아져야 합니다.
레나 영상의 모자 부분을 확대해서 보면 아래와 같이 한눈에 봐도 명암비가 높아진 것을 확인할 수 있습니다.

좌측 원본, 우측 샤프닝

이렇게 샤프닝을 처리하기 위해서는 역설적이게도 블러링된 영상을 사용한다는 것입니다.
이전에 블러링 기법은 영상의 엣지를 부드럽게 처리 한다고 설명하였습니다. 블러링에 대한 그래프는 아래와 같습니다.

원본 영상에서 블러링 영상을 빼면 아래와 같이 엣지 부근에서 블러링 처리를 위해 뺀 값이 남게 됩니다

이렇게 남은 값을 원본 영상에 더하면 엣지부근에서 명암비가 더 높아지는 샤프닝 영상이 만들어집니다.

이것을 코드로 옮기면 아래와 같습니다.

Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);

if (src.empty()) {
	cerr << "Image load failed!" << endl;
	return;
}

// blur
Mat img_blur;
blur(src, img_blur, Size(5, 5)); // g(x, y)

Mat img_gap = src - img_blur; // h(x, y) = f(x, y) - g(x, y)
Mat img_sharp = src + img_gap; // s(x, y) = f(x, y) + h(x, y)

imshow("src", src);
imshow("blur", img_blur);
imshow("sharp", img_sharp);

waitKey();
destroyAllWindows();

실행하면 아래와 같이 영상을 표시 합니다.

위 코드에서 영상을 더 또렷하게 하고 싶으면 아래와 같이 가중치 값을 받아 처리할수 있습니다.

// 가중치
cout << "insert weight: ";
float fWeight = 1.0;
cin >> fWeight;

// ...

Mat img_sharp = src + fWeight * img_gap; // s(x, y) = f(x, y) + weight * h(x, y)

이상으로 샤프닝 기법과, 코드로 처리하는 방법에 대해 알아보았습니다.