본문 바로가기

개발자/Computer Vision

[Computer Vision] OpenCV 기하학적(geometric) 변환 정리(활용 예제 및 그림 설명 포함)

반응형

Transformations

변환이란 수학적으로 표현하면 아래와 같습니다.

  • 좌표 x를 좌표 x’로 변환하는 함수

예로는 사이즈 변경(Scaling), 위치변경(Translation), 회전(Rotaion) 등이 있습니다. 변환의 종류에는 몇가지 분류가 있습니다.

  • 강체변환(Ridid-Body) : 크기 및 각도가 보존(ex; Translation, Rotation)
  • 유사변환(Similarity) : 크기는 변하고 각도는 보존(ex; Scaling)
  • 선형변환(Linear) : Vector 공간에서의 이동. 이동변환은 제외.
  • Affine : 선형변환과 이동변환까지 포함. 선의 수평성은 유지.(ex;사각형->평행사변형)
  • Perspective : Affine변환에 수평성도 유지되지 않음. 원근변환

 

1.  영상의 이동 변환과 전단 변환(Translation transformation,  Shear transformation)

 

- 영상의 이동 변환(Translation transformation)

영상을 가로 또는 세로 방향으로 일정 크기만큼 이동 시키는 연산을 의미하며, 시프트(shift) 연산이라고도 한다.

cv2.warpAffine(src, M, dsize)

Parameters:

  • src – Image
  • M – 변환 행렬
  • dsize (tuple) – output image size(ex; (width=columns, height=rows)

여기서 변환행렬은 2X3의 이차원 행렬입니다. [[1,0,x축이동],[0,1,y축이동]] 형태의 float32 type의 numpy array입니다.

- 영상의 전단 변환(Shear Transformation)

  • 전단 변환(shear transformation)은 직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변형되는 변환이며 층밀림 변환이라고도 한다.
    • 전단 변환은 가로 방향 또는 세로 방향으로 각각 정의할 수 있다.

import sys
import numpy as np
import cv2


src = cv2.imread('tekapo.bmp')

if src is None:
    print('Image load failed!')
    sys.exit()

aff = np.array([[1,0,200],
                [0,1,100], dtype = np.float32]


dst = cv2.warpAffine(src,aff,(0,0)) #dsize에 (0,0)이면 src와 같은 크기로 설정하겠다는말임 

cv2.imshow('src', src)
cv2.imshow('dst', dst) 
cv2.waitKey()
cv2.destroyAllWindows()

 

2.  영상의 확대와 축소(Scaling)

Scaling은 이미지의 사이즈가 변하는 것 입니다. OpenCV에서는 cv2.resize() 함수를 사용하여 적용할 수 있습니다. 사이즈가 변하면 pixel사이의 값을 결정을 해야 하는데, 이때 사용하는 것을 보간법(Interpolation method)입니다. 많이 사용되는 보간법은 사이즈를 줄일 때는 cv2.INTER_AREA , 사이즈를 크게할 때는 cv2.INTER_CUBIC , cv2.INTER_LINEAR 을 사용합니다.

 

cv2.resize(img, dsize, fx, fy, interpolation)

Parameters:

  • img – Image
  • dsize – Manual Size. 가로, 세로 형태의 tuple(ex; (100,200))
  • fx – 가로 사이즈의 배수. 2배로 크게하려면 2. 반으로 줄이려면 0.5
  • fy – 세로 사이즈의 배수
  • interpolation – 보간법
import cv2
import numpy as np

img = cv2.imread('messi5.jpg')
res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)

#OR

height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

3.  영상의 회전(Rotation)

물체를 평면상의 한 점을 중심으로 𝜃 만큼 회전하는 변환 입니다. 양의 각도는 시계반대방향으로 회전을 합니다. 역시 변환 행렬이 필요한데, 변환 행렬을 생성하는 함수가 cv2.getRotationMatrix2D() 함수입니다.

cv2.getRotationMatrix2D(center, angle, scale) → M

Parameters:

  • center – 이미지의 중심 좌표
  • angle – 회전 각도
  • scale – scale factor

위 결과에서 나온 변환행렬을 cv2.warpAffine() 함수에 적용합니다.

 

import sys
import numpy as np
import cv2


src = cv2.imread('tekapo.bmp')

if src is None:
    print('Image load failed!')
    sys.exit()

cp = (src.shape[1] / 2, src.shape[0] / 2)
rot = cv2.getRotationMatrix2D(cp,20,0.5)


dst = cv2.warpAffine(src, rot, (0, 0))

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()

cv2.destroyAllWindows()

4.  Affine Matrix 와 Perspective Matrix 

Affine Transformation

  • 영상의 기하학적 변환 중에서 어파인 변환(affine transformation)은 영상을 평행 이동시키거나 회전, 크기 변환 등을 통해 만들 수 있는 변환을 통칭한다.
    • 또는 영상을 한쪽 방향으로 밀어서 만든 것 같은 전단 변환도 어파인 변환에 포함된다.
    • 영상에 어파인 변환을 적용할 경우 직선은 그대로 직선으로 나타나고, 직선 간의 길이 비율과 평행 관계가 그대로 유지된다.

 Affine 변환을 위해서는 3개의 Match가 되는 점이 있으면 변환행렬을 구할 수 있습니다.

 

Perspective Transformation

Perspective(원근법) 변환은 직선의 성질만 유지가 되고, 선의 평행성은 유지가 되지 않는 변환입니다. 기차길은 서로 평행하지만 원근변환을 거치면 평행성은 유지 되지 못하고 하나의 점에서 만나는 것 처럼 보입니다.(반대의 변환도 가능)

4개의 Point의 Input값과이동할 output Point 가 필요합니다.

변환 행렬을 구하기 위해서는 cv2.getPerspectiveTransform() 함수가 필요하며, cv2.warpPerspective() 함수에 변환행렬값을 적용하여 최종 결과 이미지를 얻을 수 있습니다.

ra

import sys
import numpy as np
import cv2


src = cv2.imread('namecard.jpg')

if src is None:
    print('Image load failed!')
    sys.exit()

w, h = 720, 400
srcQuad = np.array([[325, 307], [760, 369], [718, 611], [231, 515]], np.float32)
dstQuad = np.array([[0, 0], [w-1, 0], [w-1, h-1], [0, h-1]], np.float32)

pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
dst = cv2.warpPerspective(src, pers, (w, h))

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

 

반응형