728x90
반응형
SMALL
1. 필터링(filtering)
- 커널(filter)이라고 하는 행렬을 정의하고, 이 커널을 이밎 위에서 이동시켜 가면서 커널과 겹쳐진 이미지 영역과 연산을 한 후, 그 결과값을 연산을 진행한 이미지 픽셀을 대신하여 새로운 이미지를 만드는 연산
- cv2.filter2D(영상, 이미지 깊이, 커널, 중심점 좌표, 추가될 값, 가장자리 화소 처리)
- 이미지 깊이: -1(입력과 동일)
- 커널행렬: 3*3, 5*5, ... 가로 세로가 동일한 행렬 사용
- 중심점 좌표: 기본값은 왼쪽 상단
- 추가될 값: 행렬연산 후 더해지는 값
- 가장자리 화소 처리
- BORDER_CONSTANT: 000abcdefg000, 가장 자리를 0으로 채움(검정색)
- BORDER_REPLICATE: aaaabcedfgggg, 가장 자리를 가장 끝 픽셀로 채움
...
2. 블러링(Blurring)
- 초점이 맞지 않은듯 영상을 흐릿하게 하는 작업
- 평균 블러링
- 가장 일반적인 블러링 방법으로 균일한 값으로 정규화된 커널을 이용한 이미지 필터링 방법
- 커널 영역 내에서 평균 값으로 해당 픽셀을 대체함
- 주변 픽셀들의 평균값을 적용하면 픽셀 간 차이가 적어져 선명도가 떨어져 전체적으로 흐려짐
- 필터의 크기가 클수록 평균 블러링을 적용했을 때 선명도가 떨어짐
- cv2.blur(영상, 커널사이즈)
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('dog.bmp')
dst1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # matplotlib으로 띄우기 위해
dst2 = cv2.blur(img, (3, 3))
plt.figure(figsize=(10,5))
cv2.imshow('img', img)
cv2.imshow('dst2', dst2)
# filter2D를 이용하여 블러링
for i, k in enumerate([3, 5, 9]): # 커널사이즈
kernel = np.ones((k, k)) / k ** 2
# -1: 입력과 동일한 크기
filtering = cv2.filter2D(dst1, -1, kernel)
plt.subplot(1,3,i+1)
plt.imshow(filtering)
plt.title('kernel size:{}'.format(k))
plt.axis('off')
plt.show()
cv2.waitKey()
- 가우시안 블러링
- 가우시안 분포를 갖는 커널로 블러링 하는 것(정규 분포, 평균 근처에 몰려 있는 값들의 개수가 많고 평균에서 멀어질수록 그 개수가 적어지는 분포)
- 대상 픽셀에 가까울수록 많은 영향을 주고, 멀어질수록 적은 영향을 주기 때문에 원래의 영상과 비슷하면서도 노이즈를 제거하는 효과가 있음
- cv2.GaussianBlur(영상, 출력영상, 커널사이즈)
- 출력영상: (0,0)이면 입력 영상과 같음
- 커널사이즈: 숫자 1개만 적음 예) 3 -> 3*3 커널
import cv2
img = cv2.imread('dog.bmp', cv2.IMREAD_GRAYSCALE)
dst1 = cv2.GaussianBlur(img, (0, 0), 3)
dst2 = cv2.blur(img, (3, 3))
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
- 미디언 블러링
- 커널의 픽셀 값 중 중앙값을 선택
- 소금-후추 잡음을 제거하는 효과
- cv2.medianBlur(영상, 커널)
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을 입력하면 자동 결정됨, 5보다 크면 매우 느림
- sigmaColor: 색공간의 시그마 값
- sigmaSpace: 좌표공간의 시그마 값, 값이 크면 멀리 떨어져 있는 픽셀들이 서로 영향을 미침
import cv2
img = cv2.imread('gaussian_noise.jpg', cv2.IMREAD_GRAYSCALE)
dst = cv2.bilateralFilter(img, 9, 75, 75)
dst2 = cv2.bilateralFilter(img, 5, 80, 80)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.imshow('dst2', dst2)
cv2.waitKey()
3. 에지(Edge) 검출
- 영상에서 화소의 밝기가 급격하게 변하는 부분
- 물체의 윤곽선(경계선)이 해당
- 에지를 검출할 수 있으면 물체의 윤곽선을 알 수 있음
- '케니 에지 검출'은 상당한 수준으로 에지를 신뢰성 있게 검출하는 방법
- 노이즈 제거: 5*5 가우시안 블러링 필터
- 경계 그레디언트 방향 계산: 소벨 필터로 경계 및 그레디언트 방향 검출
- 비최대치 억제: 그레디언트 방향에서 검출된 경계 중 가장 큰 값만 선택하고 나머지는 제거
- 이력 스레시홀딩: 두 개의 경계값(Max, Min)을 지정해서 경계 영역에 있는 픽셀들 중 큰 경계값(Max) 밖의 픽셀과 연결성이 없는 픽셀을 제거
- cv2.Canny(영상, 최소임계값, 최대임계값, 커널)
import cv2
import numpy as np
img = cv2.imread('dog.bmp')
med_eval = np.median(img)
lower = int(max(0, 0.7*med_eval)) # 중앙값의 70%의 값이 0보다 작아질 경우 0으로 설정
upper = int(min(255, 1.3*med_eval)) # 중앙값의 130%값이 255를 넘어가면 255로 설정
dst = cv2.GaussianBlur(img, (3, 3,), 0, 0)
dst = cv2.Canny(dst, lower, upper, 3)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
728x90
반응형
LIST
'Python > Computer Vision' 카테고리의 다른 글
[파이썬, Python] OpenCV - 레이블링(labeling)과 외곽선 검출 (0) | 2023.09.02 |
---|---|
[파이썬, Python] OpenCV - 모폴로지 처리, 모폴로지 연산 (0) | 2023.09.02 |
[파이썬, Python] OpenCV - 영상의 변환 (0) | 2023.08.29 |
[파이썬, Python] OpenCV - 이미지 유사도 판단 (1) | 2023.08.27 |
[파이썬, Python] OpenCV - 영상의 이진화 (0) | 2023.08.27 |