Vision – 영상 처리 입문 III

필터링

필터링‘입력 영상에 필터를 씌워서 출력 영상을 만드는 것’입니다.

그럼 필터링은 어떤 방식으로 이루어질까요?

여러 방식이 있지만 주로 ‘합성곱 연산’을 이용합니다.

합성곱 연산은 필터(커널)를 입력 영상에 포개고 픽셀별로 곱셈을 마친 뒤 전부 더한 값을 가운데 픽셀로 지정하는 것입니다.

1) 합성곱 신경망(Convolution Neural Network) - 딥 러닝을 이용한 자연어 처리 입문

첫 입력 영상은 5×5형태이고 출력 영상은 3×3형태입니다.
이 두 영상이 따로 존재한다고 생각하지 마시고, 3×3 출력이 입력 영상의 가운데 위치해 있다고 생각하시면 됩니다.
(영상처리 기준에서 설명)

그러면 경계선은 항상 처리될 수가 없습니다.

이 경계선은 어차피 1픽셀들의 모임이니 영상처리에 큰 부담은 안 주지만 그래도 처리하는 연산이 필요합니다.

그 처리 연산은 아래의 파라미터들을 선택해서 처리할 수가 있습니다.


블러 필터

블러 필터는 잡음을 블러링해서 없는 것처럼 보이게 하는 역할을 합니다.

블러 필터에는 아래와 같이 네 종류가 존재합니다.

  • cv2.blur, cv2.boxFilter: 필터의 weight 총합을 1로 만들고 합성곱 연산을 진행함
  • cv2.GaussianBlur: 가우시안 함수가 가지는 값들을 weight값으로 설정함
    -> 픽셀의 밝기값을 유지하면서 블러링하는 특징이 있음, 전체적으로 똑같이 블러링됨
  • cv2.bilateralFilter: space에 대한 가우시안 값, color에 대한 가우시안 값으로 결정된 필터
    -> 엣지는 블러링 안 하고 엣지가 아닌 영역만 블러링하는 특징이 있음
  • cv2.medianBlur: 중간값을 제외한 부분은 비정상으로 처리함
    (정렬 후 중간 값 선택하는 작업을 반복함)


언샤프 마스크 필터

언샤프 마스크 필터는 샤프닝을 하는 역할을 합니다.
샤프닝은 엣지나 경계선을 더욱 뚜렷하게 하는 작업을 의미합니다.
그런데, 어떻게 언샤프 마스크 필터로 샤프하게 만들 수 있을까요?

언샤프 마스크 필터링의 과정은 아래와 같습니다.

먼저 (a)는 원본 영상의 그래프입니다. 기울기가 변하는 (밝기 값이 확 변하는) 두 부분이 에지(Edge)가 됩니다.

(b)는 블러 필터를 적용하였을 때의 그래프입니다.
엣지 부분이 좀 더 부드러운 모양을 띄게 됩니다.

(c)는 (a)와 (b) 그래프를 빼고 난 뒤의 그래프입니다.
두 그래프의 차이인 엣지 부분만 튀어 나온 그래프입니다.

이 (c) 그래프를 원본 영상에 더한 것이 (d) 그래프입니다.
(d)는 엣지 부분이 더 튀어나온 그래프입니다.

이것을 영상으로 출력해보면 엣지가 더욱 뚜렷하게 나타나는 샤프닝 효과를 보게 되는 것입니다.


영상에서의 미분

영상에서 1차 미분은 에지 존재 여부를 파악하는 용도로 쓰입니다.

1차 미분을 이용한 대표적인 필터로는 ‘sobel filter’가 있습니다.

영상에서 2차 미분은 에지 존재 여부 + 에지 밝기 변화를 파악할 수 있습니다.

2차 미분에는 엣지 부분에서 부호가 바뀌는 영 교차(Zero Crossing)의 특성이 있습니다.
즉 2차 미분 그래프를 보면 엣지 부분에서 0을 지나게 되는데, 이 구간이 방향성을 갖고 있다는 것입니다.
방향성을 가지고 있으니 더 어두워졌는지 밝아졌는지 확인이 가능합니다.

하지만 2차 미분은 잡음에 민감하다는 단점이 있습니다.

따라서 2차 미분으로 엣지 검출을 할 때는
가우시안 필터를 줘서 블러링을 하고 2차 미분(라플라시안)을 적용하는 작업을 합니다.

이것을 바로 LoG 필터링이라고 합니다.


모폴로지 연산

모폴로지 연산은 형태 혹은 모양에 관심이 많습니다.
이 연산은 Image Segmentation에 주로 쓰입니다.

먼저 ‘침식’ 입니다.

침식은 객체 영역을 깎아서 축소시키는 연산입니다.
(b)필터를 이용해서 스캐닝 작업을 합니다. (입력 영상에 차례대로 포개면서 중간 픽셀 값을 결정하는 작업)
이 때 중간을 제외한 나머지 영역 중 검은 색이 하나라도 있으면 중간 픽셀은 없앱니다. (0으로 만듦)

