๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

AI/Computer Vision

[Computer Vision] Filtering

728x90
๋ฐ˜์‘ํ˜•

 

๐Ÿ‘€ ๋ณธ ์˜ˆ์ œ๋Š” Window10์˜ VSCode, Python3.11.0๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

ํ•„ํ„ฐ(filter)๋ผ๋Š” ๋ง์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ฑธ๋Ÿฌ ๋‚ด๊ตฌ ์ผ๋ถ€๋งŒ ํ†ต๊ณผ์‹œํ‚ค๋Š” ์žฅ์น˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

์˜์ƒ์ฒ˜๋ฆฌ์—์„œ ํ•„ํ„ฐ๋Š” ์˜์ƒ์—์„œ ์›ํ•˜๋Š” ์ •๋ณด๋งŒ ํ†ต๊ณผ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ
  • Smoothing
  • Sharping

 

์˜์ƒ์˜ ํ•„ํ„ฐ๋ง์€ ๋ณดํ†ต ๋งˆ์Šคํฌ(mask)๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ž‘์€ ํ–‰๋ ฌ์„ ์ด์šฉํ•œ๋‹ค.

 

๋งˆ์Šคํฌ๋Š” ํ•„ํ„ฐ๋ง์˜ ์„ฑ๊ฒฉ์„ ์ •์˜ํ•˜๋Š” ํ–‰๋ ฌ๋กœ ์ปค๋„(kernel), ์œˆ๋„์šฐ(Window)๋ผ๊ณ ๋„ ๋ถ€๋ฅด๋ฉฐ, ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ๋Š” ๋งˆ์Šคํฌ ์ž์ฒด๋ฅผ ํ•„ํ„ฐ๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค.

 

๋งˆ์Šคํฌ๋Š” ์ง์‚ฌ๊ฐํ˜• ํ–‰๋ ฌ ๋˜๋Š” ์ •๋ฐฉํ˜• ํ–‰๋ ฌ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ๋˜ํ•œ ํ•„์š”ํ•˜๋‹ค๋ฉด ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ธฐ๋ณธ ํ•„ํ„ฐ๋ง

๊ธฐ๋ณธ์ ์ธ ํ•„ํ„ฐ๋ง์€ Numpy๋กœ ๋งŒ๋“  ํ–‰๋ ฌ๊ณผ filter2D ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
for i in [3,6,10]:
    kernel = np.ones((i,i),np.uint8) / i ** 2
    filtering = cv2.filter2D(img,-1,kernel=kernel)
    cv2.imshow(f"{i}x{i}filter",filtering)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

์˜ํ‘œ๋ฉด์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํ•˜๋Š” ์— ๋ณด์‹ฑ(embossing) ํ•„ํ„ฐ๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png",cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
kernel = np.array([[-1, -1, 0], [-1, 0, 1], [0, 1, 1]])
filtering = cv2.filter2D(img,-1,kernel=kernel)
filtering = np.uint8(filtering)

cv2.imshow("filter",filtering)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

๋ธ”๋Ÿฌ๋ง(Blurring) : ์˜์ƒ์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ

๋ธ”๋Ÿฌ๋ง ๊ธฐ๋ฒ•์ด๋ž€ ์ดˆ์ ์ด ๋งž์ง€ ์•Š์€ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์˜์ƒ์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋งŒ๋“œ๋Š” ํ•„ํ„ฐ๋ง ๊ธฐ๋ฒ•์œผ๋กœ smoothing์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค.

 

์›๋ž˜๋Š” ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ•„ํ„ฐ๋ง์„ ํ•ด์•ผํ•˜์ง€๋งŒ OpenCV๋Š” blur๋กœ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

