목표
컨볼루션 연산 & 블러링 Convolutions
import cv2
import numpy as np
image = cv2.imread('images/flowers.jpeg')
imshow('Original Image', image)
# Creating our 3 x 3 kernel
kernel_3x3 = np.ones((3, 3), np.float32) / 9
# We use the cv2.fitler2D to conovlve the kernal with an image
blurred = cv2.filter2D(image, -1, kernel_3x3)
imshow('3x3 Kernel Blurring', blurred)
# Creating our 7 x 7 kernel
kernel_7x7 = np.ones((7, 7), np.float32) / 49
blurred2 = cv2.filter2D(image, -1, kernel_7x7)
imshow('7x7 Kernel Blurring', blurred2)
필터링 작업 및 컨볼루션 연산에 사용될 3x3 커널을 생성
kernel_3x3 = np.ones((3, 3), np.float32) / 9
[1/9, 1/9, 1/9]
[1/9, 1/9, 1/9]
[1/9, 1/9, 1/9]
이미지와 커널간의 컨벌루션을 수행하는 부분인데,
컨벌루션이란 두 함수를 결합해서 새로운 함수를 만든다는 뜻이고
이미지 처리에서 컨벌루션은 이미지와 커널(필터) 사이의 픽셀 단위 곱셈 및 합산을 통해 새로운 이미지를 생성
이때 여기서 cv2.filter2D 함수는 이미지와 커널 사이의 컨벌루션을 계산하는 데 사용
blurred = cv2.filter2D(image, -1, kernel_3x3)
다시 7x7 커널을 만들어서 이미지와 컨벌루션하는데
kernel_7x7 = np.ones((7, 7), np.float32) / 49
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
결과를 확인해보자.
7x7 커널과 원본이미지를 컨벌루션한 것이 가장 흐리게, 블러처리가 된것이 보인다.
3x3
[1/9, 1/9, 1/9]
[1/9, 1/9, 1/9]
[1/9, 1/9, 1/9]
7x7
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
[1/49, 1/49, 1/49, 1/49, 1/49, 1/49, 1/49]
직접 커널을 만들어서 블러링을 했는데,
일반적으로 OpenCV를 이용해서 블러링을 할때 사용되는 3가지 방법에 대해서도 알아보자.
import cv2
import numpy as np
image = cv2.imread('images/flowers.jpeg')
# 정규화된 상자 필터로 영상을 컨볼루션하여 평균화합니다.
# 이것은 상자 아래의 픽셀을 가져가고 중심 요소를 대체합니다
# 상자 크기는 홀수 및 양수여야 합니다
blur = cv2.blur(image, (5,5))
imshow('Averaging', blur)
# 박스 필터 대신 가우시안 커널
Gaussian = cv2.GaussianBlur(image, (5,5), 0)
imshow('Gaussian Blurring', Gaussian)
# 커널 영역 및 중앙 아래의 모든 픽셀의 중앙값을 가져옵니다
# 요소가 이 중앙값으로 대체됩니다
median = cv2.medianBlur(image, 5)
imshow('Median Blurring', median)
양방향 필터(bilateral filter)를 사용해서 이미지를 흐리게도 만들어보자.
이미지를 흐리게는 하지만 이미지의 엣지(경계)를 보존하는 양방향필터의 특성으로 인해 경계는 원본과 동일하게 가져가는 모습이다.
노이즈 제거
블러링을 마쳤으니 이번엔 노이즈를 제거 해보겠다.
image = cv2.imread('images/hilton.jpeg')
imshow('Original', image)
dst = cv2.fastNlMeansDenoisingColored(image, None, 6, 6, 7, 21)
imshow('fastNlMeansDenoisingColored', dst)
눈으로 봤을땐 별 차이가 없어보이지만, 아래 사진이 좀 더 인공적으로 향상된? 느낌이다.
가장자리가 부드러운 느낌
샤프닝 - 날카롭게
# Loading our image
image = cv2.imread('images/hilton.jpeg')
imshow('Original', image)
# Create our shapening kernel, remember it must sum to one
kernel_sharpening = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
# applying the sharpening kernel to the image
sharpened = cv2.filter2D(image, -1, kernel_sharpening)
imshow('Sharpened Image', sharpened)
이미지에 샤픈 필터(sharpening filter)를 적용하여 이미지를 선명하게 만드는건데,
여기서도 샤픈필터를 생성하는데, 블러링과 반대로 선명하게 만들지만 커널을 생성한다.
중심 픽셀의 값에 높은 가중치를 부여하여 이미지의 엣지를 강조하는 데 사용된다.
만든 필터를 cv2.filter2D함수를 이용해서 이미지에 적용한다.
노이즈제거와 달리 샤프닝 필터를 적용한것은 선명함이 올라간것이 보인다.
필터 커널 가운데 가중치를 높게 줘서 필터된 이미지의 가운데는 찐한 반명 가장자리들은 연한것을 확인할수있다.