[컴퓨터비전 STUDY / KOCW 한동대학교 황성수 교수님 강의 Review]
Spatial Filtering은 공간 필터링이라고 하며, Spatial Filter을 가지고 필터링을 수행하는 것을 말한다.
가령, 다음과 같은 식이다.

Saptial filter는, Spatial filter의 계수가 어떠냐에 따라서 다양한 결과를 만들 수 있다.
Averaging filter은 low pass filter 라고도 하며, 필터 마스크 주변에 포함된 픽셀의 평균을 내서 영상 픽셀 값으로 설정하는 필터이다.
블러링 필터 중에서 단순하고 구현하기 쉬운 필터 방법이다.
모든 픽셀에 대해 픽셀 값을 옆에 있는 픽셀 값과 동일한 수준의 평균으로 바꾼다.
장점 : Averaging filter은 고주파 수 noise를 줄여준다.
단점 : Averaging filter를 사용하면 이미지가 흐려진다.
다음은 특정 pixel에 가중치를 두지 않는 방식으로 Averaging filte을 수행하는 방식이다.

다음은 가중치 평균을 이용해서 Averaging filtering을 수행하는 방식이다.

Averaging filter을 수행하는 코드는 다음과 같다.
int main() {
Mat image, AvgImg, GaussianImg;
image = imread("lena.png"); // 이미지를 읽어들임
// Blurs an image using the normalized box filter
// image: input image, AvgImg: output image, Size(5, 5): blurring kernel size
blur(image, AvgImg, Size(5, 5)); // 5x5 필터로 평균 필터링 수행함
// Blurs an image using a Gaussian filter
// image: input image, GaussianImg: output image, Size(5, 5): Gaussian kernel size
// 1.5: Gaussian kernel standard deviation in X direction
GaussianBlur(image, GaussianImg, Size(5, 5), 1.5); // 5x5 필터로 가우시안 필터링 수행함
imshow("Input image", image);
imshow("Average image", AvgImg);
imshow("Gaussian blurred image", GaussianImg)
결과는 다음과 같다.
차례대로 원본 image, Averaging filtering, Gaussian filtering을 수행한 결과이다.

가우시안 필터는 가우시안 분포 (Gaussian Distribution) 함수에 근거하여 생성한 필터 마스크를 사용하는 필터링 기법으로, Averaging filter보다 자연스러운 블러링 결과를 생성한다.

가우시안 분포는 평균을 중심으로 좌우 대칭의 종 모양을 갖는 확률분포를 말하며, 정규 분포 (normal distribution)라고도 한다. 이는 평균 근방에서 분포가 가장 많이 발생하고, 평균에서 멀어질수록 발생 빈도가 종 모양으로 감소하는 형태를 따른다.
Mask 사이즈가 중요하며, mask가 커질수록 blur의 강도가 더 세진다.
다음은 예시이며, 가장 오른쪽에 있는 그림의 mask 크기가 가장 크다.

Sharpening의 주요 목표는 Intensity 변화를 강조하는 것이다.

Averaging은 통합과 유사하며, 공간 차별화를 통해 sharpening을 수행할 수 있다는 결론을 내리는 것이 합리적이다.
또한, Sharpening은 second derivative를 사용한다.

강조하고자 하는 부분을 mask의 중앙에 놓고, 주변부의 값을 줄여 총합이 0이 되도록 mask를 생성한다.
가령 다음과 같은 방식이다. (4를 강조함 -> 8)

다음은 Sharpening을 수행하는 코드이다.
int main() {
Mat image, laplacian, abs_laplacian, sharpening;
image = imread("moon.jpg", 0);
// 가우시안 blur 처리 / 0, 0은 X, Y방향의 표준 편차 / BORDER_DEFAULT는 이미지 가장 자리 처리 방식
GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);
// calculates the Laplacian of an image
// image: src, laplacian: dst, CV_16S: desire depth of dst,
// 1: aperture size used to compute second-derivative (optional)
// 1: optional scale factor for the computed Laplacian values
// 0: optional delta value that is added to the result
// 2차 미분 계산 / 16 비트 부호 있는 정수 / 커널 크기 / 선택적 스케일 팩터 / 최종 결과에 추가될 선택적 델타 값
Laplacian(image, laplacian, CV_16S, 1, 1, 0);
convertScaleAbs(laplacian, abs_laplacian);
sharpening = abs_laplacian + image; // 라플라시안 이미지 + 원본 이미지를 생성함 (선명도 향상)
imshow("Input image", image);
imshow("Laplacian", laplacian);
imshow("abs_Laplacian", abs_laplacian);
imshow("Sharpening", sharpening);
waitKey(0);
결과는 다음과 같다.




Original signal은 원본 signal이다.
Blurred signal은 Original signal에 Blurring을 더한 것이다.
Unsharp mask은 Original signal에서 Blurred signal을 뺀 것이다.
Sharpened signal은 Original signal과 Unsharp mask를 합해준 것이다.
다음은 Unsharp masking을 수행하는 코드이다.
int main() {
Mat input = imread("lena.png");
Mat gray, blur, sharp;
cvtColor(input, gray, COLOR_BGR2GRAY); // grayscale 이미지로 변환
GaussianBlur(gray, blur, Size(5, 5), 3); // 가우시안 처리
addWeighted(gray, 1.5, blur, -0.5, 0, sharp);
// grayscale 이미지 (가중치 1.5)와 blur 이미지(가중치 -0.5) 혼합, 결과를 sharp에 저장함
imshow("gray", gray);
imshow("sharp", sharp);
waitKey(0);
}
결과는 다음과 같다.

3x3 filter에서 중간값은 5번째로 큰 값이다.
5x5 filter에서 중간값은 13번째로 큰 값이다.
Median filter은 마스크의 중앙값을 찾고 마스크의 픽셀 값을 중앙값으로 바꾼다.
mXm 중앙값 필터에 의해 영역이 m^2/2보다 작고, 이웃 픽셀에 대해 밝거나 어두운 픽셀의 격리된 클러스터
Median filter은 임펄스 노이즈(또는 소금 및 후추 노이즈)가 있는 경우 제거에 효과적이다.

Median filter을 수행하는 코드는 다음과 같다.
int main() {
Mat image = imread("saltnpepper.png", 0); // 이미지를 grayscale로 읽음
imshow("SaltAndPepper", image);
Mat mf1, mf2;
// Blurs an image using the median filter
// image: src, mf1: dst, 3: aperture size(must be odd and greater than 1)
medianBlur(image, mf1, 3); // 커널 크기 3, 결과는 mf1에 저장
imshow("MedianFiltered1", mf1);
medianBlur(image, mf2, 9); // 커널 크기 9, 결과는 mf2에 저장
imshow("MedianFiltered2", mf2);
waitKey(0);
return 0;
}
결과는 다음과 같다.
