필터링이란 영상에서 원하는 정보만 통과시키고 나머지는 걸러내는 작업이다.

이를 통해 잡음을 걸러내어 영상을 깔끔하게 만들거나 부드러운 느낌을 걸러내서 날카로운 느낌의 영상을 만들수 있다.

 

필터링은 마스크, 커널, 윈도우, 필터 등으로 불리는 작은 크기의 행렬을 이용하는데 필터링 연산의 결과는 행렬의 모양과 원소의 값에 의해 결정되며 진한 색을 갖는 고정점을 기준 픽셀로 필터링 작업을 수행한다.

 

필터 마스크 행렬은 모든 원소 합이 1 또는 0이 되도록 설계하면 필터링 결과 영상의 평균 밝기가 입력 영상 평균 밝기와 같게 유지된다. 1 보다 작을 경우 영상의 평균 밝기가 어두워지고 1보다 크면 좀 더 밝아진다.

 

void filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT );

 

src : 입력영상

dst : 출력영상

ddepth : 결과 영상 깊이. -1을 지정하면 출력 영상의 깊이는 입력 영상과 같게 설정된다.

kernel : 필터링 마스크, 커널 이라고도 불리며 1채널 실수형 행렬

anchor : 고정점 좌표, Point(-1, -1)을 값으로 지정하면 마스크 행렬 중심을 고정점으로 사용한다.

delta : 필터링 연산 후 추가적으로 더할 값

borderType : 가장자리 픽셀 확장 방식

 

입력 영상의 깊이에 따라 지정 가능한 ddepth 값이 달라진다.

입력 영상의 깊이(src.depth()) 지정 가능한 ddepth 값
CV_8U -1 / CV_16S / CV_32F / CV_64F
CV_16U / CV16S -1 / CV_32F / CV_64F
CV_32F -1 / CV_32F / CV_64F
CV_64F -1 / CV_64F

가장자리 픽셀 처리 방법

BorderTypes 열거형 상수 설명
BORDER_CONSTANT 0 0 0 | a b c d e f g h | 0 0 0
BORDER_REPLICATE a a a | a b c d e f g h | h h h
BORDER_REFLECT c b a | a b c d e f g h | h g f
BORDER_REFLECT_101, BORDER_REFLECT101, BORDER_DEFAULT d c b | a b c d e f g h | g f e

 

* 엠보싱 필터링

-1 -1 0
-1 0 1
0 1 1

위의 행렬을 마스크값으로 지정하면 된다.

- 입력영상에서 픽셀값 변화가 적은 평탄한 영역은 결과영상 픽셀 값이 0에 가까운 값을 가지게 된다. (회색이 된다.)

- 입력영상에서 대각선 방향으로 픽셀 값이 급격하게 변하는 부분에서 결과 영상 필셀 값이 0 보다 훨씬 크거나 또는 0 보다 훨씬 작은 값을 가지게 된다. (밝거나 어두워진다)

- 음수 값은 포화연산에 의해 0이 되어버리기 때문에 결과 영상에 128을 더하는게 보기에 좋다.

 

* 블러링 필터

스무딩이라고도 불리며 뜻 그대로 영상을 부드럽게 만드는 필터링 기법이다. 입력영상에 존재하는 잡음의 영향을 제거하는 전처리 과정으로도 사용된다.

- 입력영상에서 인접한 픽셀 간의 픽셀 값 변화가 크지 않은 경우 초점이 맞지 않은 사진처럼 부드러운 느낌을 받을 수 있다.

 

* 평균값 필터

- 입력 영상에서 특정 픽셀과 주변 픽셀들의 산술 평균을 결과 영상 픽셀값으로 설정하는 필터이다.

- 평균값 필터에 의해 생성되는 결과 영상은 픽셀값의 급격한 변화가 줄어들어 날카로운 에지가 무뎌지고 잡음의 영향이 크게 사라지는 효과가 있다.

- 과도한 평균값 필터 적용은 사물의 경계가 흐릿해지고 사물의 구분이 어려워진다.

- 마스크 행렬의 크기가 커지면 커질수록 더욱 부드러운 느낌의 결과 영상을 생성한다.

- 원소 값은 1/(행의 길이 * 열의 길이) 이다.

 

void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );

 

ksize : 블러링 커널 크기

 

* 가우시안 필터

- 평균값 필터보다 자연스러운 블러링 결과를 생성한다.

- 가우시안 분포함수로 생성한 필터 마스크를 사용하는 필터링 기법이다.

- 평균이 0이고 표준편차가 σ 인 1차원 가우시안 분포함수를 사용한다.

- 마스크 행렬의 중앙부는 비교적 큰 값을 가지며 주변부로 갈수록 0에 가까운 작은 값을 가진다.

