본문 바로가기
런닝머신 (ML)

[컴퓨터 비전 & 머신러닝] 샤프닝 : 영상 날카롭게 하기

728x90

샤프닝은 초점이 잘 맞은 사진처럼 사물의 윤곽이 뚜렷하고 선명한 느낌이 나도록 영상을 변경하는 필터링 기법이다

이미 촬영된 사진을 초점이 잘 맞는 사진처럼 보이게끔 변경하려면 영상 에지 근방에서 픽셀 값의 명암비가 커지도록 수정해야 한다

 

언샤프 마스크 필터 :  샤프닝을 구현하기 위해서는 블러링된 영상을 사용해야 한다. 여기서 블러링이 적용된 영상을 언샤프닝 영상이라고 한다. 이처럼 언샤프닝 영상을 이용하여 역으로 날카로운 영상을 생성하는 필터를 언샤프 마스크 필터라고 한다

 

가로축은 픽셀 좌표의 이동을 나타내며, 세로축은 픽셀 값을 나타낸다.

(a)는 영상의 에지 부근에서 픽셀 값이 증가하는 모양을 나타낸 것이다

(b)에서 파란색 실선 그래프는 (a)의 그래프에 블러링을 적용한 결과이다

(c)는 (a)의 그래프에서 (b)의 그래프를 뺀 값이다, 입력 함수 값이 증가하기 시작하는 부분에서 음수 값을 가지고, 증가가 멈추는 부근에서는 양수 값을 가진다, 입력 영상에서 블러링 된 영상을 뺀 결과이므로 오직 날카로운 성분만을 가지고 있는 함수이다

(d)는 (a)의 그래프와 (c)의 그래프를 더한 값이다, 에지가 강조된 함수가 생성된다

입력 영상에 g(x,y)를 더함으로써 날카로운 성분이 강조된 최종 영상이 얻어지게 되는데, 단순하게 둘을 더하는 것이 아니라 실수 가중치를 곱한 후 더하면 날카로운 정도를 사용자가 조절할 수 있다

 

OpenCV에서는 따로 언샤프 마스크 필터 함수를 제공하지 않기에 앞 수식을 그대로 소스 코드 형태로 작성하면 아래와 같은 식이 나오게 된다

void unsharp_mask()
{
	Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);

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

	imshow("src", src);

	//가우시안 필터의 표준편자 sigma 값을 1~5까지 증가하면서 언샤프 마스크 필터링 수행
	for (int sigma = 1; sigma <= 5; sigma++) {
		Mat blurred;
		//가우시안 필터를 이용한 블러링 영상을 blurred에 저장
		GaussianBlur(src, blurred, Size(), sigma);

		float alpha = 1.f;
		//언샤프 마스크 필터링 수행
		Mat dst = (1 + alpha) * src - alpha * blurred;

		String desc = format("sigma: %d", sigma);
		putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0,
			Scalar(255), 1, LINE_AA);

		imshow("dst", dst);
		waitKey();
	}

	destroyAllWindows();
}

sigma 값이 커질수록 장미꽃 경계 부분이 좀 더 뚜렷하게 구분되는 것을 확인할 수 있다. 다만 값이 커짐에 따라 다소 과장된 느낌의 샤프닝 결과 영상이 만들어진 것을 볼 수 있다

728x90