λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

AI/Computer Vision

[Computer Vision] μ˜μƒμ˜ κΈ°ν•˜ν•™μ  λ³€ν™˜

728x90
λ°˜μ‘ν˜•
πŸ‘€ λ³Έ μ˜ˆμ œλŠ” Window10의 VSCode, Python3.11.0둜 μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

μ˜μƒμ˜ κΈ°ν•˜ν•™μ (Geometric Transform)은 μ˜μƒμ„ κ΅¬μ„±ν•˜λŠ” ν”½μ…€μ˜ 배치 ꡬ쑰λ₯Ό λ³€κ²½ν•¨μœΌλ‘œμ¨ 전체 μ˜μƒμ˜ λͺ¨μ–‘을 λ°”κΎΈλŠ” μž‘μ—…μ΄λ‹€.

 

이전 필터링은 ν”½μ…€μ˜ μœ„μΉ˜λ₯Ό κ³ μ •ν•˜κ³  ν”½μ…€μ˜ 값을 λ³€κ²½ν•˜μ˜€μ§€λ§Œ κΈ°ν•˜ν•™μ  λ³€ν™˜μ€ ν”½μ…€ 값은 κ·ΈλŒ€λ‘œ μœ μ§€ν•˜λ©΄μ„œ μœ„μΉ˜λ₯Ό λ³€κ²½ν•˜λŠ” μž‘μ—…μ΄λ‹€.

 

Affine Transform

μ˜μƒμ„ 평행 μ΄λ™μ‹œν‚€κ±°λ‚˜ νšŒμ „, 크기 λ³€ν™˜ 등을 톡해 λ§Œλ“€ 수 μžˆλŠ” λ³€ν™˜μ„ ν†΅μΉ­ν•œλ‹€.

 

Affine λ³€ν™˜μ˜ 경우 직선 κ°„μ˜ 길이 λΉ„μœ¨κ³Ό 평행 관계가 κ·ΈλŒ€λ‘œ μœ μ§€λœλ‹€.

# transforms.py
import cv2
import numpy as np
def affineTransform(image:np.ndarray,matrix:np.ndarray,shape:tuple):
    return cv2.warpAffine(image,matrix,shape)

# main.py
import cv2
import numpy as np
# affine
from transforms import affineTransform

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

points_src = np.float32([[50, 50], [200, 50], [50, 200]]) # λ³€ν™˜ μ „μ˜ 점듀
points_dst = np.float32([[10, 100], [200, 50], [100, 250]]) # λ³€ν™˜ ν›„μ˜ 점듀
matrix = cv2.getAffineTransform(points_src,points_dst)

aff_result = affineTransform(img,matrix,img.shape[:2])

show(img,aff_result)

 

 

Translation Transformation

이동 λ³€ν™˜μ€ μ˜μƒμ„ κ°€λ‘œ λ˜λŠ” μ„Έλ‘œ λ°©ν–₯으둜 일정 크기만큼 μ΄λ™μ‹œν‚€λŠ” μ—°μ‚°(μ‹œν”„νŠΈ μ—°μ‚°)을 μ˜λ―Έν•œλ‹€.

# transforms.py
import cv2
import numpy as np

def translationTransform(image:np.ndarray,matrix:np.ndarray,shape:tuple):
    return cv2.warpAffine(image,matrix,shape)
    
# main.py
import cv2
import numpy as np
# affine
from transforms import affineTransform

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

tx = 100 # xμΆ•μœΌλ‘œ 이동할 거리
ty = 50 # yμΆ•μœΌλ‘œ 이동할 거리
matrix = np.float32([[1,0,tx],[0,1,ty]])
result = translationTransform(img,matrix,img.shape[:2])

show(img,result)

 

 

Shear Transformation

전단 λ³€ν™˜μ€ μ§μ‚¬κ°ν˜• ν˜•νƒœμ˜ μ˜μƒμ„ ν•œμͺ½ λ°©ν–₯을 λ°€μ–΄μ„œ ν‰ν–‰μ‚¬λ³€ν˜• λͺ¨μ–‘μœΌλ‘œ λ³€ν˜•λ˜λŠ” λ³€ν™˜μ΄λ©° μΈ΅λ°€λ¦Ό λ³€ν™˜μ΄λΌκ³ λ„ ν•œλ‹€.

 

# transforms.py
import cv2
import numpy as np
def transformation(image:np.ndarray,matrix:np.ndarray,shape:tuple):
    return cv2.warpAffine(image,matrix,shape)

# main.py
import cv2
import numpy as np
# affine
from transforms import transformation

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

shear_factor = 0.5
matrix = np.float32([[1, shear_factor, 0], [0, 1, 0]])
shape = img.shape[:2]
result = transformation(img,matrix,(int(shape[0]+shape[1] * shear_factor),shape[1]))
show(img,result)

 

 

Scale Transformation

μ˜μƒμ˜ 크기 λ³€ν™˜μ€ μ˜μƒμ˜ 전체적인 크기λ₯Ό ν™•λŒ€ λ˜λŠ” μΆ•μ†Œν•˜λŠ” λ³€ν™˜μ΄λ‹€.

 

μ˜μƒμ˜ μŠ€μΌ€μΌλ§ μ‹œ μ˜μƒ 손싀이 있기 λ•Œλ¬Έμ— κ·Έλ•Œμ— λ§žλŠ” λ³΄κ°„λ²•μœΌλ‘œ μ˜μƒ 손싀을 μ΅œμ†Œν™” ν•΄μ•Όν•œλ‹€.

 

InterpolationFlags

  • cv2.INTER_NEAREST : κ°€μž₯ 간단, κ°€μž₯ κ°€κΉŒμš΄ ν”½μ…€ 값을 μ‚¬μš©
  • cv2. INTER_LINEAR : 2x2 ν”½μ…€ λ„€νŠΈμ›Œν¬μ—μ„œ μ„ ν˜• 보간 μˆ˜ν–‰, 일반적인 ν™•λŒ€ 및 μΆ•μ†Œμ— 적합
  • cv2. INTER_CUBIC : 4x4 ν”½μ…€ λ„€νŠΈμ›Œν¬μ—μ„œ 3μ°¨ 보간 μ‚¬μš©, ν™•λŒ€ν•  λ•Œ 주둜 μ‚¬μš©
  • cv2. INTER_AREA : ν”½μ…€ μ˜μ—­ 평균을 μ‚¬μš©ν•˜μ—¬ 이미지λ₯Ό μΆ•μ†Œν•  λ•Œ 주둜 μ‚¬μš©, μΆ•μ†Œ μ‹œ ν’ˆμ§ˆ μ’‹κ³ , λͺ¨μžμ΄ν¬ 효과λ₯Ό μ€„μ΄λŠ” 데 효과적
  • cv2. INTER_LANCZOS4 : 8x8 ν”½μ…€ λ„€νŠΈμ›Œν¬μ—μ„œ Lanczos μž¬μƒ˜ν”Œλ§μ„ μ‚¬μš©, κ°€μž₯ μ„±λŠ₯이 μ’‹κ³  μΆ•μ†Œμ‹œ λ•Œ 효과적

 

import cv2
import numpy as np

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

result = cv2.resize(img,None,fx=1.5,fy=1.5,interpolation=cv2.INTER_LANCZOS4)

show(img,result)

 

 

Rotation Transformation

μ˜μƒ 처리 μ‹œμŠ€ν…œμ„ λ§Œλ“€λ‹€λ³΄λ©΄ μ˜μƒμ„ νšŒμ „ μ‹œμΌœμ•Όν•  λ•Œκ°€ μ’…μ’… λ°œμƒν•œλ‹€.

 

μ΄λ•Œ μ‚¬μš©ν•˜λŠ” νšŒμ „ λ³€ν™˜μ€ νŠΉμ • μ’Œν‘œλ₯Ό κΈ°μ€€μœΌλ‘œ μ˜μƒμ„ μ›ν•˜λŠ” κ°λ„λ§ŒνΌ νšŒμ „ν•˜λŠ” λ³€ν™˜μ΄λ‹€.

