๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[v0.19]์์์ฒ๋ฆฌ_ ํํฐ์ ์ปจ๋ณผ๋ฃจ์ ์ฐ์ฐ, ๋ธ๋ฌ๋ง ๋ณธ๋ฌธ
[v0.19]์์์ฒ๋ฆฌ_ ํํฐ์ ์ปจ๋ณผ๋ฃจ์ ์ฐ์ฐ, ๋ธ๋ฌ๋ง
์ง์ง์ํ์นด 2022. 1. 8. 01:45220108 ์์ฑ
<๋ณธ ๋ธ๋ก๊ทธ๋ ๊ทํ์ด ์์ฌ๋์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํด์ ๊ณต๋ถํ๋ฉฐ ์์ฑํ์์ต๋๋ค>
OpenCV - 17. ํํฐ(Filter)์ ์ปจ๋ณผ๋ฃจ์ (Convolution) ์ฐ์ฐ, ํ๊ท ๋ธ๋ฌ๋ง, ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง, ๋ฏธ๋์ธ ๋ธ๋ฌ๋ง,
์ด๋ฒ ํฌ์คํ ๋ถํฐ๋ ์์ ํํฐ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ์ด๋ฒ ํฌ์คํ ์ญ์ 'ํ์ด์ฌ์ผ๋ก ๋ง๋๋ OpenCV ํ๋ก์ ํธ(์ด์ธ์ฐ ์ )'๋ฅผ ์ ๋ฆฌํ ๊ฒ์์ ๋ฐํ๋๋ค. ์ฝ๋: github.com/BaekKyunShin/OpenCV_Project_Python/tree
bkshin.tistory.com
1. ํํฐ (Filter)์ ์ปจ๋ณผ๋ฃจ์ (Convolution)
๊ณต๊ฐ ์์ญ ํํฐ๋ง(spacial domain filtering)
: ์๋ก์ด ํฝ์ ๊ฐ์ ์ป์ ๋ ํ๋์ ํฝ์ ๊ฐ์ด ์๋ ๊ทธ ์ฃผ๋ณ ํฝ์ ๋ค์ ๊ฐ์ ํ์ฉ
: ์ฐ์ฐ ๋์ ํฝ์ ๊ณผ ๊ทธ ์ฃผ๋ณ ํฝ์ ๋ค์ ํ์ฉํ์ฌ ์๋ก์ด ํฝ์ ๊ฐ์ ์ป๋ ๋ฐฉ๋ฒ
๋ธ๋ฌ๋ง(Blurring)
: ๊ธฐ์กด์ ์์์ ํ๋ฆฟํ๊ฒ ๋ง๋๋ ์์
์ปค๋(kernel)
: ์ฃผ๋ณ ํฝ์ ์ ์ด๋ ๋ฒ์๊น์ง ํ์ฉํ ์ง ๊ทธ๋ฆฌ๊ณ ์ฐ์ฐ์ ์ด๋ป๊ฒ ํ ์ง๋ฅผ ๊ฒฐ์
: ์๋(window), ํํฐ(filter), ๋ง์คํฌ(mask)๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค
์ปจ๋ณผ๋ฃจ์ ์ฐ์ฐ
: ์ผ๋์ผ๋ก ๋์ํ๋ ์์น์ ์๋ ์ปค๋์ ์์์ ๋์ํ๋ ์ ๋ ฅ ํฝ์ ๊ฐ์ ๊ณฑํด์ ๋ชจ๋ ํฉํ ๊ฒ์
๊ฒฐ๊ณผ ํฝ์ ๊ฐ์ผ๋ก ๊ฒฐ์
: ์ฐ์ฐ์ ๋ง์ง๋ง ํฝ์ ๊น์ง ๋ฐ๋ณต
dst = cv2.filter2D(src, ddepth, kernel, dst, anchor, delta, borderType)
: ์ปจ๋ณผ๋ฃจ์
์ฐ์ฐํ๊ธฐ
- src : ์
๋ ฅ ์์, Numpy ๋ฐฐ์ด
- ddepth: ์ถ๋ ฅ ์์์ dtype (-1: ์
๋ ฅ ์์๊ณผ ๋์ผ)
- kernel: ์ปจ๋ณผ๋ฃจ์
์ปค๋, float32์ n x n ํฌ๊ธฐ ๋ฐฐ์ด
- dst(optional): ๊ฒฐ๊ณผ ์์
- anchor(optional): ์ปค๋์ ๊ธฐ์ค์ , default: ์ค์ฌ์ (-1, -1)
- delta(optional): ํํฐ๊ฐ ์ ์ฉ๋ ๊ฒฐ๊ณผ์ ์ถ๊ฐํ ๊ฐborderType(optional): ์ธ๊ณฝ ํฝ์
๋ณด์ ๋ฐฉ๋ฒ ์ง์
2. ํ๊ท ๋ธ๋ฌ๋ง (Average Blurring)
: ๋ธ๋ฌ๋ง์ ์ด์ ์ด ๋ง์ง ์๋ฏ์ด ์์์ ํ๋ฆฟํ๊ฒ ํ๋ ์์
: ํ๊ท ๋ธ๋ฌ๋ง์ ์ฃผ๋ณ ํฝ์ ๊ฐ๋ค์ ํ๊ท ์ ์ ์ฉ
: ์ฃผ๋ณ ํฝ์ ๋ค์ ํ๊ท ๊ฐ์ ์ ์ฉํ๋ฉด ํฝ์ ๊ฐ ์ฐจ์ด๊ฐ ์ ์ด์ ธ ์ ๋ช ๋๊ฐ ๋จ์ด์ ธ ์ ์ฒด์ ์ผ๋ก ํ๋ฆฟํ๋ค
# ํ๊ท ํํฐ๋ฅผ ์์ํ์ฌ ๋ธ๋ฌ ์ ์ฉ
import cv2
import numpy as np
img = cv2.imread('img/night.jpg')
'''
#5x5 ํ๊ท ํํฐ ์ปค๋ ์์ฑ ---โ
kernel = np.array([[0.04, 0.04, 0.04, 0.04, 0.04],
[0.04, 0.04, 0.04, 0.04, 0.04],
[0.04, 0.04, 0.04, 0.04, 0.04],
[0.04, 0.04, 0.04, 0.04, 0.04],
[0.04, 0.04, 0.04, 0.04, 0.04]])
'''
# 5x5 ํ๊ท ํํฐ ์ปค๋ ์์ฑ ---โก
kernel = np.ones((5,5))/5**2
# ํํฐ ์ ์ฉ ---โข
blured = cv2.filter2D(img, -1, kernel)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
cv2.imshow('origin', img)
cv2.imshow('avrg blur', blured)
cv2.waitKey()
cv2.destroyAllWindows()
# 5x5 ํ๊ท ๋ธ๋ฌ๋ง ํํฐ ์ปค๋ ์์ฑ
kernel = np.ones((5,5))/5**2
- 5 x 5 ํํฐ์ ์์ ๊ฐ์์ธ 5**2(=25)๋ก ๋๋๊ธฐ
- ํํฐ์ ํฌ๊ธฐ๊ฐ ํด์๋ก ํ๊ท ๋ธ๋ฌ๋ง์ ์ ์ฉํ์ ๋ ์ ๋ช ๋๊ฐ ๋ ๋จ์ด์ง๋ค
+) opencv ์ ํ๊ท ๋ธ๋ฌ๋ง ํจ์
dst = cv2.blur(src, ksize, dst, anchor, borderType)
: ์ปค๋์ ํฌ๊ธฐ๋ง ์ ํด์ฃผ๋ฉด ์์์ ํ๊ท ์ปค๋์ ์์ฑํด์ ํ๊ท ๋ธ๋ฌ๋ง์ ์ ์ฉํ ์์์ ์ถ๋ ฅ
: ์ปค๋ ํฌ๊ธฐ๋ ์ผ๋ฐ์ ์ผ๋ก ํ์
- src : ์
๋ ฅ ์์, numpy ๋ฐฐ์ด
- ksize : ์ปค๋์ ํฌ๊ธฐ
- ๋๋จธ์ง ํ๋ผ๋ฏธํฐ๋ cv2.filter2D()์ ๋์ผ
dst = cv2.boxFilter(src, ddepth, ksize, dst, anchor, normalize, borderType)
: normalize์ True๋ฅผ ์ ๋ฌํ๋ฉด cv2.blur() ํจ์์ ๋์ผํ ๊ธฐ๋ฅ
- ddepth : ์ถ๋ ฅ ์์์ dtype (-1: ์ ๋ ฅ ์์๊ณผ ๋์ผ)
- normalize(optional) : ์ปค๋ ํฌ๊ธฐ๋ก ์ ๊ทํ(1/ksize²) ์ง์ ์ฌ๋ถ (Boolean), default=True
- ๋๋จธ์ง ํ๋ผ๋ฏธํฐ๋ cv2.filter2D()์ ๋์ผ
# ๋ธ๋ฌ ์ ์ฉ ํจ์๋ก ๋ธ๋ฌ๋ง ์ ์ฉ
import cv2
import numpy as np
file_name = 'img/taekwonv1.jpg'
img = cv2.imread(file_name)
# blur() ํจ์๋ก ๋ธ๋ฌ๋ง ---โ
blur1 = cv2.blur(img, (10,10))
# boxFilter() ํจ์๋ก ๋ธ๋ฌ๋ง ์ ์ฉ ---โก
blur2 = cv2.boxFilter(img, -1, (10,10))
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack( (img, blur1, blur2))
cv2.imshow('blur', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ๋ ํจ์ ๋์ผํ ์ด๋ฏธ์ง ์ถ๋ ฅ !
3. ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง(Gaussian Blurring)
: ๊ฐ์ฐ์์ ๋ถํฌ๋ฅผ ๊ฐ๋ ์ปค๋๋ก ๋ธ๋ฌ๋ง ํ๋ ๊ฒ
: ๊ฐ์ฐ์์ ๋ถํฌ(gaussian distribution)๋ ์ ๊ท ๋ถํฌ(normal distribution)์ด๋ผ๊ณ ๋ ํจ
: ํ๊ท ๊ทผ์ฒ์ ๋ชฐ๋ ค ์๋ ๊ฐ๋ค์ ๊ฐ์๊ฐ ๋ง๊ณ ํ๊ท ์์ ๋ฉ์ด์ง์๋ก ๊ทธ ๊ฐ์๊ฐ ์ ์ด์ง๋ ๋ถํฌ
: ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง ์ปค๋์ ์ค์๊ฐ์ด ๊ฐ์ฅ ํฌ๊ณ ์ค์์์ ๋ฉ์ด์ง์๋ก ๊ทธ ๊ฐ์ด ์์์ง๋ค
- ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง ์ปค๋์ ์ ์ฉํ๋ฉด ๋์ ํฝ์ ์ ๊ฐ๊น์ธ์๋ก ๋ง์ ์ํฅ์ ์ฃผ๊ณ ,
๋ฉ์ด์ง์๋ก ์ ์ ์ํฅ์ ์ฃผ๊ธฐ ๋๋ฌธ์
์๋์ ์์๊ณผ ๋น์ทํ๋ฉด์๋ ๋ ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๋ ํจ๊ณผ
cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
: ์ปค๋ ํฌ๊ธฐ์ ํ์ค ํธ์ฐจ๋ฅผ ์ ๋ฌํ๋ฉด ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง์ ์ ์ฉ
- src : ์
๋ ฅ ์์
- ksize : ์ปค๋ ํฌ๊ธฐ (์ฃผ๋ก ํ์)
- sigmaX : X ๋ฐฉํฅ ํ์คํธ์ฐจ (0: auto) -> ์๋์ผ๋ก ํ์คํธ์ฐจ๋ฅผ ์ ํํด์ ์ฌ์ฉ
- sigmaY(optional) : Y ๋ฐฉํฅ ํ์คํธ์ฐจ (default: sigmaX) -> ์๋ตํ๋ฉด sigmaX ๊ฐ๊ณผ ๋์ผ
- borderType(optional) : ์ธ๊ณฝ ํ
๋๋ฆฌ ๋ณด์ ๋ฐฉ์
ret = cv2.getGaussianKernel(ksize, sigma, ktype)
: ์ปค๋ ํฌ๊ธฐ์ ํ์ค ํธ์ฐจ๋ฅผ ์ ๋ฌํ๋ฉด ๊ฐ์ฐ์์ ํํฐ๋ฅผ ๋ฐํ
: ๋ฐํ๋ ํํฐ๋ 1์ฐจ์์ด๋ฏ๋ก cv2.filter2D() ํจ์์ ์ฌ์ฉํ๋ ค๋ฉด ret * ret.T์ ๊ฐ์ ํ์์ผ๋ก ์ ๋ฌ
- ret : ๊ฐ์ฐ์์ ์ปค๋ (1์ฐจ์์ด๋ฏ๋ก ret * ret.T ํํ๋ก ์ฌ์ฉํด์ผ ํจ)
# ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง
import cv2
import numpy as np
img = cv2.imread('img/gaussian_noise.jpg')
# ๊ฐ์ฐ์์ ์ปค๋์ ์ง์ ์์ฑํด์ ๋ธ๋ฌ๋ง ---โ
k1 = np.array([[1, 2, 1],
[2, 4, 2],
[1, 2, 1]]) *(1/16)
blur1 = cv2.filter2D(img, -1, k1)
# ๊ฐ์ฐ์์ ์ปค๋์ API๋ก ์ป์ด์ ๋ธ๋ฌ๋ง ---โก
k2 = cv2.getGaussianKernel(3, 0)
blur2 = cv2.filter2D(img, -1, k2*k2.T)
# ๊ฐ์ฐ์์ ๋ธ๋ฌ API๋ก ๋ธ๋ฌ๋ง ---โข
blur3 = cv2.GaussianBlur(img, (3, 3), 0)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
print('k1:', k1)
print('k2:', k2*k2.T)
merged = np.hstack((img, blur1, blur2, blur3))
cv2.imshow('gaussian blur', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ์ฒซ ๋ฒ์งธ๋ ๊ฐ์ฐ์์ ํํฐ๋ฅผ ์ง์ ์์ฑํด์ cv2.filter2D() ํจ์์ ์ ๋ฌํ์ฌ ๋ธ๋ฌ๋ง
- ๋ ๋ฒ์งธ๋ cv2.getGaussianKernel() ํจ์๋ฅผ ์ด์ฉํด ๊ฐ์ฐ์์ ์ปค๋ ์ป๊ณ cv2.filter2D() ํจ์์ ์ ๋ฌํ์ฌ ๋ธ๋ฌ๋ง
- ์ธ ๋ฒ์งธ๋ cv2.GaussianBlur() ํจ์๋ฅผ ํ์ฉํ์ฌ ํํฐ๋ฅผ ๋ณ๋๋ก ๊ตฌํ์ง ์๊ณ ์ง์ ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง์ ์ ์ฉ
- ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง์ ๋ ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๋ ํจ๊ณผ
4. ๋ฏธ๋์ธ ๋ธ๋ฌ๋ง(Median Blurring)
: ์ปค๋์ ํฝ์ ๊ฐ ์ค ์ค์๊ฐ์ ์ ํํ๋ ๊ฒ
: ๋ฏธ๋์ธ ๋ธ๋ฌ๋ง์ ์๊ธ-ํ์ถ ์ก์์ ์ ๊ฑฐํ๋ ํจ๊ณผ
: ์๊ธ-ํ์ถ ์ก์์ด๋ ์ด๋ฏธ์ง์ ์๊ธ๊ณผ ํ์ถ๋ฅผ ๋ฟ๋ฆฐ ๊ฒ๊ณผ ๊ฐ์ด ์๊ธด ์ก์
dst = cv2.medianBlur(src, ksize)
src: ์
๋ ฅ ์์
ksize: ์ปค๋ ํฌ๊ธฐ
# ๋ฏธ๋์ธ ๋ธ๋ฌ๋ง
import cv2
import numpy as np
img = cv2.imread("img/salt_pepper_noise.jpg")
# ๋ฏธ๋์ธ ๋ธ๋ฌ ์ ์ฉ --- โ
blur = cv2.medianBlur(img, 5)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img,blur))
cv2.imshow('media', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
5. ๋ฐ์ด๋ ํฐ๋ด ํํฐ(Bilateral Filter)
: ๊ฒฝ๊ณ๋ฅผ ํ๋ฆฟํ๊ฒ ํ๋ ๋ฌธ์ ๋ฅผ ๋ณด์
: ๊ฐ์ฐ์์ ํํฐ์ ๊ฒฝ๊ณ ํํฐ๋ฅผ ๊ฒฐํฉ
: ๊ฒฝ๊ณ๋ ๋๋ ทํ๊ณ ๋ ธ์ด์ฆ๋ ์ ๊ฑฐ๋๋ ํจ๊ณผ๊ฐ ์์ง๋ง ์๋๊ฐ ๋๋ฆฌ๋ค
dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst, borderType)
- src : ์
๋ ฅ ์์
- d : ํํฐ์ ์ง๊ฒฝ(diameter), 5๋ณด๋ค ํฌ๋ฉด ๋งค์ฐ ๋๋ฆผ
- sigmaColor : ์๊ณต๊ฐ์ ์๊ทธ๋ง ๊ฐ
- sigmaSpace : ์ขํ ๊ณต๊ฐ์ ์๊ทธ๋ง ๊ฐ
# ๋ฐ์ด๋ ํฐ๋ด ํํฐ์ ๊ฐ์ฐ์์ ํํฐ ๋น๊ต
import cv2
import numpy as np
img = cv2.imread("img/gaussian_noise.jpg")
# ๊ฐ์ฐ์์ ํํฐ ์ ์ฉ ---โ
blur1 = cv2.GaussianBlur(img, (5,5), 0)
# ๋ฐ์ด๋ ํฐ๋ด ํํฐ ์ ์ฉ ---โก
blur2 = cv2.bilateralFilter(img, 5, 75, 75)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img, blur1, blur2))
cv2.imshow('bilateral', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ๊ฐ์ฐ์์์ ๊ฒฝ๊ณ๊ฐ ํ๋ฆฟ, ๋ ํ๋ฆฌ๋ฉํ ..
- ๋ฐ์ด๋ ํฐ๋ด์ ๋ ธ์ด์ฆ ์ค๋ฉด์ ๊ฒฝ๊ณ๊ฐ ์ ์ง, ๊ฐ์ฐ์์๋ณด๋จ ์ ๋ช ๋๋ ท
'๐ฉโ๐ป IoT (Embedded) > Image Processing' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[v0.21]์์์ฒ๋ฆฌ_๋ชจํด๋ก์ง(Morphology) ์ฐ์ฐ (0) | 2022.01.11 |
---|---|
[v0.20]์์์ฒ๋ฆฌ_๊ฒฝ๊ณ ๊ฒ์ถ (0) | 2022.01.11 |
[v0.18]์์์ฒ๋ฆฌ_ ์ค์ตํ๊ธฐ(๋ชจ์์ดํฌ ์ฒ๋ฆฌ, ๋ฆฌํดํ์ด, ์๊ณก ๊ฑฐ์ธ ์ด๋ฏธ์ง ๋คํ๊ธฐ) (0) | 2022.01.08 |
[v0.17]์์์ฒ๋ฆฌ_๋ ์ฆ ์๊ณกํ๊ธฐ (0) | 2022.01.08 |
[v0.16]์์์ฒ๋ฆฌ_์ด๋ฏธ์ง ๋คํ๊ธฐ (0) | 2022.01.07 |