blur์— ์‚ฌ์šฉ๋˜๋Š” ํ•„ํ„ฐ๋Š” ํ‰๊ท ๊ฐ’ ํ•„ํ„ฐ(3x3, 5x5, 7x7)์ด๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
blur = cv2.blur(img,(3,3))
cv2.imshow("blur",blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

๊ฐ€์šฐ์‹œ์•ˆ ํ•„ํ„ฐ๋ง(Gaussian Filtering) : ์žก์Œ์„ ์ œ๊ฑฐ

๊ฐ€์šฐ์‹œ์•ˆ ํ•„ํ„ฐ๋ง์€ ๊ฐ€์šฐ์‹œ์•ˆ ๋ถ„ํฌ ํ•จ์ˆ˜๋ฅผ ๊ทผ์‚ฌํ•˜์—ฌ ์ƒ์„ฑํ•œ ํ•„ํ„ฐ ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•œ ํ•„ํ„ฐ๋ง ๊ธฐ๋ฒ•์ด๋‹ค.

 

๊ฐ€์šฐ์‹œ์•ˆ ๋ถ„ํฌ๋Š” ํ‰๊ท ์„ ์ค‘์‹ฌ์œผ๋กœ ์ขŒ์šฐ ๋Œ€์นญ์˜ ์ข… ๋ชจ์–‘(bell shape)์„ ๊ฐ–๋Š” ํ™•๋ฅ  ๋ถ„ํฌ๋ฅผ ๋งํ•˜๋ฉฐ ์ •๊ทœ๋ถ„ํฌ๋กœ๋„ ๋ถˆ๋ฆฐ๋‹ค.

 

GaussianBlur ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํ•„ํ„ฐ๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
gaussian = cv2.GaussianBlur(img,(0,0),sigmaX=3) # sigmaX์˜ ๊ฐ’์— ๋”ฐ๋ผ ํ•„ํ„ฐ๋ง ๊ฐ•๋„ ๋ฐ”๋€œ 
cv2.imshow("gaussian",gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

๋ฏธ๋””์•ˆ ํ•„ํ„ฐ๋ง(Median Filtering) : ์†Œ๊ธˆ ํ›„์ถ” ์žก์Œ ์ œ๊ฑฐ์šฉ

๋ฏธ๋””์•ˆ ํ•„ํ„ฐ๋ง์€ ๋”ฐ๋กœ ์ปค๋„์„ ๋งŒ๋“ค์–ด ํ•„ํ„ฐ๋ง์„ ํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ ์œˆ๋„์šฐ์— ์žˆ๋Š” ๋ชจ๋“  ํ”ฝ์…€์„ ์ •๋ ฌํ•˜์—ฌ ์ค‘๊ฐ„๊ฐ’์„ ์„ ํƒํ•˜์—ฌ ํ•„ํ„ฐ๋งํ•œ๋‹ค.

 

์žก์Œ ํ”ฝ์…€ ๊ฐ’์ด ์ฃผ๋ณ€ ํ”ฝ์…€ ๊ฐ’๊ณผ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์— ํšจ๊ณผ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

medianBlur ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„ํ„ฐ๋ง ํ•œ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
median = cv2.medianBlur(img,7)
cv2.imshow("median",median)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ๋ง(Bilateral Filtering)

๋‘ ํ”ฝ์…€์˜ ๋ช…์•”๊ฐ’ ์ฐจ์ด ๋˜ํ•œ ์ปค๋„์— ๋„ฃ์–ด ๊ฐ€์ค‘์น˜๋กœ ๊ณฑํ•œ๋‹ค.

 

ํ”ฝ์…€์˜ ์ฐจ์ด๊ฐ€ ํฌ๋‹ค๋ฉด ๊ฐ€์ค‘์น˜๊ฐ€ 0์— ๊ฐ€๊นŒ์šด ๊ฐ’์ด ๋˜์–ด ํ•ฉ์ณ์ง€์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜์—ญ๊ณผ ์˜์—ญ ์‚ฌ์ด์ฆˆ์˜ ๊ฒฝ๊ณ„์„ ์ด ์ž˜ ๋ณด์ „๋  ์ˆ˜ ์žˆ๋‹ค.

 

์—ฃ์ง€๋ฅผ ๋ณด์กดํ•ด์ฃผ๊ณ  ๊ธฐ์กด์— ํ”ฝ์…€๊ณผ ์ด์›ƒ ํ”ฝ์…€๊ฐ„์˜ ๊ฑฐ๋ฆฌ, ํ”ฝ์…€๊ฐ„์˜ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ธ”๋Ÿฌ๋ง์„ ์ง„ํ–‰ํ•œ๋‹ค.

 

bilateralFilter๋กœ ํ•„ํ„ฐ๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
bilateral = cv2.bilateralFilter(img,d=-1,sigmaColor=10,sigmaSpace=5)
cv2.imshow("bilateral",bilateral)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

์ƒคํ”„๋‹(sharpening)

์˜์ƒ์„ ๋‚ ์นด๋กญ๊ฒŒ ๋งŒ๋“œ๋Š” ์ฒ˜๋ฆฌ์ด๋‹ค.

 

์ €ํ™”์งˆ ์˜์ƒ์„ ๋ณด๋‹ค ์„ ๋ช…ํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

 

์ค‘์‹ฌ ํ™”์†Œ๊ฐ’๊ณผ ์ธ์ ‘  ํ™”์†Œ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ๋” ํฌ๊ฒŒ ๋งŒ๋“ ๋‹ค.

 

์ƒคํ”„๋‹์€ Numpy๋กœ ์ƒคํ”„๋‹ ๋งˆ์Šคํฌ๋ฅผ ๋งŒ๋“ค์–ด ํ•„ํ„ฐ๋ง ํ•œ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
blur = cv2.blur(img,(3,3))
cv2.imshow("blur",blur)
mask = np.asarray([[-1,-1,-1],
                   [-1,9,-1],
                   [-1,-1,-1]], dtype = np.float32)
sharpening_img = cv2.filter2D(blur,-1, mask)
cv2.imshow("sharp",sharpening_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

Canny Edge

์˜์ƒ์—์„œ ํ™”์†Œ์˜ ๋ฐ๊ธฐ๊ฐ€ ๊ธ‰๊ฒฉํ•˜๊ฒŒ ๋ณ€ํ•˜๋Š” ๋ถ€๋ถ„์„ ์—์ง€(edge)๋ผ๊ณ  ํ•œ๋‹ค.

 

์˜์ƒ์•ˆ์—์„œ ์ƒ๋‹นํ•œ ๋ฐ๊ธฐ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ณณ์ด๊ณ , ๋Œ€๊ฒŒ ๋ฌผ์ฒด์˜ ์œค๊ณฝ์„ (๊ฒฝ๊ณ„์„ )์— ํ•ด๋‹นํ•œ๋‹ค.

 

์—์ง€๋ฅผ ๊ฒ€์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ๋ฌผ์ฒด์˜ ์œค๊ณฝ์„ ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ์—์ง€๋ฅผ ๊ฒ€์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋‚˜ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์€ "Canny Edge" ๊ฒ€์ถœ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

Canny Edge์˜ ์—ฐ์‚ฐ ์ˆœ์„œ

  1. ์žก์Œ ์–ต์ œ : ์—์ง€๋ฅผ ๊ฒ€์ถœํ•˜๊ธฐ ์ „์— 5x5 ๊ฐ€์šฐ์‹œ์•ˆ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜์ƒ์˜ ์žก์Œ์„ ์ œ๊ฑฐ.
  2. ๊ทธ๋ผ๋””์–ธํŠธ ๊ณ„์‚ฐ : Sobal ๋งˆ์Šคํฌ๋กœ ์ˆ˜ํ‰ ๋ฐ ์ˆ˜์ง ๋ฐฉํ–ฅ์˜ 1์ฐจ ๋ฏธ๋ถ„๊ฐ’์„ ์–ป์Œ.
  3. ๋ถˆํ•„์š”ํ•œ ์—์ง€๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ๋ผ๋””์–ธํŠธ์˜ ๊ฐ’์ด ๊ทธ๋ผ๋””์–ธํŠธ ๋ฐฉํ–ฅ์˜ ์ธ์ ‘ ํ™”์†Œ ์ค‘์—์„œ ์ตœ๋Œ€๊ฐ’์ธ์ง€๋ฅผ ํ™•์ธ.
  4. ๋ชจ๋“  ์—์ง€ ํ›„๋ณด๋“ค์ด ์‹ค์ œ ์—์ง€์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๊ฒฐ์ •

 

Canny ์—์ง€๋Š” Canny ํ•จ์ˆ˜๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

import numpy as np
import cv2

img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",img)
# cv2.Canny(์ด๋ฏธ์ง€,ํ•˜์œ„ ์ž„๊ณ„๊ฐ’,์ƒ์œ„ ์ž„๊ณ„๊ฐ’, sobal ๋งˆ์Šคํฌ ํฌ๊ธฐ)
edge = cv2.Canny(img,100,255)
cv2.imshow("canny",edge)
cv2.waitKey(0)
cv2.destroyAllWindows()

728x90
๋ฐ˜์‘ํ˜•