- 필터링 대상 픽셀과 멀리 떨어져 있는 주변부에 가중치를 조금 주는것으로 가중평균을 구하는것과 같다. 마스크가 가중 평균을 구하기 위한 가중치 행렬 역할을 한다.

- 표준편차 값이 커지면 마스크 크기도 함께 커지며 연산량은 마스크 크기에 비례한다.

- 2차원 가우시안 마스크 행렬을 이용한 필터링은 1차원 가수시안 마스크 행렬과 전치행렬로 필터링한 것과 같은 결과를 얻을 수 있으며 이를 통해 연산량을 줄일 수 있다.

- CV_8U 깊이의 영상은 6σ+1 크기의 필터 마스크를 사용한다. 필터 마스크 크기를 반올림하여 만든 정수 값이 짝수이면 1을 더하여 홀수로 만든다.

 

void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );

 

sigmaX : x 방향 가우시안 마스크 표준편차

sigmaY : y 방향 가우시안 마스크 표준편차. 값이 0이면 sigmaX와 같은 값을 사용한다. sigmaX도 0 일 경우 ksize로부터 표준편차를 계산해 사용한다.

 

Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F );

 

ksize : 마스크 크기, ksize는 0 보다 큰 홀수여야 한다.  (8*sigma+1) 보다 같거나 크게 지정하는것이 좋다.

sigma : 가우시안 표준 편차. 0 or 음수로 지정하면 0.3*((ksize-1)*0.5-1)+0.8

반환값 : ksize x 1 크기의 가우시안 필터 마스크. ksize<=7 || sigma<=0 인 경우 미리 정해놓은 커널행렬을 생성한다.

 

* 샤프닝 필터

샤프닝이란 날카로운 느낌이 나게하는 필터링 기법으로 날카로운 느낌이란 초점이 잘 맞는 사진처럼 객체의 윤곽이 뚜렷하게 구분되는것을 의미한다.

 

* 언샤프 마스크 필터

이미 촬영된 사진을 초점이 잘맞는 사진처럼 보이게끔 변경하려면 영상 에지 근방에서 픽셀 값의 명암비가 커지게 수정해야한다. 이때 사용되는 샤프닝 기법은 블러링이 적용된 날카롭지 않은 영상. 즉 언샤프를 이용하며 언샤프 마스크 필터라고 불린다.

f = 입력영상

f' = 블러링이 적용된 f

g = f-f'

h = f+g 라 할때

g는 입력영상(f) 값이 증가하기 시작하는 부근에서 음수값을 증가가 멈추는 부근에서 양수값을 가지며 입력영상(f)에서 부드러워진 입력영상(f')을 뺀. 오직 입력영상의 날카로운 성분만을 가지고 있는 함수라고 할 수 있다.

그러므로 h는 입력영상에 날카로움(에지)을 더함으로써 날카로운 성분이 강조된 최종 영상이 된다.

이때 실수 가중치를 곱한 후 더하면 날카로운 정도를 조절할 수 있다.

최종적으로 h = f+ 가중치 * g 가 되며 정리하면

언샤프를 적용하는식은 (1 + 가중치) * f - 가중치 * f' 이다.

 

void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );

언샤프에 쓰일 블러링 영상을 만들때 sigma 값을 크게할수록 과장된 느낌의 샤프닝 결과영상이 나온다.

 

* 잡음 제거 필터링

어떠한 환경에서건 촬영된 영상은 크든 작든 원치 않은 잡음을 포함할 수 있다. 이러한 잡음은 광학적 신호를 전기적 신호로 변환하는 센서에서 주로 추가된다.

 

* 잡음 모델

잡음이 생성되는 방식

 

* 가우시안 잡음 모델

보통 평균이 0인 가우시안 분포를 따르는 잡음

 

- 가우시안 분포에 따르면 전체데이터가

± σ 구간에는 67%

± 2σ 구간에는 95%

± 3σ 구간에는 99.7% 존재한다. 

 

void randn(InputOutputArray dst, InputArray mean, InputArray stddev);

dst : 가우시안 난수로 채울 행렬. 미리 할당 되어 있어야 한다. 자료형에 맞게 자동으로 포화연산이 수행된다.

mean : 가우시안 분포 평균. 0일 경우 양수와 음수가 섞여있는 난수가 발생하므로 부호 있는 자료형 행렬(CV_32S, CV_32F)을 사용해야 한다.

stddev : 가우시안 분포 표준편차. 값이 증가함에 따라 잡음의 영향이 커진다. 반대로 작을수록 잡음에 의한 픽셀 값 변화가 적다.

 