import cv2
import numpy as np
# affine
from transforms import transformation

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

# νšŒμ „ μΆ• μ’Œν‘œ
h,w,_ = img.shape
center = (h // 2,w // 2)
# νšŒμ „ 각도
angle = 45
# λ³€ν˜Έλ‚˜ ν–‰λ ¬
matrix = cv2.getRotationMatrix2D(center,angle,1.0) # λ§ˆμ§€λ§‰ μΈμžλŠ” μŠ€μΌ€μΌλ§
result = transformation(img,matrix,(w,h))

show(img,result)

 

 

Symmetry Transformation

λŒ€μΉ­ λ³€ν™˜μ€ μ˜μƒμ„ 마치 κ±°μšΈμ— λΉ„μΉœ κ²ƒμ²˜λŸΌ 쒌우λ₯Ό λ°”κΎΈλŠ” λ³€ν™˜μ„ 쒌우 λŒ€μΉ­ λ˜λŠ” 쒌우 λ°˜μ „μ΄λΌκ³  ν•œλ‹€.

 

μž…λ ₯ μ˜μƒκ³Ό 좜λ ₯ μ˜μƒμ΄ μΌλŒ€μΌ λŒ€μ‘λ˜λ―€λ‘œ 보간법이 ν•„μš”ν•˜μ§€ μ•ŠλŠ”λ‹€.

import cv2
import numpy as np

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))
cv2.imshow("origin",origin)
# μˆ˜ν‰ λŒ€μΉ­ (XμΆ• κΈ°μ€€)
horizontal_flip = cv2.flip(img, 0)
cv2.imshow("horizon",horizontal_flip)
# 수직 λŒ€μΉ­ (YμΆ• κΈ°μ€€)
vertical_flip = cv2.flip(img, 1)
cv2.imshow("vertical",vertical_flip)
# 쀑심 λŒ€μΉ­ (원점 κΈ°μ€€)
both_flip = cv2.flip(img, -1)
cv2.imshow("both",both_flip)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

 

Perspectuve Transform

νˆ¬μ‹œ λ³€ν™˜μ€ μ§μ‚¬κ°ν˜• ν˜•νƒœμ˜ μ˜μƒμ„ μž„μ˜μ˜ 볼둝 μ‚¬κ°ν˜• ν˜•νƒœλ‘œ λ³€κ²½ν•  수 μžˆλŠ” λ³€ν™˜μ΄λ‹€.

 

νˆ¬μ‹œ λ³€ν™˜μ— μ˜ν•΄ 원본 μ˜μƒμ— 있던 직선은 κ²°κ³Ό μ˜μƒμ—μ„œ κ·ΈλŒ€λ‘œ 직선성이 μœ μ§€λ˜μ§€λ§Œ, 두 μ§μ„ μ˜ 평행 κ΄€κ³„λŠ” κΉ¨μ–΄μ§ˆ 수 μžˆλ‹€.

import cv2
import numpy as np
# affine
from transforms import transformation_per

def show(origin:np.ndarray,result:np.ndarray):
    cv2.imshow("origin",origin)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread("test.png")
img = cv2.resize(img,(480,480))

# 원본 μ΄λ―Έμ§€μ—μ„œ λ³€ν™˜ν•  λ„€ 점 (μ‹œμž‘μ )
points = np.float32([[50, 50], [200, 50], [50, 200], [200, 200]])

# λ³€ν™˜ν•  λ„€ 점 (λŒ€μƒμ )
dst_points = np.float32([[10, 10], [300, 50], [50, 250], [250, 200]])

# νˆ¬μ‹œ λ³€ν™˜ ν–‰λ ¬ 생성
matrix = cv2.getPerspectiveTransform(points, dst_points)

# 이미지에 νˆ¬μ‹œ λ³€ν™˜ 적용
height, width = img.shape[:2]
result = cv2.warpPerspective(img, matrix, (width, height))
show(img,result)

 

728x90
λ°˜μ‘ν˜•