5.13. 선형 및 이웃 필터¶
이 장 앞부분의 픽셀 수학 연산은 두 이미지를 점별로 결합했습니다. 필터는 관련된 작업을 다른 방식으로 수행합니다. 즉, 모든 출력 픽셀의 값을 해당 위치를 둘러싼 입력 픽셀의 작은 이웃으로부터 계산합니다. (x, y) 위치의 출력은 (x, y)를 중심으로 한 작은 상자 안에 있는 입력 픽셀들의 어떤 통계량 – 평균, 중앙값, 가장 흔한 값 – 입니다.
이러한 관점의 작은 변화 – 한 번에 한 픽셀씩 처리하던 것에서 한 번에 픽셀 윈도우를 처리하는 것으로 옮겨가는 것 – 가 유용한 연산들의 전체 계열을 작동하게 만듭니다. 작은 윈도우에 대한 단순 평균은 센서 노이즈를 매끄럽게 제거합니다. 같은 윈도우에 대한 중앙값은 에지를 덜 부드럽게 만들면서 단일 픽셀 스페클을 제거합니다. 양방향 평균(bilateral average)은 강한 대비 경계를 가로질러 매끄럽게 만드는 것을 거부하여, 물체의 에지를 보존하면서 그 내부의 텍스처를 정리합니다. 이웃이 작업의 단위이며, 통계량의 선택이 필터가 무엇을 할지 결정합니다.
5.13.1. 커널 크기¶
모든 이웃 필터는 윈도우의 반경을 픽셀 단위로 설정하는 size 매개변수를 받습니다. 윈도우 자체는 정사각형이며 각 변에서 (2 * size + 1) 픽셀을 덮습니다 – 따라서 size=1은 3×3 이웃, size=2는 5×5, size=3은 7×7 등을 의미합니다.
이웃은 이미지를 가로질러 좌측 상단에서 우측 하단으로 한 번에 한 픽셀씩 미끄러져 갑니다. 각 출력 픽셀은 그것을 중심으로 한 입력 이웃에 필터의 통계량을 적용한 결과입니다.¶
크기가 클수록 이웃이 커지며, 이는 더 매끄러운(또는 더 강력한) 필터링을 의미합니다. 비용은 윈도우의 면적에 따라 증가하므로, size=3 필터는 픽셀당 size=1 필터의 약 9배의 작업을 수행합니다. 대부분의 정리 작업에 대한 실용적인 기본값은 size=1 또는 size=2입니다. 작은 이웃으로는 애플리케이션이 억제하려는 특징을 억제하기에 충분하지 않을 때에만 더 큰 크기를 사용하십시오.
5.13.2. 평균 필터¶
mean()은 각 픽셀을 그 이웃의 산술 평균으로 대체합니다. 그 결과 픽셀 간 변화가 윈도우 크기에 걸쳐 매끄러워지며, 이는 센서 노이즈 스페클을 억제하는 가장 저렴한 방법입니다. 고주파 변화는 평균화되어 사라지고 저주파 내용은 살아남습니다.
그 대가로 에지와 다른 선명한 특징들도 평균화됩니다. 필터 적용 전에 한 픽셀 너비였던 밝은 에지는 size=1 평균 필터 적용 후 두세 픽셀 너비가 되며, 가장자리에서 밝기가 점차 낮아집니다. 텍스처가 적은 이미지(깨끗한 벽, 색상 마커의 내부)에서 순수한 노이즈 감소를 위해서라면 이 절충은 괜찮습니다. 에지가 중요한 복잡한 장면에서는 보통 다음 필터 중 하나가 더 적합합니다.
img.mean(1) # 3x3 box average -- fast, gentle smoothing
img.mean(2) # 5x5 box average -- stronger, slower
5.13.3. 중앙값, 최빈값, 중간점¶
다른 세 가지 통계적 이웃 필터는 단순 산술 평균을 이상치(outlier)에 더 강건한 무언가로 대체합니다.
median()은 이웃의 중앙값 – 정렬된 윈도우 픽셀 목록의 가운데에 오는 값 – 을 반환합니다. 윈도우 안의 매우 밝거나 매우 어두운 단일 픽셀은 중앙값을 끌어당기지 않습니다. 그저 버려지는 극단값 중 하나가 될 뿐입니다. 실질적인 효과는 중앙값 필터링이 mean처럼 에지를 부드럽게 만들지 않으면서 단일 픽셀 스페클과 소금-후추 노이즈를 제거한다는 것입니다. 그 비용은 픽셀당 더 많은 계산 – 윈도우를 정렬하는 것은 평균을 내는 것보다 느립니다 – 이며, 그 결과가 엄밀히 평균은 아니어서 후속 수학 처리에서 때때로 문제가 될 수 있습니다.
percentile 매개변수(기본값 0.5)는 선택되는 값을 엄밀한 중앙값에서 벗어나게 이동시킵니다. percentile=0.0은 이웃의 최솟값을, percentile=1.0은 최댓값을 반환하며, 중간 값들은 정렬된 윈도우에서 그 사이를 비례적으로 선택합니다. 이는 median에게 순서 통계량의 이상치 강건성을 잃지 않으면서 이웃의 어두운 부분이나 밝은 부분을 강조하는 능력을 부여합니다.
mode()는 이웃에서 가장 흔한 값을 반환합니다. 노이즈 모델이 “대부분의 픽셀은 올바르고, 일부가 정도의 차이를 두고 손상되었다”인 경우에 유용하며, 이때 올바른 답은 가장 자주 나타나는 값입니다 – 손상된 값들이 정렬된 윈도우의 한쪽에 몰려 있을 때 중앙값은 이를 놓칠 수 있습니다.
midpoint()는 이웃의 최솟값과 최댓값의 가중 조합을 반환합니다 – bias=0.5는 둘 사이의 중간점을, bias=0.0은 최솟값을, bias=1.0은 최댓값을 제공합니다. 다른 것들보다 덜 흔하게 사용되지만, 어두운 특징이나 밝은 특징을 추출하는 것이 목표일 때 알아두면 유용합니다.
5.13.4. 양방향 필터, 에지를 보존하는 버전¶
bilateral()은 가장 잘 이해할 가치가 있는 이웃 필터입니다. 이것은 mean()의 평활화 효과를 내지만 추가 제약이 있습니다. 이웃 픽셀이 중심 픽셀과 차이가 클수록, 평균에서 차지하는 비중이 작아집니다. 그 결과 모든 균일한 영역의 내부를 매끄럽게 만들면서도 그 영역들을 구분하는 에지를 가로질러 번지지 않으며, 이는 정확히 대부분의 애플리케이션이 실제로 원하는 것입니다.
두 매개변수가 필터가 얼마나 적극적으로 픽셀의 비중을 낮추는지를 제어합니다:
color_sigma는 색상 차이가 가중치에 어떻게 영향을 미치는지를 결정합니다. 값이 작을수록 필터가 중심과 다른 픽셀의 비중을 낮추는 데 더 엄격해집니다.space_sigma는 공간적 거리가 가중치에 어떻게 영향을 미치는지를 결정합니다. 값이 작을수록 중심에 가까운 픽셀에 더 많은 가중치를 줍니다.
기본값(color_sigma=0.1, space_sigma=1.0)은 합리적인 출발점입니다. 이를 조정하는 것은 보통 샘플 프레임에서 필터를 실행하고 에지가 선명하고 내부가 깨끗해질 때까지 조정하는 문제입니다.
양방향 필터는 median()보다 비용이 많이 들고 mean()보다 훨씬 더 비용이 많이 듭니다. 따라서 에지 보존 동작이 애플리케이션에 필요한 바로 그것일 때에만 사용할 가치가 있습니다.
5.13.5. 적응형 임계값 처리¶
평균, 중앙값, 최빈값, 중간점 필터는 모두 그 출력을 이진 임계값으로 바꾸는 동일한 키워드 인자 쌍을 가지고 있습니다:
threshold=True는 필터를 임계값 처리 모드로 전환합니다.offset=N은 비교 전에 로컬 컷오프를N단위만큼 이동시킵니다.
그 메커니즘은 필터의 일반적인 동작 위에 직접 구축됩니다. threshold=True 없이는, 필터가 이웃에 대해 통계량을 계산하고 그 통계량을 출력 픽셀에 씁니다. threshold=True를 사용하면, 필터가 동일한 통계량을 계산한 다음, 같은 위치의 원본 픽셀을 통계량 더하기 오프셋과 비교하고, 원본이 더 크면 포맷의 최댓값을, 그렇지 않으면 0을 씁니다.
그 결과는 컷오프가 프레임 전체에 걸쳐 로컬 밝기에 따라 이동하는 이진 이미지입니다. 밝은 영역은 높은 컷오프를, 어두운 영역은 낮은 컷오프를 가지며, 이웃보다 국소적으로 더 밝은 전경 픽셀은 밝은 영역에 있든 어두운 영역에 있든 일치합니다 – 이는 정확히 단일 전역 임계값으로는 고르지 않게 조명된 이미지에서 만들어낼 수 없었던 동작입니다.
img.mean(3, threshold=True, offset=5)
offset 매개변수는 애플리케이션이 테스트가 얼마나 엄격한지를 제어하는 곳입니다. 작은 양의 오프셋은 일치로 간주되기 전에 원본 픽셀이 이웃보다 측정 가능할 정도로 더 밝을 것을 요구하며, 이는 희미한 전경을 누락시키는 대가로 센서 노이즈 거짓 양성을 억제합니다. 작은 음의 오프셋은 일부 노이즈를 통과시키는 대가로 희미한 전경을 잡아냅니다. 그 선택은 파이프라인의 나머지 부분이 이진 출력을 가지고 무엇을 할 것인지에 달려 있습니다.
고르지 않은 조명 아래에서는 단일 전역 임계값이 모든 위치의 전경을 기술할 수 없습니다. threshold=True로 실행한 이웃 필터는 로컬 밝기에 따라 이동하는 컷오프를 만들어내며 프레임 전체에 걸쳐 전경을 올바르게 분류합니다.¶
이 필터 계열이 적응형 임계값을 실행하므로 올바른 필터를 고르는 것이 중요합니다. 가장 저렴한 적응형 임계값에는 mean()을, 입력에 로컬 컷오프를 계산하기 전에 필터가 걸러내야 할 소금-후추 노이즈가 있을 때는 median()을 사용하십시오.