스캐닝을 마친 뒤에는 (c)처럼 침식이 만들어 집니다.

다음은 ‘팽창’입니다.

팽창은 객체 영역을 덧붙여서 확대시키는 연산입니다.
(b)필터를 이용해서 스캐닝 작업을 합니다.
이 때 중간을 제외한 나머지 영역 중 흰 색이 하나라도 있으면 중간 주위의 픽셀들을 추가합니다. (1으로 만듦)

스캐닝을 마친 뒤에는 (d)처럼 팽창이 만들어 집니다.


침식과 팽창을 모두 적용한 것은 ‘Open’입니다.

Open 연산은 침식을 하고 팽창을 진행합니다.
그러면 침식을 통해 노이즈가 제거됩니다. 그러나 객체의 크기가 작아지게 됩니다.
그래서 팽창을 진행해서 객체의 크기를 다시 키웁니다.

즉 노이즈 제거를 목적으로 할 때 Open을 이용합니다.


반대는 ‘Close’입니다.

Close 연산은 팽창을 하고 침식을 진행합니다.
그러면 팽창을 통해 구멍이 메꿔 집니다. 그러나 객체와 잡음이 모두 커지게 됩니다.
그래서 침식을 진행해서 객체의 크기를 다시 작아지게 합니다.

즉 구멍 제거를 목적으로 할 때 Close를 이용합니다.


그렇다면 노이즈도 제거하고 구멍도 제거하려면 어떻게 할까요?
Open연산을 통해 노이즈를 먼저 제거하고, Close연산을 통해 구멍을 제거하면 됩니다.


레이블링

객체별로 숫자를 매기는 작업‘레이블링’이라고 합니다.

레이블링은 객체를 구분하기 위해서 사용합니다.

레이블링을 위한 ‘고전적 레이블링 기법’을 소개하겠습니다.

먼저 1은 오브젝트 픽셀, 0은 배경 픽셀로 지정합니다.
앞으로 숫자가 1이상이면 레이블이 있다고 하고, 0이면 레이블이 없다고 표현하겠습니다.

이후 한 픽셀씩 살펴 보는데 레이블이 있기 전까지는 그냥 지나칩니다.

레이블이 있는 픽셀에 오면 위쪽과 왼쪽의 이웃 픽셀을 살펴 봅니다.

이 때 이웃 픽셀이 모두 레이블이 없으면 현재 보는 픽셀에 레이블(숫자)를 지정합니다.
(숫자는 1부터 차례대로 기록함)

그리고 등가 테이블의 한 행에 레이블(숫자)를 기록합니다. ex) 1-1

만약 이웃 픽셀 중 하나만 레이블이 있는 경우는 그 레이블을 현재 보는 픽셀에 지정합니다.

이웃 픽셀 모두 레이블이 있는 경우는 작은 레이블을 현재 보는 픽셀에 지정합니다.
이후 등가 테이블의 1열에서 큰 레이블이 존재하는 행을 찾고, 그 행의 2열에 작은 레이블을 기록합니다.

레이블이 있는 픽셀들이 붙어 있으니 둘은 서로 같은 레이블로 봐도 괜찮다는 의미입니다.
ex) 4-1 => 레이블4 = 레이블1

위의 작업을 반복합니다.

마지막 레이블까지 확인했다면, 등가 테이블의 2열에 적힌 숫자로 레이블을 모두 변경합니다.

그러면 위와 같이 레이블링이 완료됩니다.


레이블링을 구현하는 OpenCV 함수는 connectedComponentsWithStats입니다.
이 함수는 중심 좌표 및 범위도 알려주기 때문에 유용하게 쓰입니다.


에지 추출

미분을 이용해서도 에지를 추출할 수 있지만 정확한 추출은 어렵다고 합니다.

밝기 값의 차이가 적은 부분은 에지가 끊어진 채로 출력될 수 있기 때문입니다.

이를 극복한 방법은 ‘캐니 에지 검출’ 입니다.

캐니 에지 방법은 이중 임계값을 이용한 검출입니다.

위와 같이 임계값을 두 개로 설정하였을 때,

T(High)보다 큰 구간은 무조건 에지, T(High)보다 작고 T(Low)보다 크면 약한 에지, T(Low)보다 작으면 에지가 아니라고 보는 것입니다.

강한 에지와 연결된 약한 에지는 일반 에지로 봅니다.

이 방법은 Canny 함수를 이용합니다.


허프 변환

허프 변환은 직선이나 원을 검출할 때 사용합니다.

x-y 공간에 에지에 해당하는 직선이 있을 때,
직선 위의 점(에지로 판별되는 모든 점)을 a-b 파라미터 공간에 직선으로 표현하는 것입니다.

a-b공간에서 직선이 교차하는 점을 찾으면 x-y공간 상의 직선 정보를 얻을 수 있습니다.
이 때, 축적 배열(accumulation array)을 사용한다고 합니다.

이 방법은 HoughLinesP, HoughCircles 함수를 이용합니다.


GitHub에 파이썬 코드를 제공하겠습니다.
필자의 GitHub는 메인 화면 배너에 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *