본문 바로가기
AI/컴퓨터 비전

OpenCV - 영상필터링 연산 | 블러처리 | Canny

by 바다의 공간 2025. 3. 24.

▶영상의 필터링 연산

영상의 필터링 연산(Image Filtering Operation) 은 영상의 특성을 강조하거나 잡음을 제거하기 위해 커널(필터)을 활용하여 픽셀 값을 변환하는 과정입니다.

 

OpenCV에서는 필터링을 통해 노이즈 제거, 엣지 검출, 블러 효과, 샤프닝 등의 처리를 수행할 수 있습니다. 대표적인 필터링 기법으로는 평균 블러링(Averaging), 가우시안 블러링(Gaussian Blur), 미디언 블러링(Median Blur) 등이 있으며, cv2.blur(), cv2.GaussianBlur(), cv2.medianBlur() 함수를 통해 적용할 수 있습니다.

 

또한, 고급 필터링 기법으로 소벨 필터(Sobel Filter), 라플라시안 필터(Laplacian Filter) 와 같은 엣지 검출 필터도 제공되며, cv2.Sobel() 및 cv2.Laplacian()을 사용하여 적용할 수 있습니다. 필터링 연산은 영상 내 중요한 특징을 강조하거나 불필요한 정보를 제거하는 데 활용되며, 영상 분석 및 전처리에 필수적인 기법입니다.

 

 

 

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('D:/PJ/DLHJ/ong.jpg')
img = cv2.resize(img,(400,400))
dst1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
dst2 = cv2.blur(img, (7,7))

cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()

 

여기서 cv2.blur(img, (7, 7))은7*7의 블러 커널을 입힌다고 생각하면 된다.

7*7 커널을 사용해서 49개의 픽셀을 평균내서 한 픽셀 값을 결정합니다.

즉 픽셀을 기준으로 주변 49개 픽셀 평균값을 계산해서 블러효과를 적용합니다.

 

blur : 이미지에 평균 브럴 효과를 적용합니다.

 

blur(이미지, (정방행렬크기))를 넣어주면 됩니다.

 

 

 

cv2.filter2D()를 사용하는 방법은 

 

filtered_img = cv2.filter2D(src, ddepth, kernel)

 

매개변수 설명

src 원본 이미지

ddepth 출력 이미지의 깊이 (-1이면 원본과 동일)

kernel 사용자 정의 커널 (필터)

 

이다. 그래서 IMG넣고 -1넣고 커널은 위에서 정의 된 kernel을 작성했다.

 

 

 

 

▶커널사이즈별 블러효과 시각화

#커널사이즈별 블러효과
plt.figure(figsize=(10,5))

for i, k in enumerate([5,7,9]):
    print(i,k)
    #커널 요소의 합이 1이되도록 정규화 -> 모든 픽셀을 같은 가중치로 평규 내는 필터가 생성됨
    kernel = np.ones((k,k)) / k**2
    #filter2D : 필터링을 적용
    #filter2D(이미지, 깊이, 커널) -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()

 

이렇게 했는데 ....!!

 

 

 

아무것도 안나온다 TITLE은 잘 적힌거같은데 그안에 사진이 없어서 왜인지 고민했다..

 

plt.show를 해서 다 보일줄알았는데 plt.imshow()를 해야 for문이 보이는거였다.

커널사이즈가 크면 클수록 더 뿌옇게된다!


▶plt.show() vs plt.imshow()

함수 역할
plt.show() 모든 plt 요소를 화면에 출력 (최종 실행)
  • plt.imshow()로 추가한 이미지(또는 그래프)를 최종적으로 화면에 표시하는 함수
  • 여러 개의 그래프나 이미지를 plt.subplot()으로 추가한 후 한꺼번에 출력할 때 사용
  • 한 번 실행하면 이전 플롯을 지우고 새로운 창을 띄움
plt.imshow() 이미지를 Matplotlib의 figure(그래프 창)에 추가
  • 이미지를 그리기 위한 함수
  • Matplotlib에서 이미지를 그래프 창에 추가하는 역할
  • plt.subplot()을 사용할 때 각 서브플롯에 이미지를 배치할 때도 사용

 

최종적으로 show는 맨 마지막에 큰 창에 다 때려박는?거고 imshow는 이미지를 각각 배치하는 느낌이다.


▶가우시안블러 vs 일반 블러

import cv2
import numpy as np

img = cv2.imread('D:/PJ/DLHJ/ong.jpg')
img = cv2.resize(img, (400,400))
#가우시안블러 : 노이즈제거에 효과적, 엣지를 잘 보존하면서 흐림 효과 적용
#GaussianBlur(이미지, 커널크기, 표준편차) , (0,0) = 자동으로 적절한 커널크기를 선택, 2:값이 클수록 흐려짐(더 부드러운 효과)
dst1 = cv2.GaussianBlur(img, (0,0), 2)

#평균블러 : 커널 내의 모든 픽셀 값을 평균내서 흐리게 함
# 단순한만큼 엣지를 많이 손상시킬 수 있음.
dst2 = cv2.blur(img, (5,5))

cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()

 

dst1가 가우시안 블러를 처리한거고 dst2는 일반 블러인데 이 둘의 차이를 보면 dst1의 테두리가 더 적은거같습니다.

그렇지만 사실 가우시안이 테두리 안쪽으로 더 블러가 되는것을 알아두어야합니당!


webp란?

구글에서 만든 gif도되고, png도 되고 깨지지도 않는 확장명입니다.


▶medianblur : 노이즈를 제거하는 방법!

:: 미디안블러는 

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('C:/AIProject2/DAY12/space.webp')
img = cv2.resize(img, (400, 200))
dst = cv2.medianBlur(img,3)
dst1 = cv2.GaussianBlur(img, (0,0), 1)

cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.imshow('dst1', dst1)
cv2.waitKey()

 

salt papper 노이즈라고합니다. 이런 노이즈를 좀 없애기 위해서는 미디안블러를 사용해 볼 수 있는데,

블러는 평균값을 내서 덮어버리기때문에 노이즈로 흰색으로 노이즈가 된 부분을 좀 사라지게 할 수 있습니다.


 

▶ Canny

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('C:/AIProject2/DAY12/ong.jpg')
img = cv2.resize(img, (400, 200))

med_val = np.median(img)
#중앙값
print(med_val)

#중앙값을 70%로 해주고 그 외의값이라면 0으로 반환
lower = int(max(0, 0.7*med_val))
upper = int(min(255, 1.3*med_val))

#canny알고리즘활용
dst = cv2.GaussianBlur(img, (3,3), 0)
#Canny : 엣지를 구하는 함수
#Canny(이미지, 낮은 임계값, 높은 임계값), lower보다 작은 값은 무시하고, upper보다 큰 값만 확실한 엣지로 인식한다.

dst = cv2.Canny(dst, lower, upper, 3)


cv2.imshow('img', img)
cv2.imshow('dst', dst)
# cv2.imshow('dst1', dst1)
cv2.waitKey()

 

 

▶ 결과확인

canny

 

canny