관리 메뉴

공부 기록장 💻

[OpenCV/C++] 영상의 필터링 1 - 필터 마스크 연산과 엠보싱 필터링 (Filtering, Embossing) 본문

# Tech Studies/Computer Vision • OpenCV

[OpenCV/C++] 영상의 필터링 1 - 필터 마스크 연산과 엠보싱 필터링 (Filtering, Embossing)

dream_for 2022. 11. 30. 12:44

OpenCV 4로 배우는 컴퓨터비전과 머신 러닝 CH7 필터링 정리

 

영상 필터링 시리즈

영상의 필터링 1 - 필터 마스크 연산과 엠보싱 필터링 (Embossing) https://dream-and-develop.tistory.com/307

영상의 필터링 2 - 블러링과 가우시안 필터링 https://dream-and-develop.tistory.com/308

영상의 필터링 3 - 샤프닝과 잡음 제거 필터링 https://dream-and-develop.tistory.com/309

 


 

영상의 필터링

 

영상 처리에서 필터링(filtering) 이란, 영상에서 원하는 정보만 통과시키고 원치 않는 정보는 걸러 내는 작업이다. 영상의 필터링은 보통 마스크(mask) 라 부르는 작은 크기의 행렬을 이용한다. 마스크는 필터링의 성격을 정의하는 행렬로 커널(kernel), 윈도우(window)라고도 부르며, 경우에 따라서는 마스크 자체를 필터라고 부르기도 한다.

 

필터 마스크

 

영상 처리에서 다양한 크기의 모양의 필터 마스크가 사용되는데, 행렬의 원소는 보통 실수로 구성되며, 1x3, 3x1 형태의 직사각형 행렬, 3x3, 5x5 등 정방형 행렬, 필요하다면 십자가 모양 등 여러 가지 모양이 있으며, 그중에서도 3x3 정방형 행렬이 가장 널리 사용되고 있다. 

 

위의 그림은 다양한 필터 마스크 모양을 타나내느데, 진한 색으로 표시된 위치는 고정점(anchor point)를 나타낸다.

고정점은 현재 필터링 작업을 수행하고 있는 기준 픽셀 위치를 나타내고, 대부분의 경우 마스크 행렬 정중앙을 고정점으로 사용한다.

 

필터링 연산의 결과는 마스크 행렬의 모양과 원소 값에 의해 결정되는데, 마스크 행렬을 어떻게 정의하는가에 따라 영상을 드럽게 혹은 날카롭게 만들 수도, 잡음을 제거하거나 에지 성분만 나타나도록 만들 수도 있다.

 

가장 널리 사용하는 3x3 정방형 마스크를 이용해 필터링을 수행한다고 해보자.

m은 마스크 행렬을 나타내고, f와 g는 각각 입력 영상과 출력 영상을 의미한다. 마스크 행렬의 크기가 3x3이므로 고정점의 좌표는 중심 좌표인 (1,1)로 설정할 수 있다.

마스크를 이용한 필터링은 입력 영상의 모든 픽셀 위로 마스크 행렬을 이동시키면서 마스크 연산을 수행하는 방식으로 이루어진다. 마스크 연산은, 마스크 행렬의 모든 원소에 대해 마스크 행렬 원소 값과 같은 위치에 있는 입력 영상 픽셀 값을 서로 곱한 후, 그 결과를 모두 더하는 연산이다. 그리고 마스크 연산의 결과를 출력 영상에서 고정점 위치에 대응하는 픽셀 값으로 설정한다. 

따라서 마스크 행렬 m의 중심이 입력 영상의 (x,y) 좌표 위에 위치했을 때 필터링 결과 영상의 픽셀 값 g(x,y)는 다음과 같이 계산된다.

 

 

(x,y) 좌표에서 마스크 연산을 통해 영상의 픽셀 값 g(x,y)를 구했으면, 다음에는 마스크를 한 픽셀 옆으로 이동하여 (x+1, y) 좌표에 다시 마스크 연산을 수행하고, 그 결과를 g(x+1, y)에 저장한다. 이 과정을 영상 전체 픽셀에 대해 수행하면 필터링이 완료된다.

 

가장자리 픽셀 확장 방법

 

