๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[v0.20]์์์ฒ๋ฆฌ_๊ฒฝ๊ณ ๊ฒ์ถ ๋ณธ๋ฌธ
[v0.20]์์์ฒ๋ฆฌ_๊ฒฝ๊ณ ๊ฒ์ถ
์ง์ง์ํ์นด 2022. 1. 11. 00:44220110 ์์ฑ
<๋ณธ ๋ธ๋ก๊ทธ๋ ๊ทํ์ด ์์ฌ๋์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํด์ ๊ณต๋ถํ๋ฉฐ ์์ฑํ์์ต๋๋ค>
OpenCV - 18. ๊ฒฝ๊ณ ๊ฒ์ถ (๋ฏธ๋ถ ํํฐ, ๋ก๋ฒ์ธ ๊ต์ฐจ ํํฐ, ํ๋ฆฌ์ ํํฐ, ์๋ฒจ ํํฐ, ์ค๋ฅด ํํฐ, ๋ผํ๋ผ์
์ด๋ฒ ํฌ์คํ ๋ถํฐ๋ ๊ฒฝ๊ณ๋ฅผ ๊ฒ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ์ด๋ฒ ํฌ์คํ ์ญ์ 'ํ์ด์ฌ์ผ๋ก ๋ง๋๋ OpenCV ํ๋ก์ ํธ(์ด์ธ์ฐ ์ )'๋ฅผ ์ ๋ฆฌํ ๊ฒ์์ ๋ฐํ๋๋ค. ์ฝ๋: github.com/BaekKyunShin/OpenCV_Pr
bkshin.tistory.com
1. ๊ธฐ๋ณธ ๋ฏธ๋ถ ํํฐ
์คํ๋ (Sharpening)
: ์์์ ๊ฒฝ๊ณ๋ฅผ ์ ๋ช ํ๊ณ ๋๋ ทํ๊ฒ ๋ง๋ ๋ค
: ์์์์ ๊ฒฝ๊ณ๋ฅผ ๊ฒ์ถํ์ฌ ๊ฒฝ๊ณ์ ์๋ ํฝ์ ๊ฐ์กฐ
1) ๊ฒฝ๊ณ(์ฃ์ง)๋ฅผ ๊ฒ์ถํ๊ธฐ ์ํด์๋ ํฝ์ ๊ฐ์ด ๊ธ๊ฒฉํ๊ฒ ๋ณํ๋ ์ง์ ์ฐพ๊ธฐ
2) ์ฐ์๋ ํฝ์ ๊ฐ์ ๋ฏธ๋ถ์ ํ์ฌ ์ฐพ๊ธฐ
3) ํฝ์ ์ ์ฐ์ ๊ณต๊ฐ ์์ ์์ง ์์ผ๋ฏ๋ก ๋ฏธ๋ถ ๊ทผ์ฌ๊ฐ ๊ตฌํ๊ธฐ
- ์๋ก ๋ถ์ด ์๋ ํฝ์ ๊ฐ์ ๋นผ๊ธฐ
- x๋ฐฉํฅ, y๋ฐฉํฅ์ผ๋ก ๊ฐ๊ฐ ํฝ์ ๊ฐ์ ๋นผ๋ฉด ๋ฏธ๋ถ ๊ทผ์ฌ๊ฐ
# ๋ฏธ๋ถ ์ปค๋๋ก ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
img = cv2.imread("img/sudoku.jpg")
#๋ฏธ๋ถ ์ปค๋ ์์ฑ ---โ
gx_kernel = np.array([[ -1, 1]])
gy_kernel = np.array([[ -1],[ 1]])
# ํํฐ ์ ์ฉ ---โก
edge_gx = cv2.filter2D(img, -1, gx_kernel)
edge_gy = cv2.filter2D(img, -1, gy_kernel)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img, edge_gx, edge_gy))
cv2.imshow('edge', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- x ๋ฐฉํฅ ๋ฏธ๋ถ ํํฐ๋ ์ธ๋ก ๋ฐฉํฅ์ ๊ฒฝ๊ณ ๊ฒ์ถ!
=> ์ข์ฐ ํฝ์ ๊ฐ์ ์ฐจ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํํฐ๋ง
- y ๋ฐฉํฅ ๋ฏธ๋ถ ํํฐ๋ ๊ฐ๋ก ๋ฐฉํฅ์ ๊ฒฝ๊ณ ๊ฒ์ถ!
=> ์ํ ํฝ์ ๊ฐ์ ์ฐจ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํํฐ๋ง
์์ ๊ธฐ
2. ๋ก๋ฒ์ธ ๊ต์ฐจ ํํฐ (Robert Cross Filter)
: ๋๊ฐ์ ๋ฐฉํฅ์ผ๋ก +1, -1์ ๋ฐฐ์น์์ผ ์ฌ์ ๊ฒฝ๊ณ ๊ฒ์ถ ํจ๊ณผ ๋์ธ๋ค
: ๋ ธ์ด์ฆ์ ๋ฏผ๊ฐํ๋ค
# ๋ก๋ฒ์ธ ๊ต์ฐจ ํํฐ๋ฅผ ์ ์ฉํ ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
img = cv2.imread("img/sudoku.jpg")
# ๋ก๋ฒ์ธ ์ปค๋ ์์ฑ ---โ
gx_kernel = np.array([[1,0], [0,-1]])
gy_kernel = np.array([[0, 1],[-1,0]])
# ์ปค๋ ์ ์ฉ ---โก
edge_gx = cv2.filter2D(img, -1, gx_kernel)
edge_gy = cv2.filter2D(img, -1, gy_kernel)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img, edge_gx, edge_gy, edge_gx+edge_gy))
cv2.imshow('roberts cross', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ๋๊ฐ์ ํ๋๊น ์ค๋ฅธ์ชฝ ์๊ฐ ์ ๋ช ํ๊ตฐ
- ๊ฑฐ๊พธ๋ก ํด๋ณผ๊น
3. ํ๋ฆฌ์ ํํฐ (Prewitt Filter)
: x์ถ๊ณผ y์ถ์ ๊ฐ ๋ฐฉํฅ์ผ๋ก ์ฐจ๋ถ์ ์ธ ๋ฒ ๊ณ์ฐํ์ฌ ๊ฒฝ๊ณ๋ฅผ ๊ฒ์ถํ๋ ํํฐ
: ์ํ/์ข์ฐ ๊ฒฝ๊ณ๋ ๋๋ ทํ๊ฒ ์ ๊ฒ์ถํ์ง๋ง ๋๊ฐ์ ๊ฒ์ถ์ด ์ฝํ๋ค
# ํ๋ฆฌ์ ๋ง์คํฌ๋ฅผ ์ ์ฉํ ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
file_name = "img/sudoku.jpg"
img = cv2.imread(file_name)
# ํ๋ฆฌ์ ์ปค๋ ์์ฑ
gx_k = np.array([[-1,0,1], [-1,0,1],[-1,0,1]])
gy_k = np.array([[-1,-1,-1],[0,0,0], [1,1,1]])
# ํ๋ฆฌ์ ์ปค๋ ํํฐ ์ ์ฉ
edge_gx = cv2.filter2D(img, -1, gx_k)
edge_gy = cv2.filter2D(img, -1, gy_k)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img, edge_gx, edge_gy, edge_gx+edge_gy))
cv2.imshow('prewitt', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
4. ์๋ฒจ ํํฐ (Sovel Filter)
: ์ค์ฌ ํฝ์ ์ ์ฐจ๋ถ ๋น์ค์ ๋ ๋ฐฐ๋ก ์ค ํํฐ
: x์ถ, y์ถ, ๋๊ฐ์ ๋ฐฉํฅ์ ๊ฒฝ๊ณ ๊ฒ์ถ์ ๋ชจ๋ ๊ฐํจ
: ์ปค๋์ ์ค์ฌ์์ ๋ฉ์ด์ง์๋ก ์ฃ์ง ๋ฐฉํฅ์ฑ์ ์ ํ๋๊ฐ ๋จ์ด์ง๋ค
dst = cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
- src : ์
๋ ฅ ์์
- ddepth : ์ถ๋ ฅ ์์์ dtype (-1: ์
๋ ฅ ์์๊ณผ ๋์ผ)
- dx, dy : ๋ฏธ๋ถ ์ฐจ์ (0, 1, 2 ์ค ์ ํ, ๋ ๋ค 0์ผ ์๋ ์์)
- ksize : ์ปค๋์ ํฌ๊ธฐ (1, 3, 5, 7 ์ค ์ ํ)
- scale : ๋ฏธ๋ถ์ ์ฌ์ฉํ ๊ณ์
- delta : ์ฐ์ฐ ๊ฒฐ๊ณผ์ ๊ฐ์ฐํ ๊ฐ
# ์๋ฒจ ๋ง์คํฌ๋ฅผ ์ ์ฉํ ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
img = cv2.imread("img/sudoku.jpg")
# ์๋ฒจ ์ปค๋์ ์ง์ ์์ฑํด์ ์ฃ์ง ๊ฒ์ถ ---โ
## ์๋ฒจ ์ปค๋ ์์ฑ
gx_k = np.array([[-1,0,1], [-2,0,2],[-1,0,1]])
gy_k = np.array([[-1,-2,-1],[0,0,0], [1,2,1]])
## ์๋ฒจ ํํฐ ์ ์ฉ
edge_gx = cv2.filter2D(img, -1, gx_k)
edge_gy = cv2.filter2D(img, -1, gy_k)
# ์๋ฒจ API๋ฅผ ์์ฑํด์ ์ฃ์ง ๊ฒ์ถ
sobelx = cv2.Sobel(img, -1, 1, 0, ksize=3)
sobely = cv2.Sobel(img, -1, 0, 1, ksize=3)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged1 = np.hstack((img, edge_gx, edge_gy, edge_gx+edge_gy))
merged2 = np.hstack((img, sobelx, sobely, sobelx+sobely))
merged = np.vstack((merged1, merged2))
cv2.imshow('sobel', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
5. ์ค๋ฅด ํํฐ (Scharr Filter)
: ์๋ฒจ ํํฐ ๊ฐ์ ํ ํํฐ
dst = cv2.Scharr(src, ddepth, dx, dy, dst, scale, delta, borderType)
- ksize๊ฐ ์๋ค
- ๋ชจ๋ ํ๋ผ๋ฏธํฐ๋ cv2.Sobel()๊ณผ ๋์ผ
# ์ค๋ฅด ๋ง์คํฌ๋ฅผ ์ ์ฉํ ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
img = cv2.imread("img/sudoku.jpg")
# ์ค๋ฅด ์ปค๋์ ์ง์ ์์ฑํด์ ์ฃ์ง ๊ฒ์ถ ---โ
gx_k = np.array([[-3,0,3], [-10,0,10],[-3,0,3]])
gy_k = np.array([[-3,-10,-3],[0,0,0], [3,10,3]])
edge_gx = cv2.filter2D(img, -1, gx_k)
edge_gy = cv2.filter2D(img, -1, gy_k)
# ์ค๋ฅด API๋ก ์ฃ์ง ๊ฒ์ถ ---โก
scharrx = cv2.Scharr(img, -1, 1, 0)
scharry = cv2.Scharr(img, -1, 0, 1)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged1 = np.hstack((img, edge_gx, edge_gy))
merged2 = np.hstack((img, scharrx, scharry))
merged = np.vstack((merged1, merged2))
cv2.imshow('Scharr', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
6. ๋ผํ๋ผ์์ ํํฐ (Laplacian Filter)
: 2์ฐจ ๋ฏธ๋ถ์ ์ ์ฉ
: ๊ฒฝ๊ณ๋ฅผ ๋ ์ ๋๋ก ๊ฒ์ถ
dst = cv2.Laplacian(src, ddepth, dst, ksize, scale, delta, borderType)
- ํ๋ผ๋ฏธํฐ๋ cv2.Sobel()๊ณผ ๋์ผ
# ๋ผํ๋ผ์์ ๋ง์คํฌ๋ฅผ ์ ์ฉํ ๊ฒฝ๊ณ ๊ฒ์ถ
import cv2
import numpy as np
img = cv2.imread("img/sudoku.jpg")
# ๋ผํ๋ผ์์ ํํฐ ์ ์ฉ ---โ
edge = cv2.Laplacian(img, -1)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
merged = np.hstack((img, edge))
cv2.imshow('Laplacian', merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ๊ฒฝ๊ณ ๋๋ ท
- ๊น๋ํ๋ค ๊ทผ๋ฐ ์กฐ๊ธ ํฌ๋ฏธํ๋..
7. ์บ๋ ์ฃ์ง (Canny Edge)
: ํ ๊ฐ์ง ํํฐ๋ง ์ฌ์ฉ์ด ์๋, 4 ๋จ๊ณ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ ๊ฒฝ๊ณ๋ฅผ ๊ฒ์ถ
1) ๋ ธ์ด์ฆ ์ ๊ฑฐ
: 5 x 5 ๊ฐ์ฐ์์ ๋ธ๋ฌ๋ง ํํฐ๋ก ๋
ธ์ด์ฆ ์ ๊ฑฐ
2) ๊ฒฝ๊ณ ๊ทธ๋ ๋์ธํธ ๋ฐฉํฅ ๊ณ์ฐ
: ์๋ฒจ ํํฐ๋ก ๊ฒฝ๊ณ ๋ฐ ๊ทธ๋ ๋์ธํธ ๋ฐฉํฅ ๊ฒ์ถ
3) ๋น์ต๋์น ์ต์ (Non-Maximum Suppression)
: ๊ทธ๋ ๋์ธํธ ๋ฐฉํฅ์์ ๊ฒ์ถ๋ ๊ฒฝ๊ณ ์ค ๊ฐ์ฅ ํฐ ๊ฐ๋ง ์ ํํ๊ณ ๋๋จธ์ง๋ ์ ๊ฑฐ
4) ์ด๋ ฅ ์ค๋ ์ํ๋ฉ
: ๋ ๊ฐ์ ๊ฒฝ๊ณ ๊ฐ(Max, Min)์ ์ง์ ํด์ ๊ฒฝ๊ณ ์์ญ์ ์๋ ํฝ์ ๋ค ์ค
ํฐ ๊ฒฝ๊ณ ๊ฐ(Max) ๋ฐ์ ํฝ์ ๊ณผ ์ฐ๊ฒฐ์ฑ์ด ์๋ ํฝ์ ์ ๊ฑฐ
edges = cv2.Canny(img, threshold1, threshold2, edges, apertureSize, L2gardient)
- img : ์
๋ ฅ ์์
- threshold1, threshold2 : ์ด๋ ฅ ์ค๋ ์ํ๋ฉ์ ์ฌ์ฉํ Min, Max ๊ฐ
- apertureSize : ์๋ฒจ ๋ง์คํฌ์ ์ฌ์ฉํ ์ปค๋ ํฌ๊ธฐ
- L2gradient : ๊ทธ๋ ๋์ธํธ ๊ฐ๋๋ฅผ ๊ตฌํ ๋ฐฉ์ (True: ์ ๊ณฑ ํฉ์ ๋ฃจํธ False: ์ ๋๊ฐ์ ํฉ)
- edges : ์ฃ์ง ๊ฒฐ๊ณผ ๊ฐ์ ๊ฐ๋ 2์ฐจ์ ๋ฐฐ์ด
# ์บ๋ ์ฃ์ง ๊ฒ์ถ
import cv2, time
import numpy as np
img = cv2.imread("img/sudoku.jpg")
# ์ผ๋ ์ฃ์ง ์ ์ฉ
edges = cv2.Canny(img,100,200)
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
cv2.imshow('Original', img)
cv2.imshow('Canny', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
- ๊ฒฝ๊ณ ๊ฒ์ถ ๊ตฟ๊ตฟ
์ถ์ต๋๋๋ค..
์ค๋์ฟ
'๐ฉโ๐ป IoT (Embedded) > Image Processing' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[v0.22]์์์ฒ๋ฆฌ_๋ชจํด๋ก์ง(Morphology) ์ฐ์ฐ (0) | 2022.01.12 |
---|---|
[v0.21]์์์ฒ๋ฆฌ_๋ชจํด๋ก์ง(Morphology) ์ฐ์ฐ (0) | 2022.01.11 |
[v0.19]์์์ฒ๋ฆฌ_ ํํฐ์ ์ปจ๋ณผ๋ฃจ์ ์ฐ์ฐ, ๋ธ๋ฌ๋ง (0) | 2022.01.08 |
[v0.18]์์์ฒ๋ฆฌ_ ์ค์ตํ๊ธฐ(๋ชจ์์ดํฌ ์ฒ๋ฆฌ, ๋ฆฌํดํ์ด, ์๊ณก ๊ฑฐ์ธ ์ด๋ฏธ์ง ๋คํ๊ธฐ) (0) | 2022.01.08 |
[v0.17]์์์ฒ๋ฆฌ_๋ ์ฆ ์๊ณกํ๊ธฐ (0) | 2022.01.08 |