πŸ’»/λ©€ν‹°λ―Έλ””μ–΄

[μ˜μƒμ²˜λ¦¬] κΈ°ν•˜ λ³€ν™˜, μ—­λ°©ν–₯ 맀핑

ruhz 2020. 10. 11. 21:43

μ–΄νŒŒμΈ κΈ°ν•˜ λ³€ν™˜ (Affine Transformation)

μ €λŠ” Affine을 'μ–΄νŒŒμΈ'으둜 읽도둝 λ°°μ› μ§€λ§Œ μœ„ν‚€ν”Όλ””μ•„μ—μ„œλŠ” 'μ–΄ν•€'이라고 ν•˜λ‚˜ λ΄…λ‹ˆλ‹€. μš°λ¦¬κ°€ 0-9의 숫자λ₯Ό μ •μ˜ν•˜κ³  κ·Έ μ•ˆμ—μ„œ 연산을 μ •μ˜ν•΄ 문제λ₯Ό ν•΄κ²°ν•˜λ“―, μ–΄νŒŒμΈλ„ μ–΄λ– ν•œ 체계(곡간)λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. μ–΄νŒŒμΈμ€ 점과 벑터λ₯Ό μ›μ†Œλ‘œ, κ·Έκ²ƒλ“€μ˜ 연산을 μ •μ˜ν•©λ‹ˆλ‹€. ν•œ ν¬μŠ€νŒ…μ•ˆμ—μ„œ λ‹€λ£¨κΈ°μ—λŠ” μžλ£Œκ°€ λ§Žμ•„, 좔후에 ν¬μŠ€νŒ…ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. κ΄€λ ¨ λ‚΄μš©μ€ μœ νŠœλΈŒλ‚˜ ꡬ글을 μ°Έκ³ ν•˜μ‹œκΈΈ λ°”λžλ‹ˆλ‹€.

 

 

μ•„ν•€ λ³€ν™˜ (Affine Transformation)

μ•„ν•€ λ³€ν™˜μ΄ 점, 직선 및 평면을 μ–΄λ–»κ²Œ λ³΄μ‘΄ν•˜λŠ”μ§€ μ•Œμ•„λ΄…λ‹ˆλ‹€. μ•„ν•€ λ³€ν™˜κ³Ό 기타 μ£Όμ œμ— κ΄€ν•œ μ½”λ“œ 예제, λΉ„λ””μ˜€, λ¬Έμ„œκ°€ μžλ£Œμ— ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

kr.mathworks.com

 

μ—­λ°©ν–₯ 맀핑 (Backward Mapping)

μ–΄νŒŒμΈ λ³€ν™˜ 쀑 ν•˜λ‚˜μΈ νšŒμ „λ³€ν™˜μ„ μ‘μš©ν•œ μ˜ˆμ‹œ μ½”λ“œλ₯Ό μ²¨λΆ€ν•©λ‹ˆλ‹€. μš°λ¦¬κ°€ μƒκ°ν•˜λŠ” 일반적인 νšŒμ „λ³€ν™˜μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. 이미지λ₯Ό 30도 νšŒμ „μ‹œν‚€κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 'μ›λž˜ 이미지 μ’Œν‘œ(x, y)λ₯Ό 30도 νšŒμ „μ‹œμΌœμ„œ(x', y'), κ·Έ μœ„μΉ˜μ— f(x', y')←f(x, y)λ₯Ό λŒ€μž…ν•΄μ•Όκ² λ‹€'. 이것을 ν¬μ›Œλ“œ 맀핑(Forward Mapping)이라고 ν•©λ‹ˆλ‹€..

 

ν•˜μ§€λ§Œ 이것을 거꾸둜 'λ‚΄κ°€ λ§Œλ“€ μ΄λ―Έμ§€λŠ” μ›λž˜ μ΄λ―Έμ§€μ˜ 30도 νšŒμ „ ν›„ μƒνƒœμΌ κ±°μ•Ό. κ·ΈλŸ¬λ‹ˆκΉŒ λ§Œλ“€ μ΄λ―Έμ§€μ˜ μ–΄λ–€ μ’Œν‘œ(x', y')μ—μ„œ 값을 μ›λž˜ μ΄λ―Έμ§€λ‘œλΆ€ν„° κ°€μ Έμ˜¬ λ•Œ -30도 λ³€ν™˜ν•œ κ³³(x, y)μ—μ„œ κ°€μ Έμ˜€λ©΄ λ˜μ§€ μ•Šμ„κΉŒ?' μƒκ°ν•œ 방식이 λ°±μ›Œλ“œ 맀핑(Backward Mapping)μž…λ‹ˆλ‹€. 

 

두 방법을 비ꡐ해보면 λ°±μ›Œλ“œ 맀핑 μ‹œ, ν¬μ›Œλ“œ λ§€ν•‘ν•œ 그림에 μžˆλŠ” ꡬ멍(hole)듀이 사라짐을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
μ•„λž˜λŠ” 과제둜 μž‘μ„±ν–ˆλ˜ μ½”λ“œμž…λ‹ˆλ‹€.


import cv2
import numpy as np

def backward_transform(img, angle):
    height, width = img.shape
    result = np.zeros((height, width), np.uint8)

    affine = np.array([[np.cos(np.radians(angle)), np.sin(np.radians(angle)), 0],
                      [-np.sin(np.radians(angle)), np.cos(np.radians(angle)), 0],
                      [0, 0, 1]])

    for x in range(width):
        for y in range(height):
            p = affine.dot(np.array([x, y, 1]))
            xp = int(p[0])
            yp = int(p[1])

            if 0 <= yp < height and 0 <= xp < width:
                result[y, x] = img[yp, xp]
    return result

in_image = cv2.imread('파일λͺ….jpg', 0)
out_image = backward_transform(in_image, 20)

cv2.imshow('input', in_image)
cv2.imshow('output', out_image)

cv2.imwrite('bw_transformed.jpg', out_image)
cv2.waitKey()