그런데 영상의 가장자리 픽셀에 대해서 수행할 때에는, 영상의 가장자리 픽셀을 확장하여 영상 바깥쪽에 가상의 픽셀을 만드는 방법을 수행한다. 가상의 픽셀 값을 어떻게 설정하는가에 따라 필터링 연산 결과가 달라지는데, OpenCV 필터링 연산에서 기본적으로 사용하는 방법은 아래와 같이 실제 입력 영상의 픽셀 값이 대칭 형태로 나타나도록 설정하는 방법이다.

아래는 5x5 크기의 필터 마스크를 사용하므로 좌측 상단의 가장자리 바깥쪽에 두 개씩의 가상 픽셀을 추가적으로 표현한 것이다.

 

 

OpenCV 필터링 연산에서 사용할 수 있는 가장자리 픽셀 확장 방법은 다음과 같이 BorderTypes라는 열거형 상수를 이용해 다른 방식으로 설정할 수도 있다.

 

 

 

filter2D() 함수

OpenCV 에서 필터 마스크를 사용하는 일반적인 필터링은 filter2D() 함수를 이용한다.

src 영상에 kernel 필터를 이용하여 필터링을 수행하고, 그 결과를 dst에 저장한다.

src와 dst 인자에 같은 변수 지정 시 필터링 결과를 입력 영상에 덮어쓰게ㅇ 된다.

 

 

 

함수가 수행하는 연산을 수식으로 표현하면 다음과 같다.

filter2D() 함수의 수식

 

ddepth 인자는 결과 영상의 깊이를 지정하는 용도로 사용하며, 입력 영상의 깊이에 따라 지정할 수 있는 값은 다음과 같다.

 

anchor, delta, borderType 인자는 기본 값을 가지고 있다.

anchor은 커널 행렬에서 고정점으로 사용할 좌표이며, 기본값으로 Point(-1, -1)을 지정하면 커널 행렬 중심 좌표를 고정점으로 사용한다.

delta는 필터링 연산 후 결과 영상에 추가적으로 더할 값을 지정하는 인자이며 (기본값 0), borderType은 위의 BorderTypes 열거형 상수 중 하나를 지정하면 된다.

 


 

엠보싱 필터링

엠보싱(embossing) 이란, 직물이나 종이, 금속판 등에 올록볼록한 형태로 만든 객체의 윤곽 또는 무늬를 뜻하며, 엠보싱 필터는 입력 영상을 엠보싱 느낌이 나도록 변환환하는 필터이다.

보통 픽셀 값 변화가 적은 평탄한 영역은 회색으로, 객체의 경계 부분은 좀 더 밝거나 어둡게 설정하여 엠보싱 느낌을 낼 수 있다.

 

간단한 3x3 엠보싱 필터 마스크는 다음과 같이 대각선 방향으로 +1, -1 값이 지정되어 있는 행렬이다.

 

 

대각선 방향으로 픽셀 값이 급격하게 변하는 부분에서 결과 영상 픽셀 값이 0보다 훨씬 크거나 0보다 훨씬 작은 값을 가직 되어, 픽셀값이 크게 바뀌지 않는 평탄한 영역은 결과 영상의 픽셀 값이 0에가까운 값을 가지게 된다. 

이렇게 구한 결과 영상을 그대로 화면에 나타내면 음수 값은 모두 포화 연산에 의해 0이 되어버리므로, 입체감이 크게 줄어들기 때문에 엠보싱 필터를 구현할 때에는 결과 영상에 128을 더하는 것이 보기에 좋다.

 

// 엠보싱 필터링
void filter_embossing() {
	Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);

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

	// 엠보싱 필터링 마스크
	float data[] = { -1,-1,0,-1,0,1,0,1,1 };
	Mat emboss(3, 3, CV_32FC1, data);

	Mat dst;
	filter2D(src, dst, -1, emboss, Point(-1,-1), 128); // 결과 영상에 128을 더하기

	imshow("src", src);
	imshow("dst", dst);

	waitKey(0);
	destroyAllWindows();
}

 

rose 이미지에 대해 엠보싱 필터 마스크 연산을 수행한 결과는 다음과 같다.

 

 

embossing filtering 연산 결과

 

픽셀 값이 급격하게 변하는 장미꽃의 경계 부분이 입체감 있게 표현된 것을 확인할 수 있다.

픽셀 값이 완만하게 바뀌는 나머지 부분에 대해서는 필터링 결과 영상이 대체로 밝기값 128에 가까운 회색으로 표현되어 있는 것 또한 확인할 수 있다.

728x90
반응형
Comments