728x90
반응형
영상 필터링
커널(filter)라고 하는 정방행렬을 정의하고, 이 커널을 이미지 위에서 이동시키면서 커널과 겹쳐진 이미지 영역과(컨벌루션 연산)
연산을 한 후 그 결과값을 연산을 진행한 이미지 픽셀을 대신하여 새로운 이미지를 만드는 연산
# 컨벌루션 곱을 하면 3바이 3행렬에서 1개가 나온다. 새로운 이미지를 만든다는 뜻이다.
필터링
- 영상에서 필요한 정보만 통과시키고 원치 않는 정보를 걸러내는 작업
예) 노이즈를 제거하여 영상을 깔끔하게 만드는 필터. 부드러운 느낌의 성분을 제거하여 날카로운 느낌이 나도록 만들 수 있음
- 영상의 필터링은 마스크라고 부르는 작은 크기의 행렬을 이용
- 마스크는 필터링의 성격을 정의하는 행렬이며 커널 또는 필터라고 부름
- 마스크의 정중앙을 고정점으로 사용
✔ OpenCV에서 필터 마스크를 사용하는 일반적인 필터릴은 filter2D 함수를 사용
filter2D(영상, 이미지 깊이(자료형 크기, -1이면 입력과 동일), 커널 행렬, 증심정 좌표, 추가될 값, 가장자리 화소 처리)
가장자리 화소 처리
OpenCV에서는 영상을 필터링을 수행할 때 영상의 가장자리 픽셀을 확장하여 바깥쪽에 가상의 픽셀을 만듬
- 패딩(padding)을 추가
- 픽셀값을 어떻게 설정하느냐에 따라 필터링 연산의 결과가 달라짐
- 가장자리 화소 처리 상수 값
BORDER_CONSTANT : 000픽셀픽셀픽셀픽셀픽셀픽셀픽셀000
BORDER_REPLICATE : aaaabcdefghhh
BORDER_REFLECT : cbabcdefghgf - 3개의 픽셀 전걸
✔ 필터링
import cv2
import matplotlib.pyplot as plt
import numpy as np
src = cv2.imread('rose.bmp')
dst = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,5))
for i, k in enumerate([3, 6, 10]):
# 3바퀴 i는 인덱스 k에는 3 , 6 ,9가 들어간다.
kernel = np.ones((k, k)) / k ** 2 # 제곱을 나눠준다, 마스크만들기
filtering = cv2.filter2D(dst, -1, kernel)
plt.subplot(1 , 3, i+1)
plt.imshow(filtering)
plt.title('kernel size : {}'.format(k))
plt.axis('off')
plt.show()
이미지 블러링(Image Bluring)
- 이미지를 흐리게 만드는 기법
- 고주파 영역을 제거함으로써 노이즈를 제거하거나 경계선을 흐리게 만듬
- Averaging, Gaussian Filtering, Median Filtering, Bilateral Filtering
Averaging
- 가장 일반적인 필터링 방법으로 균일한 값을 정규화 된 커널을 이용한 이미지 필터링 방법
- 커널 영역 내에서 평균 값으로 해당 픽셀을 대체함
- cv2.blur()
✔ 블러링
import cv2
src = cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.blur(src, (3,3)) # (3,3) 내각 원하는 3*# 행렬 마스크
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
Gaussian Filtering
- 가우시안 함수를 이용한 커널을 적용
- 중앙 위치에 놓인 픽셀과 가까울수록 가중치가 높아지고 멀어질 수록 가중치가 작아져 중앙 픽셀과 멀어질 수록
해당 픽셀값에 대한 영향력이 작아짐
- 전체적으로 밀도가 동일한 노이즈, 백색노이즈를 제거하는데 효과적
cv2.GaussianBlur(영상, 커널의 크기, 가우시안 커널의 X방향 표준편차, 가우시안 커널의 Y방향 표준편차)
커널의 크기다 (0,0)을 지정하면 sigma값에 의해 자동으로 결정
# 얼마만큼 범위의 표준편차가 나올지 종모양 가우시안 필터링 방식
✔ 가우시안
import cv2
src = cv2.imread('rose.bmp', cv2.IMREAD_GRAYSCALE)
dst1 = cv2.GaussianBlur(src, (0,0), 3)
# 시그마 값 3에 의해 바뀜
dst2 = cv2.blur(src,(7,7))
# 7,7 마스크에 따라 바뀜
cv2.imshow('src', src)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
Median Filtering
- 따로 kernel을 만들어 합성곱하지 않고, kernel window에 있는 모든 픽셀들을 정렬한 후 중간값을 선택하여
- 중간값 필터링의 경우에는 항상 이미지의 일부 픽셀값으로 대체됨
- 소금-후추 잡음 제거에 효과적
cv2.medianBlur(영상, 커널사이즈(1ㅗ다 큰 홀수를 지정))
오름차순 중앙값을 선택(anchor)
반응형
✔ 미디안
import cv2
src = cv2.imread('noise.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.medianBlur(src,3)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
Bilateral Filtering
- 경계선을 유지하면서 Gaussian Filtering이 하는 것처럼 Blur 처리를 해주는 기법
- 가우시안 필터링에서는 두 픽셀의 거리 차이만 고려하지만 양방향 필터링의 경우에는 두 픽셀의 명암값 차이 또한 커널에
넣어 가중치로 곱함
- 픽셀의 차이가 크면 가중치가 0에 가까운 값이 되어 합쳐지지 않으므로 영역과 영역사이즈의 경계선이 잘 보전될 수 있음
- 엣지를 보존해주고 기존에 픽셀하고 이웃 픽셀간의 거리, 픽셀간의 차이를 고려하여 블러링을 해준다.
cv2.bilateralFilter(영상, 필터링에 사용될 이웃 픽셀의 거리(지름), 색 공간에서 필터의 표준 편차, 좌표 공간에서 표준편차)
영상 : 8bit, 채널수가 1, 3인 이미지
필터링에 사용될 이웃 픽셀의 거리(지름) : -1를 입력하면 sigmaSpace값에 의해 자동 결정됨
좌표 공간에서 표준퍈치 : 값이 크면 멀리 떨어져 있는 픽셀들이 서로 영향을 미침, 지름이 양수면 sigmaSpace에 상관없이
인접한 픽셀들에 영향을 미치지만, -1인 경우 sigmaSpace에 비례
✔ 이미지도 음성 신호처럼 주파수로 표현할 수 있음
고주파 : 밝기 변화가 많은 곳 -> 주변 영역과 색 차이가 크게 나는 부분(모서리)
* 고주파를 제거하면 경계선의 변화가 약해져 Blur 처리가 됨
저주파 : 밝기 변화가 적은 곳 -> 주변 영역과 색 차리가 적은 부분(배경, 면) , 넓은 부분
* 저주파를 제거하면 배경 영역이 흐려져 대상의 영역(Edge)를 뚜력하게 확인할 수 있음
✔ Bilateral
import cv2
src = cv2.imread('dog.jpg')
dst = cv2.bilateralFilter(src, -1, 10, 5)
cv2.imshow('src',src)
cv2.imshow('dst',dst)
cv2.waitKey()
샤프닝(sharpening)
- 영상을 날카롭게 만드는 처리
- 영상을 선명하게 할 때 사용
- 중심 화소값과 인접 화소값의 차이를 더 크게 만듬
✔ 샤프닝
import cv2
import numpy as np
src = cv2.imread('dog.jpg')
cv2.imshow('src', src)
mask = np.asarray([[-1,-1,-1],
[-1,9,-1],
[-1,-1,-1]], dtype = np.float32)
sharpening_img = cv2.filter2D(src,-1, mask)
cv2.imshow('sharpening_img', sharpening_img)
cv2.waitKey()
에지(edge) 검출
- 영상에서 화소의 밝기가 급격하게 변하는 부분
- 영상안에서 상당한 밝기 차이가 있는 곳이고, 대게 물체의 윤곽선(경계선)에 해당
- 에지를 검출할 수 있으면 물체의 윤곽선을 알 수 있음
- '캐니 에지 검출' 방법처럼 상당한 수준으로 에지를 신뢰성 있게 검출하는 방법들이 존재
✔ 캐니 에지 연산자
- 널리 사용되고 상당히 신뢰성 있는 에지 검출 알고리즘
* 케니 에지 연산자가 적용되는 순서
1. 잡음 억제 : 에지를 검출하기 전에 5*5 가우시안 필터를 사용하여 영상의 잡음응 제거
2. 그라디언트 계산 : Sobel 마스크로 수평 및 수직 방향의 1차 미분값을 얻음
3. 불필요한 에지를 제거하기 위해 그라디언트의 값이 그라디언트 방향의 인접 화소 중에서 최대값인지를 확인
(최대값만 남기고 나머지는 제거) -> 얇은 에지 처리를 위해
4. 모든 에지 후보들이 실제 에지인지 아닌지를 결정
Canny(영상, 하위 임계값, 상위 임계값, sobel마스크의 크기)
✔ 캐니
import cv2
import numpy as np
src = cv2.imread('rose.bmp')
cv2.imshow('src',src)
med_val = np.median(src)
# 하위 임계값을 0 또는 중앙의 70%로 설정하겠다는 의미이다.
lower = int(max(0, 0.7 * med_val))
# 상위 임계값을 130% 또는 255로 설정하겠다.
upper = int(min(255,1.3*med_val))
# 임계값을(높은/낮은 값) 만든다음 에지값만 받아내기
dst = cv2.GaussianBlur(src, (3,3), 0,0)
# 마스크가 클 수록 얇아지고 작을수록 커진다. 에지값이
dst = cv2.Canny(dst,lower, upper,3)
cv2.imshow('dst', dst)
cv2.waitKey()
문제
- 카메라 입력 영상을 출력
- 스페이스바를 누를때마다 일반영상, 가우시안 피러, 케니 필터
- 스페이스바 : ord(' ')
- 8_fitercream.py
✔ 문제
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
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))
img = cv2.GaussianBlur(img, (3, 3), 0, 0)
img = cv2.Canny(img, lower, upper, 3)
return img
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(1)
if key == 27:
break
elif key == ord(' '):
cam_mode += 1
if cam_mode == 3:
cam_mode = 0
cap.release()
반응형
'Python > openCV' 카테고리의 다른 글
테서렉트 예제 (0) | 2023.03.17 |
---|---|
테서렉트 설치(사전준비) (0) | 2023.03.16 |
Python OpenCV (영상의 이진화, 자동 이진화, 지역 이진화, 적응형 이진화, 모폴로지) (0) | 2023.03.10 |
Python openCV (어파인, 크기변환, 영상회전, 보간법, 투시변환) (0) | 2023.03.09 |
Python openCV 기본 (0) | 2023.03.08 |