본문으로 바로가기

소벨(Sobel)

대표적인 필터로 Prewitt 필터에 픽셀의 가중치를 두 배로 두었습니다.

상대적으로 대각선 검출에 약한 Prewitt 필터에 비해 Sobel 은 수평, 수직, 대각선 검출에 모두 강합니다.

 

cv2.Sobel(src, ddepth, dx, dy ~ ) -> dst

  • src: 입력 이미지
  • ddept: 출력 이미지 데이터 타입 (-1, 입력 이미지와 동일)
  • dx, dy: x,y 방향 미분 차수 (0, 1, 2)
  • dst: 출력 이미지
import cv2
import os
import numpy as np

path = os.path.join('image', 'sudoku.jpg')
src = cv2.imread(path)

dx = cv2.Sobel(src, -1, 1, 0)
dy = cv2.Sobel(src, -1, 0, 1)

cv2.imshow('src', src)
cv2.imshow('dx', dx)
cv2.imshow('dy', dy)

cv2.waitKey()
cv2.destroyAllWindows()

원본

x 방향 미분

dx = cv2.Sobel(src, -1, 1, 0)

 

y 방향 미분

dy = cv2.Sobel(src, -1, 0, 1)

 

샤르(Scharr)

Prewitt 필터에 픽셀의 가중치를 (3, 10, 3) 배로 증가했습니다.

수평, 수직, 대각선 검출에 모두 강합니다.

 

cv2.Scharr(src, ddepth, dx, dy ~ ) -> dst

  • src: 입력 이미지
  • ddept: 출력 이미지 데이터 타입 (-1, 입력 이미지와 동일)
  • dx, dy: x,y 방향 미분 차수 (0, 1, 2)
  • dst: 출력 이미지
import cv2
import os
import numpy as np

path = os.path.join('image', 'lenna.jpeg')
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)

dx = cv2.Scharr(img, -1, 1, 0)
dy = cv2.Scharr(img, -1, 0, 1)

cv2.imshow('img', img)
cv2.imshow('dx', dx)
cv2.imshow('dy', dy)

cv2.waitKey()
cv2.destroyAllWindows()

원본

 

x 방향 미분

dx = cv2.Scharr(img, -1, 1, 0)

 

y 방향 미분

dy = cv2.Scharr(img, -1, 0, 1)

 

라플라시안(Laplacian)

대표적인 2차 미분 필터로 잡음 성분에 매우 민감하여 더 많은 엣지를 검출하는 경향이 있습니다.

따라서 적용하기전에 잡음을 제거하는게 좋습니다.

 

cv2.Laplacian(src, ddepth, scale, delta ~ ) -> dst

  • src: 입력 이미지
  • ddept: 출력 이미지 데이터 타입 (-1, 입력 이미지와 동일)
  • scale: 결과에 추가적으로 곱할 값
  • delta: 결과에 추가적으로 더할 값
  • dst: 출력 이미지
import cv2
import os
import numpy as np

path = os.path.join('img', 'img.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)

def onChange_scale(k):
    if k == 0:
        cv2.imshow('scale', src)
    else:
        dst = cv2.Laplacian(src, -1, scale=k)
        cv2.imshow('scale', dst)

def onChange_delta(k):
    if k == 0:
        cv2.imshow('delta', src)
    else:
        dst = cv2.Laplacian(src, -1, delta=k)
        cv2.imshow('delta', dst)

dst = cv2.Laplacian(src, -1)
cv2.imshow('src', src)
cv2.imshow('basic', dst)

cv2.imshow('scale', src)
cv2.imshow('delta', src)

cv2.createTrackbar('scale', 'scale', 0, 10, onChange_scale)
cv2.createTrackbar('delta', 'delta', 0, 100, onChange_delta)

cv2.waitKey()
cv2.destroyAllWindows()

원본

 

스케일 옵션을 트랙바를 이용하여 비교해 보았습니다.

 

델타 옵션을 트랙바를 이용하여 비교해 보았습니다.

 

Magnitude calculation

 

cv2.magnitude(x, y, magnitude=None) -> magnitude

  • x: 2D 벡터의 x좌표 행렬(실수형)
  • y: 2D 벡터의 y좌표 행렬(실수형)
  • maginitude: 2D 벡터의 크기 행렬, x와 같은 크기 & 데이터타입
import cv2
import os
import numpy as np

path = os.path.join('img', 'img.jpg')
src = cv2.imread(path, cv2.IMREAD_GRAYSCALE)

sobel_dx = cv2.Sobel(src, cv2.CV_32F, 1, 0)
soble_dy = cv2.Sobel(src, cv2.CV_32F, 0, 1)

sobel_mag = cv2.magnitude(sobel_dx, soble_dy)
sobel_mag = np.clip(sobel_mag, 0, 255).astype(np.uint8)

cv2.imshow('src', src)

cv2.imshow('sobel_dx', sobel_dx)
cv2.imshow('soble_dy', soble_dy)

cv2.imshow('sobel_mag', sobel_mag)

cv2.waitKey()
cv2.destroyAllWindows()

원본

소벨 필터를 활용합니다.

sobel_dx = cv2.Sobel(src, cv2.CV_32F, 1, 0)
soble_dy = cv2.Sobel(src, cv2.CV_32F, 0, 1)

 

각 축으로 미분한 결과를 이용합니다.

sobel_mag = cv2.magnitude(sobel_dx, soble_dy)
sobel_mag = np.clip(sobel_mag, 0, 255).astype(np.uint8)