이미지 필터링

필터(Filter)는 일상생활에서 많이 쓰는 말이다. 필터란 무언가를 걸러주는 역할을 하는 것을 말하는데, 카메라의 렌즈 필터, 공기청정기의 필터 그리고 셀로판지를 통해 들어오는 빛이 특정색상으로 걸러지는것도 필터라고 말할 수 있다.

영상처리 분야에서의 필터링은 영상에서 필요한 정보만 통과시키고 원하지 않는 정보는 걸러내는 작업이다. 필터링은 공간적 필터링(Spatial domain filter)주파수 공간에서의 필터링(Frequency domain filtering), 두가지 방법으로 나뉜다.  

이 포스팅에서는 공간적 필터링에 대해서 알아보도록 한다.

Spatial domain filtering

공간적 필터링이란 영상의 픽셀값을 직접 이용하는 필터링 방법이다. 이때 특정 픽셀의 주변 픽셀들을 동시에 사용하며 주로 마스크(mask) 연산을 이용한다. 마스크 대신 커널, 윈도우, 템플릿이라는 용어를 쓰기도 하는데 주로 마스크 또는 커널이란 용어를 사용한다.

마스크는 보통 3*3 행렬의 형태를 많이 사용하지만 상황에 따라 5*5라던지 일직선 또는 십자가 형태의 마스크도 사용한다.

마스크의 형태와 값에 따라 필터의 역할이 결정된다. 이미지를 부드럽게 만들거나, 선명하게 만들 때 그리고 노이즈를 제거하는 등의 기능을 구현할 수 있다.

일반적으로 3*3 마스크를 이용하여 공간적 필터링을 계산하는 과정은 다음과 같다.

타겟 픽셀과 그 주변 픽셀들을 사용하여 마스크와 함께 연산하여 출력 픽셀(영상)을 결정한다. 아래의 움짤은 파랑색이 입력영상 녹색이 출력영상이다. 마스크와 함께 주변부 픽셀 연산을 통해 출력영상을 만들어가는 과정을 가시화하고 있다.

 

필터링 연산방식은 대충 감이 오리라 생각이 든다. 이러한 연산을 Convolution이라고 하고, Correlation이라고도 한다.

OpenCV에서 필터를 적용하기 위해 사용하는 함수로 filter2D가 있다.

filter2D(Mat src, Mat dst, int ddepth, Mat kernel)
src : 입력 영상
dst : 출력 영상
ddepth : 출력 영상 데이터 타입. -1을 지정하면 src와 같은 타입의 dst영상을 생성
kernel : 마스크 행렬

추가적으로 borderType을 지정할 수 있다.

대부분의 OpenCV함수는 입력 영상 외곽에서 참조할 픽셀이 없는 경우 가상의 픽셀을 생성하는데, 그 픽셀을 어떻게 만들지 borderType에 지정하면된다.  

BORDER_DEFAULT : BORDER_REFLECT_101과 같음. 기본값
BORDER_CONSTANT : 입력한(고정) 값으로 픽셀을 확장한다.
BORDER_WRAP : 반대쪽부터 복제해서 픽셀을 확장한다.
BORDER_REPLICATE : 엣지 픽셀을 복사해서 확장한다.
BORDER_REFLECT : 반사로 픽셀을 확장한다.
BORDER_REFLECT_101 : 반사로 픽셀을 확장한다. 엣지 픽셀을 '이중으로' 만들지 않는다.

필터 적용 예제 

다음 안드로이드 예제는 주어진 이미지에 filter2D함수와 특정 마스크를 사용하여 블러효과를 적용한다.

private val kernelSize = 5
override fun process(src: Mat): Mat {
    val dst = Mat()
    val kernel = Mat(kernelSize, kernelSize, CvType.CV_32F)
    for(i in 0 until kernelSize){
        for(j in 0 until kernelSize){
            kernel.put(i, j, 1.0 / (kernelSize*kernelSize).toDouble())
        }
    }
    Imgproc.filter2D(src, dst, -1, kernel)
    return dst
}

마스크의 형태는 다음과 같다

// 마스크
1/25, 1/25, 1/25, 1/25, 1/25,
1/25, 1/25, 1/25, 1/25, 1/25,
1/25, 1/25, 1/25, 1/25, 1/25,
1/25, 1/25, 1/25, 1/25, 1/25,
1/25, 1/25, 1/25, 1/25, 1/25

실행 결과.

원본

필터 1회 적용

필터 2회 적용

필터 3회 적용

Buy me a coffeeBuy me a coffee
카테고리: AndroidOpenCV

0개의 댓글

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.