인공지능 공부

dtw-python 응용하기

DualQuaternion 2023. 8. 2. 15:40

내가 해야 하는 것은 두가지 캐릭터 모션데이터를 align 하는 것이다. 이 과정에 고전적으로 DTW를 사용해서 나도 DTW를 이용하기로 했다.

 

DTW에는 세가지 입력이 필요하다. 명칭은 달라질 수 있으나 dtw-python quick start에서 사용했던 용어를 그대로 쓰면, 

 

 1. query: 첫번째 타임시리즈  =X = x1, x2 ...., xm

 2. template: 두번째 타임시리즈 = Y = y1, y2, ... yn

 3. non-negative 거리 계산 함수 = f (xi,yi)

 

여기서 거리 계산함수는 query와 template의 매 item들 간에 적용된다.  

 

1. 퀵스타트 소스코드 분석

 

quickstart 소스코드를 한줄 한줄 분석해보자.

 

#index를 만든다. 

idx = np.linspace(0,6.28,num=100)  

 

#index를 이용해서 noise가 포함된 sin 곡선을 만든다.

query = np.sin(idx) + np.random.uniform(size=100)/10.0 

 

#index를 이용해서 cos 곡선을 만든다. 

template = np.cos(idx) 

 

# DTW를 수행한다. 

alignment = dtw(query, template, keep_internals=True)

 

## 정렬 결과를 draw 한다. 
alignment.plot(type="threeway")

 

## Rabiner-Juang type VI-c unsmoothed recursion 으로 DTW를 수행하고 스탭 패턴을 프린트 한다. 
dtw(query, template, keep_internals=True, 
    step_pattern=rabinerJuangStepPattern(6, "c"))\
    .plot(type="twoway",offset=-2)

 

## 결과를 그려준다. 
print(rabinerJuangStepPattern(6,"c"))
rabinerJuangStepPattern(6,"c").plot()

 

스탭패턴은 다음과 같이 출력된다.

2. 코드 변환 및 적용

 

일단 내가 해야하는 작업은 query와 template를 1차원이 아닌 다차원으로 늘이는 작업이다.

 

캐릭터 애니메이션은 보통 24개의 조인트를 쓰고 각자 3dof를 가지고 있다 치면 총 72 dof를 가지게 된다.

 

이제 고민이 되는 부분은 alignment를 하기 위한 distance function을 어떻게 잡냐인데...

 

일단은 각 조인트 별 position distance를 다 합한걸 distance function이라고 하면 약간 편하게 작업이 가능할 것 같다.

 

이걸 어떻게 파이썬 안에서 구현할지에 대해서 고민해보자. 

 

일단 논문 12페이지를 보면, 

https://www.jstatsoft.org/article/view/v031i07

 

Computing and Visualizing Dynamic Time Warping Alignments in R: The dtw Package | Journal of Statistical Software

Abstract Dynamic time warping is a popular technique for comparing time series, providing both a distance measure that is insensitive to local compression and stretches and the warping which optimally deforms one of the two input series onto the other. A v

www.jstatsoft.org

 관련된 내용이 나온다.

 

일단 차원수는 c라고 지칭하게 된다.

 

dtw는 기본적으로 유클리디언 로컬 디스턴스를 가정한다. 그러면 별 문제가 없을 것 같다.

 

이후에는 그냥 query와 template를 다차원으로 확장해서 쓰면 되는 모양. 해보자.

 

import numpy as np

## A noisy sine wave as query

query =  np.random.randn(200, 3)
template =  np.random.randn(200, 3)

## Find the best match with the canonical recursion formula
from dtw import *
alignment = dtw(query, template, keep_internals=True)

## Display the warping curve, i.e. the alignment curve
alignment.plot(type="threeway")

 

3차원의 랜덤 query와 template를 만든 후 dtw를 적용한 결과를 plot 해보면 아래와 같다.

이제 이걸 캐릭터 조인트에 적용해볼 차례다.

 

이번 포스팅은 여기까지.