OpenCV 비전 실무10장 · Sobel 과 Laplacian 경계 검출11 / 21← 이전목차다음 →MetaContents

10장. Sobel 과 Laplacian 경계 검출

노이즈와 블러 먼저 하기

시끄러운 카페에서 친구 목소리를 들으려고 귀를 바짝 세우면, 옆 테이블의 그릇 소리까지 크게 들립니다. "소리가 바뀌는 순간"에 민감해질수록 잡음에도 민감해집니다. 경계 검출이 그렇습니다. 옆 칸끼리 빼면 진짜 경계뿐 아니라 노이즈로 생긴 작은 들쭉날쭉까지 변화량으로 잡힙니다. 두 번 빼는 Laplacian 은 더 민감합니다. 그래서 6장에서 본 Gaussian 블러로 노이즈를 먼저 누그러뜨린 뒤 경계를 찾습니다.

노이즈 사진, Gaussian 블러 5×5, Sobel 이나 Laplacian, 임계값의 네 단계 흐름도

그림의 네 단계가 노이즈 낀 그림에서 경계를 찾는 순서입니다. 둘째 단계의 블러가 핵심입니다. 블러 뒤에 Laplacian 을 거는 짝은 따로 LoG(Laplacian of Gaussian)라는 이름이 있을 만큼 흔합니다. 여기서 옆 테이블의 그릇 소리가 노이즈이고, 귀를 바짝 세우는 일이 빼기입니다.

노이즈 낀 도형 그림에서 블러 없이 구한 Sobel 크기와 Laplacian, Gaussian 5×5 블러 뒤에 구한 Sobel 크기와 Laplacian 을 2행 3열로 놓은 그림

위 줄이 블러 없이, 아래 줄이 Gaussian 5×5 블러 뒤에 구한 결과입니다. 노이즈는 6장에서 본 것과 같은 꼴(표준편차 20)이고 씨앗은 1010 입니다. 위 줄의 Laplacian(오른쪽 위)은 바탕 전체가 자글자글해 도형의 테두리를 알아보기 어렵습니다. Sobel 크기(가운데 위)도 바탕이 지글거리지만 Laplacian 보다는 덜합니다. 블러를 먼저 건 아래 줄은 바탕이 거의 검고 테두리만 남았습니다.

블러 없이와 블러 먼저 견주기

도형 사이의 고른 바탕(세로 125~144, 가로 150~309)에서 크기가 100 을 넘는 칸, 곧 "노이즈를 경계로 잘못 찾은 칸"의 비율입니다.

입력바탕의 밝기 표준편차Sobel 크기 > 100|Laplacian(ksize 3)| > 100
노이즈 없는 원본0.00.0000.000
노이즈 (표준편차 20)20.10.3720.591
노이즈 → Gaussian 5×55.50.0000.000

노이즈만 더해도 바탕의 37% 넘는 칸을 Sobel 이 경계로 잘못 찾고, Laplacian 은 59% 넘게 잘못 찾습니다. 블러를 먼저 걸면 바탕의 흔들림이 20.1 에서 5.5 로 줄어 잘못 찾는 칸이 없어집니다.

짧은 예시

Python
import cv2
import numpy as np

img = cv2.imread("ch10_shapes.png", cv2.IMREAD_GRAYSCALE)
# 6차시에서 본 것과 같은 꼴의 가우시안 노이즈. 씨앗 1010, 표준편차 20
rng = np.random.default_rng(1010)
noisy = np.clip(img.astype(np.float64) + rng.normal(0, 20, img.shape), 0, 255).astype(np.uint8)

for name, src in [("블러 없이", noisy), ("블러 먼저", cv2.GaussianBlur(noisy, (5, 5), 0))]:
    mag = cv2.magnitude(cv2.Sobel(src, cv2.CV_64F, 1, 0), cv2.Sobel(src, cv2.CV_64F, 0, 1))
    # 고른 바탕에서 크기가 100 을 넘는 칸의 비율
    print(name, round(float((mag[125:145, 150:310] > 100).mean()), 3))
# 결과: 블러 없이 0.372 / 블러 먼저 0.0

주의할 점

  • 블러를 너무 세게 걸면 진짜 경계도 흐려져 약해지고 굵어집니다. 5×5 쯤에서 시작해 결과를 보며 고릅니다.
  • 블러 크기를 바꾸면 기울기 값의 크기도 바뀌므로, 임계값도 다시 봅니다.
← 이전 절10장 · Laplacian: 변화량의 변화량다음 절 →10장 · 경계만 남기기와 두 방법 견주기