#08-1. 어파인 변환

기하학적 변환

  • Geometric Transfrom
  • f1, f2 정의 → 영상 크기 변경, 회전

어파인 변환

  • Affine Transformation

  • 영상 평행 이동, 회전, 크기 변환, 전단 변환

  • 직선은 그대로 직선, 직선 간의 길이 비율, 평행 관계 유지

    ex. 직사각형 → 평행사변형

  • 6개의 파라미터

  • 어파인 변환 행렬 구하는 함수

    • getAffineTransform(src[], dst[])
    • src : 입력 영상에서 임의의 세 점의 좌표 → 좌측 상단, 우측 상단, 우측 하단
  • 영상을 어파인 변환

    • warpAffine(src, dst, M, dsize, flags =INTER_LINEAR, borderMode=BORDER_CONSTRANT, const Scalar& borderValue=Scalar());

    • M : 2*3 어파인 변환 행렬

    • dsize : 결과 영상 크기

    • flags : 보간법 알고리즘

      rows = src.shape[0]
      cols = src.shape[1]
      src_pts = np.array([[0, 0],
                         [cols - 1, 0],
                         [cols - 1, rows - 1]]).astype(np.float32)
      dst_pts = np.array([[50, 50],
                         [cols - 100, 100],
                         [cols - 50, rows - 50]]).astype(np.float32)
      affine_mat = cv2.getAffineTransform(src_pts, dst_pts)
      dst = cv2.warpAffine(src, affine_mat, (0, 0))

이동 변환

  • Translation Transformation, shift

  • (150,100) 만큼 이동

    affine_mat = np.array([[1, 0, 150],
                          [0, 1, 100]]).astype(np.float32)
    dst = cv2.warpAffine(src, affine_mat, (0, 0))

전단 변환

  • Shear Transformation
  • 한쪽 방향으로 밀어서 평행사변형 모양으로 변형 → 원점은 이동 X
  • 가로 방향으로 밀기
  • 세로 방향으로 밀기
rows = src.shape[0]
cols = src.shape[1]
mx = 0.3
affine_mat = np.array([[1, mx, 0],
                      [0, 1, 0]]).astype(np.float32)
dst = cv2.warpAffine(src, affine_mat, (int(cols + rows * mx), rows))

크기 변환

  • Sx, Sy > 1 : 영상 확대, < 1 : 영상 축소

  • resize(src, dst, dsize, fx = 0, fy = 0, interpolation = INTER_LINEAR)

    • dsize : 결과 영상 크기
    • fx : x축 방향 크기 변환 비율
    • fy : y축 방향 크기 변환 비율
    • interpolation : 보간법 지정
  • 보간법

    • INTER_NEAREST : 최근방 이웃 보간법
    • INTER_LINEAR : 양선형 보간법
    • INTER_CUBIC : 3차 보간법
    • INTER_AREA : 픽셀 영역 리샘플링
    • INTER_LANCZOS4 : 8x8 이웃 픽셀을 사용하는 란초스 보간법

Moire effect

  • 모아레 패턴

회전 변환

  • Rotation Transformation

  • 특정 좌표 기준 → 영상 원하는 각도만큼 회전

  • 삼각함수 이용

  • getRotationMatrix2D(center, angle, scale)

    • center : 회전 중심 좌표

    • angle : 회전 각도, 양수(반시계), 음수(시계)

    • scale : 회전 후 추가적으로 확대,축소할 비율 (1 = 크기 변환 X)

      → 2*3 어파인 변환 행렬 리턴

cp = (src.shape[1] / 2, src.shape[0] / 2)   # 영상 중심 기준
affine_mat = cv2.getRotationMatrix2D(cp, 20, 1)   # 반시계 20도
dst = cv2.warpAffine(src, affine_mat, (0, 0))

대칭변환

  1. 좌우대칭
  2. 상하대칭

flipcode > 0 (좌우), = 0 (상하), < 0 (둘 다)

for flip_code in [1, 0, -1]:
    dst = cv2.flip(src, flip_code)

#08-2. 투시 변환

def on_mouse(event, x, y, flags, param):
    global cnt, src_pts
    if event == cv2.EVENT_LBUTTONDOWN:
        if cnt < 4:
            src_pts[cnt, :] = np.array([x, y]).astype(np.float32)
            cnt += 1
            
            cv2.circle(src, (x, y), 5, (0,0,255), -1)
            cv2.imshow('src', src)
        if cnt == 4:
            w = 200
            h = 300
            dst_pts = np.array([[0, 0],
                               [w-1, 0],
                               [w-1, h-1],
                               [0, h-1]]).astype(np.float32)
            pers_mat = cv2.getPerspectiveTransform(src_pts, dst_pts)
            dst = cv2.warpPerspective(src, pers_mat, (w, h))
            cv2.imshow('dst', dst)

cnt = 0
src_pts = np.zeros([4,2], dtype=np.float32)
src = cv2.imread('card.bmp')
if src is None:
    print('Image load failed!')
    exit()
cv2.namedWindow('src')
cv2.setMouseCallback('src', on_mouse)
cv2.imshow('src', src)
cv2.waitKey(0)
cv2.destroyAllWindows()
profile
숭실대학교 컴퓨터학부 21

0개의 댓글