1. 필터링(filtering)
커널(filter)이라고 하는 행렬을 정의하고, 이미지 위에서 이동해가며 커널과 겹쳐진 이니지 영역과 연산을 한 후,
그 결과값을 연산을 진행한 이미지 픽셀을 대신하여 새로운 이미지를 만드는 연산
◼ 이미지 필터링 함수
filter2D(영상, 이미지 깊이, 커널의 크기, 중심점 좌표, 추가될 값, 가장자리 화소 처리) |
[이미지깊이] * 1: 입력과 동일한 크기의 영상 * 커널: 3 * 3, 5 * 5, .. * 가장자리 회소 처리 BORDER_CONSTANT: 000abcdef000 BORDER_REPLICATE: aaaavcdeffff |
2. 블러링(Blurring)
초점이 맞지 않는 듯 영상을 흐릿하게 하는 작업
◼ 평균 블러링
cv2.blur(영상, 커널) |
- 가장 일반적인 블러링 방법으로 일한 값을 정규화 된 커널을 이용한 이미지 필터링 방법 - 커널 영역 내에서 평균값으로 해당 픽셀을 대체함 - 주변 픽셀들의 평균값을 적용하면 픽셀 간 차이가 적어져 선명도가 떨어져 전체적으로 흐려짐 - 필터의 크기가 클수록 평균 블러링을 적용했을 때 선명도가 떨어짐 |
◼ 예제: 평균블러링 적용하기
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 이미지 읽기 및 색상 변환 (BGR -> RGB)
img = cv2.imread('/dog.bmp')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 블러링 적용 (3x3 커널)
blurred_img = cv2.blur(img_rgb, (3, 3))
# 다양한 커널 크기로 필터링
kernel_sizes = [5, 7, 9]
# Matplotlib을 사용하여 이미지 및 필터링 결과 표시
plt.figure(figsize=(15, 5))
# 원본 이미지 및 블러링된 이미지 표시
plt.subplot(1, 4, 1)
plt.imshow(img_rgb)
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 4, 2)
plt.imshow(blurred_img)
plt.title('Blurred Image (3x3)')
plt.axis('off')
# 다양한 커널 크기로 필터링 및 표시
for i, k in enumerate(kernel_sizes):
kernel = np.ones((k, k), dtype=np.float32) / (k ** 2)
filtered_img = cv2.filter2D(img_rgb, -1, kernel)
plt.subplot(1, 4, i + 3)
plt.imshow(filtered_img)
plt.title(f'Kernel size: {k}')
plt.axis('off')
plt.tight_layout()
plt.show()
|
◼ 가우시안 블러링
cv2.GaussianBlur(영상, 출력영상, 커널) 출력영상: (0, 0)이면 입력 영상과 같은 크기의 영상 생성 커널: 3 = 3 * 3 |
- 가우시안 분포를 갖는 커널로 블러링 하는 것(정규 분포, 평균 근처에 몰려 있는 값들의 개수가 많고 평균에서 멀어질수록 그 개수가 적어지는 분포) - 대상 픽셀의 가까올수록 많은 영향을 주고, 멀어질수록 적은 영향을 주기 때문에 원래의 영상과 비슷하면서도 노이즈를 제거하는 효과가 있음 |
◼ 예제 : 평균블러링과 가우시안 블러링 비교
import cv2
img = cv2.imread('/dog.bmp', cv2.IMREAD_GRAYSCALE)
dst1 = cv2.GaussianBlur(img, (0,0), 2)
dst2 = cv2.blur(img, (9, 9))
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
|
◼ 미디언 블러링
cv2.mdeianBlur(영상, 커널) |
- 커널의 픽셀 값 중 중안값을 선택 - 소금-후추 잡음을 제거하는 효과 |
◼ 예제: 미디언블러링 적용하기
import cv2
img = cv2.imread('./noise.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.medianBlur(img, 3)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
|
◼ 바이레터럴 필터(Bilateral Filter)_양방향 필터
cv2.bilateralFilter(영상, 픽셀의 거리, 시그마 컬러, 시그마 스페이스)
픽셀의 거리(필터의 직경): -1을 입력하면 자동 결정됨 * 시그마 컬러: 색공간의 시그마 값 * 시그마 스페이스: 좌표 공간의 시그마 값(값이 클수록 떨어져 있음 픽셀들의 영향을 미침) |
- 잡음을 제거하는 효과는 뛰어났지만, 해당 잡음의 경계도 흐릿하게 만드는 문제 해결하기 위해 나옴 - 경계도 뚜렷하고 노이즈도 제거되는 효과는 있지만 속도가 느리다는 단점이 존재 |
◼ 예제: 가우시안 블러와 바이레터럴 필터 비교하기
import cv2
img = cv2.imread('./gaussian_noise.jpg', cv2.IMREAD_GRAYSCALE)
dst1 = cv2.GaussianBlur(img, (5, 5), 1)
dst2 = cv2.bilateralFilter(img, 5, 80, 80)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
|
◼ 에지(edge) 검출
cv2.Canny(영상, 최소임계값, 최대입계값, 커널) * 최소임계값, 최대입계값: 두 개의 경계 값(Max, Min)을 지정해서 경계에 있는 영역 픽셀을 찾음 |
- 영상에서 화소의 밝기가 급격하게 변하는 부분 - 물체의 윤곽선(경계선)이 해당 - 에지를 검출할 수 있으면 물체의 윤관선을 알 수 있음 - "캐니 에지 검출"은 상당한 수준으로 에지를 신뢰성 있게 검출하는 방법 |
◼ 예제: 가우시안 블러를 적용하고 Canny 에지 검출
import cv2
import numpy as np
img = cv2.imread('./dog.bmp')
# 중간 값 계산
med_val = np.median(img)
# Canny 에지 검출을 위한 하위, 상위 임계값 계산
lower = int(max(0, 0.7 * med_val))
upper = int(min(0, 1.3 * med_val))
dst = cv2.GaussianBlur(img, (3, 3), 0, 0) # 가우시안 블러 적용
dst = cv2.Canny(dst, lower, upper, 3) # Canny 에지 검출 적용
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
|
◼ 스페이스바를 누를 때마다 영상에 다른 필터링 적용하기 (기본 -> 가우시안 블러 -> 케니필터링)
import cv2
video_path = 'sea.mp4'
# 동영상 캡처 객체 생성
cap = cv2.VideoCapture(video_path)
# 필터 상태 변수
filter_state = 0
# 동영상 읽기 확인
if not cap.isOpened():
print("동영상을 로드할 수 없습니다.")
exit()
while True:
ret, frame = cap.read()
# 동영상이 끝나면 루프 종료
if not ret:
break
# 필터 상태에 따라 필터 적용
if filter_state == 0:
filtered_frame = frame # 기본 영상
elif filter_state == 1:
filtered_frame = cv2.GaussianBlur(frame, (15, 15), 0) # 가우시안 필터링
elif filter_state == 2:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
filtered_frame = cv2.Canny(gray, 100, 200) # 캐니 에지 검출
filtered_frame = cv2.cvtColor(filtered_frame, cv2.COLOR_GRAY2BGR) # 다시 BGR로 변환
# 영상 출력
cv2.imshow('Video', filtered_frame)
key = cv2.waitKey(30) & 0xFF
# 'q' 키를 누르면 종료
if key == ord('q'):
break
# 스페이스바를 누르면 필터 상태 변경
if key == ord(' '):
filter_state = (filter_state + 1) % 3
# 동영상 캡처 객체와 모든 창 닫기
cap.release()
|
◼스페이스바를 누를 때마다 캠에 다른 필터링 적용하기 (기본 -> 가우시안 블러 -> 케니필터링)
import cv2
import numpy as np
def blur_filter(img):
img = cv2.GaussianBlur(img, (0, 0), 3)
return img
def canny_filter(img):
med_val = np.median(img)
lower = int(max(0, 0.7 * med_val))
upper = int(min(255, 1.3 * med_val))
dst = cv2.GaussianBlur(img, (3, 3), 0, 0)
dst = cv2.Canny(dst, lower, upper, 3)
return dst
cap = cv2.VideoCapture(0)
cam_mode = 0
while True:
ret, frame = cap.read()
if cam_mode == 1:
frame = blur_filter(frame)
elif cam_mode == 2:
frame = canny_filter(frame)
cv2.imshow('frame', frame)
key = cv2.waitKey(10)
if key == 27:
break
elif key == ord(' '):
cam_mode += 1
if cam_mode == 3:
cam_mode = 0
cap.release()
|
'Python > 컴퓨터 비전' 카테고리의 다른 글
2024-07-24 VGG19 | 분류 (0) | 2024.08.06 |
---|---|
2024-07-23 모폴로지 변환, 레이블링, OCR (0) | 2024.07.29 |
2024-07-18 마스크, 관심영역, 이진화, 이미지 유사도, 영상의 변환 (2) | 2024.07.24 |
2024-07-17 영상 화소처리, 평활화, 색공간, CLAHE, 정규화 (0) | 2024.07.23 |
2024-07-16 OpenCV 라이브러리 (0) | 2024.07.22 |