가우시안 잡음(가우시안 분포를 따르는 난수)으로 구성된 행렬을 생성해서 dst에 반환한다. 이렇게 생성된 잡음(dst)을 원본영상에 add 하면 잡음이 추가된 영상이 된다.

 

* 가우시안 필터

영상에 포함되는 대부분의 잡음은 가우시안 잡음에 속하며 이 잡음을 제거하기 위해 가우시안 필터를 사용한다.

해당 필터는 잡음제거와 함께 블러링 효과를 입히는데

픽셀 값이 크게 변하지 않는 영역(평탄한 영역)에선 블러링 되면서 잡음의 영향을 크게 줄여주지만 급격하게 변경되는 영역(에지)에선 잡음뿐만 아니라 객체의 윤곽이 흐릿해진다.

 

* 양방향 필터

잡음과 에지를 함께 제거하는 가우시안 필터의 단점을 극복하기 위한 에지 보전 잡음 제거 필터 토마시가 제안한 알고리즘이다.

 

f를 입력영상

g를 출력영상

p,q 를 픽셀의 좌표

S를 필터 크기

w를 양방향 필터 마스크 합이 1이 되도록 만드는 정규화 상수

 

f(p) 를 p점에서의 입력 영상 픽셀 값

f(p) 를 p점에서의 출력 영상 픽셀 값

G(σ) 는 표준편차가 σ인 가우시안 분포 함수

 

G(σ)(||p - q||) 를 두 점 사이의 거리에 대한 가우시안 함수 (가우시안 필터와 같은 의미로 동작)

G(σ)(|f(p) - f(q)|) 는 두 점의 픽셀 값 차이에 의한 가우시안 함수 라 할때

토마시의 양방향 필터 알고리즘

양방향 필터의 함수는 두 개의 가우시안 합수 곱으로 구성되어 있다.

 

- G(σ)(|s(p) - s(q)|) 함수는 픽셀 값이 크게 변하지 않는 영역(차이가 적은 평탄한 영역)에선 큰 가중치를

급격하게 변경되는 영역(차이가 큰 에지 근방)에선 상대적으로 0에 가까운 가중치를 할당해주므로 블러링 효과가 거의 없어 에지가 보존된다.

 

- 양방향 필터 마스크는 모든 픽셀 위치에서 주변 픽셀과의 값(밝기) 차이에 따라 고유의 마스크를 가지므로 모든 픽셀에서 서로다른 형태를 갖게된다. 그러므로 일반적인 가우시안 필터가 모든 픽셀에 같은 가우시안 마스크 필터를 사용하는것보다 많은 연산량을 필요로 한다.

 

void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );

d : 필터링에 사용할 이웃 픽셀과의 거리. 음수를 지정하면 sigmaSpace로부터 자동 계산된다.

sigmaColor : 색 공간에서의 가우시안 필터 표준 편차. 에지를 보존할(블러링을 적용하지 않을) 밝기차의 기준점으로 

작게 지정하면 픽셀 값 차이가 큰 주변 픽셀과는 블러링이 적용되지 않지만

크게 지정하면 차이가 크더라도 블러링이 적용된다. 즉, 기준점 이상의 밝기차는 에지를 유지시킨다.

sigmaSpace : 좌표 공간에서의 가우시안 필터 표준 편차. 일반적인 가우시안 필터링에서 아용하는 표준편차와 같다. 값이 클수록 더 많은 주변 픽셀을 고려해서 블러링을 수행한다. 

 

* 미디언 필터

입력영상에서 자기 자신 픽셀과 주변 픽셀 값의 중간값을 결과영상 픽셀 값으로 지정하는 필터로 잡음 픽셀 값이 주변 픽셀 값과 큰 차이가 있는 경우(소금 & 후추 잡음. 픽셀값이 0 또는 255로 변경되는 형태의 잡음)에 효과적이다.

 

void medianBlur( InputArray src, OutputArray dst, int ksize );

src : 입력영상. 1,3,4 채널 영상을 지정할수 있으며 ksize가 3 or 5 이면 src는 CV_8U, CV_16U, CV_32F의 깊이를 가질 수 있다. 그 이상의 필터 크기에서는 CV_8U 깊이만 사용할 수 있다.

ksize : 필터크기. 3보다 같거나 큰 홀수를 지정할 수 있다. ksize * ksize 크기를 이용한다.

 

- 내부적으로 BORDER_REPLICATE 방식으로 가장자리 외곽 픽셀 값을 설정하여 필터링을 수행한다.

'공부 > OpenCV' 카테고리의 다른 글

레이블링  (0) 2019.08.16
어파인 변환  (0) 2019.07.30
영상의 연산  (0) 2019.07.19
OpenCV (Open Computer Vision)  (0) 2019.05.29

+ Recent posts