영상 매체에서 선정적이거나 부정적인 의미를 담고 있는 물체를 가릴 때 흔히 사용하는 모자이크에는 어떤 원리가 들어있을까?
자세히 보면 알 수 있듯이 하나의 픽셀마다 각각 다른 색으로 보이는 것을 확인할 수 있다. 필터링도 유사한 의미를 갖고 있다.
정의를 보면, 필터링이란 영상에서 필요한 정보만 통과시키고 원하지 않는 정보는 걸러내는 작업을 의미한다.
여러가지 필터링 기법이 있고, 크게 두 가지로 나눌 수 있다.
1. 주파수 공간에서의 필터링
2. 공간적 필터링
1) 영상 부드럽게 만들기
2) 영상 날카롭게 만들기
3) edge 검출
4) 잡음 제거
cv2.filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None,borderType=None) ->dst
1) src : 입력 영상
2) ddepth : 출력 영상 데이터 타입 (-1을 지정하면 src와 같은 타입의 dst 영상을 생성)
3) kernel : 필터 마스크 행렬. 실수형
4) anchor : 고정점 위치 (-1,-1)이면 필터 중앙을 고정점으로 사용
5) delta : 추가적으로 더할 값
6) borderType : 가장자리 픽셀 확장 방식
7) dst : 출력 영상
: 영상의 특정 좌표 값을 주변 픽셀 값들의 산술 평균으로 설정
import sys
import numpy as np
import cv2
src=cv2.imread('rose.bmp',cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed')
sys.exit()
kernel=np.array([[1/9,1/9,1/9],
[1/9,1/9,1/9],
[1/9,1/9,1/9]],dtype=np.float64)
# kernel의 각 요소를 1/9로 하는 평균값 필터 적용
dst=cv2.filter2D(src,-1,kernel)
cv2.imshow('src',src)
cv2.imshow('dst',dst)
cv2.waitKey()
cv2.destroyAllWindows()
c2.blur(src, ksize, dst=None, anchor=None, brderType=None) -> dst
1) src : 입력 영상
2) ksize : 평균값 필터 크기. (width, height) 형태의 튜플
3) dst : 결과 영상. 입력 영상과 같은 크기 & 같은 타입
import sys
import numpy as np
import cv2
src = cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
cv2.imshow('src', src)
for ksize in (3, 5, 7):
dst = cv2.blur(src, (ksize, ksize))
# ksize 만큼 blur 처리를 함
desc = 'Mean: {}x{}'.format(ksize, ksize)
cv2.putText(dst, desc, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
1.0, 255, 1, cv2.LINE_AA)
# 10,30 위치에 desc 문장을 SIMPLEX 폰트로 적음
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None) -> dst
1) src : 입력 영상
2) dst : 출력 영상. src와 같은 크기, 같은 타입
3) ksize : 가우시안 커널 크기. (0,0)을 지정하면 sigma 값에 의해 자동으로 결정된다.
4) sigmaX : x방향 sigma
5) sigmaY : y방향 sigma
6) borderType : 가장자리 픽셀 확장 방식
stc=cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)
cv2.imshow('src', src)
for sigma in range(1,6):
dst=cv2.GaussianBlur(src, (0,0), sigma)
desc='sigma={}'.format(sigma)
cv2.putText(dst, desc, (10,30), cv2.FONT_HERSHET_SIMPLEX,
1.0, 255, 1, cv2.LINE_AA)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
: 부드러워진 영상을 이용하여 날카로운 영상을 생성
import sys
import numpy as np
import cv2
src = cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
blr = cv2.GaussianBlur(src, (0, 0), 2) # sigma를 2로 고정
dst = np.clip(2.0*src - blr, 0, 255).astype(np.uint8)
# clipping해서 일정 값을 넘지 못하도록 함
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
src=cv2.imread('rose.bmp')
src_ycrcb=cv2.cvtColor(src, cv2.COLOR_BGR2YCrCb)
# BGR 형식의 이미지를 YCrCb 형식으로 변환
src_f=src_ycrcb[:,:,0].astype(np.float32)
blr=cv2.GaussianBlur(src_f,(0,0),2.0)
src_ycrcb[:,:,0]=np.clip(2.* src_f-blr,0,255).astype(np.uint8)
dst=cv2.cvtColor(src_ycrcb, cv2.COLOR_YCrCb2BGR)
: 영상의 픽셀 값에 추가되는 원치 않는 형태의 신호
: 주변 픽셀들의 값을 정렬하여 그 중앙 값으로 픽셀 값을 대체
-> 소금-후추 잡음 제거에 효과적 (소금-후추 잡음은 약간 극단적인 성격이 존재하기 떄문에)
cv2.medianBlur(src, ksize, dst=None) -> dst
1) src : 입력 영상. 각 채널 별로 처리됨
2) ksize : 커널 크기. 1보다 큰 홀수를 지정
3) dst : 출력 영상. src와 같은 크기, 같은 타입
import sys
import numpy as np
import cv2
src = cv2.imread('noise.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
dst = cv2.medianBlur(src, 3)
# 커널 크기 3의 blurring을 medianblurring으로 처리
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None) -> dst
1) src : 입력 영상. 8비트 또는 실수형, 1채널 또는 3채널
2) d : 필터링에 사용될 이웃 픽셀의 거리 (지름). 음수(-1)를 입력하면 sigmaSpace 값에 의해 자동으로 결정된다.
3) sigmaColor : 색 공간에서 필터의 표준 편차
4) sigmaSpace : 좌표 공간에서 필터의 표준 편차
5) dst : 출력 영상. src와 같은 크기, 같은 타입이다.
6) borderType : 가장자리 픽셀 처리 방식
import sys
import numpy as np
import cv2
src = cv2.imread('lenna.bmp')
if src is None:
print('Image load failed!')
sys.exit()
dst = cv2.bilateralFilter(src, -1, 10, 5)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
: 카메라 입력 영상에 실시간으로 필터링을 적용해서 만화풍의 그림처럼 보이게 하는 기능
# 카툰 필터 카메라
import sys
import numpy as np
import cv2
def cartoon_filter(img):
h, w = img.shape[:2]
img2 = cv2.resize(img, (w//2, h//2))
blr = cv2.bilateralFilter(img2, -1, 20, 7)
edge = 255 - cv2.Canny(img2, 80, 120)
edge = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
dst = cv2.bitwise_and(blr, edge)
dst = cv2.resize(dst, (w, h), interpolation=cv2.INTER_NEAREST)
return dst
def pencil_sketch(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blr = cv2.GaussianBlur(gray, (0, 0), 3)
dst = cv2.divide(gray, blr, scale=255)
return dst
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print('video open failed!')
sys.exit()
cam_mode = 0
while True:
ret, frame = cap.read()
if not ret:
break
if cam_mode == 1:
frame = cartoon_filter(frame)
elif cam_mode == 2:
frame = pencil_sketch(frame)
frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == 27:
break
elif key == ord(' '):
cam_mode += 1
if cam_mode == 3:
cam_mode = 0
cap.release()
cv2.destroyAllWindows()
사실 7강까지 들었는데 학기 중이라 바빠서 이제서야 몰아서 올리는 중이다..