먼저 이 논문은 손의 동작(Pose)를 인식하는 방법에 관한 논문이다.
전체적인 구성은
먼저 키넥트로부터 영상을 입력받고,
손 영역을 찾고
손 영역에서 본 논문이 제안하는 SBSM (Spherical Blurred Shape Model) 디스크립터를 추출한다.
추출된 디스크립터로 사전에 SVM으로 학습한 모델을 이용하여 인식하는 것이다.
손은 기본적으로 카메라에서 가장 가까이 있다고 가정하고 찾는 듯 하다.
그래서 일단 이부분은 중요한 부분이 아니니 패스~
중요한 포인트는 찾아진 손 영역에서 어떻게 디스크립터를 추출하느냐 이다.
그림 4.1을 보면 피와 세타 r을 볼 수 있다. 간단하게 말해서 3차원 히스토그램이라고 보면 되지 않을까 싶다.
O는 무게중심일 것이며, 무게중심을 기준으로 phi 와 theta, r 을 가지고 해당 3d 픽셀의 좌표를 정하고
해당 좌표를 빈 형태로 구분하여 카운팅한다.
이렇게 함으로써 3차원 배열 형태의 디스크립터를 생성할 수 있다.
그림 4.3은 위에서 설명한 방법대로 디스크립터를 생성한 결과를 시각화 한 것이다.
손 모양에 따라서 녹색이 구성됨을 볼 수 있다.
위의 알고리즘은 디스크립터를 생성하는 알고리즘이다.
1번은 무게중심으로 이동하는 것을 나타내며,
2번은 구 형태의 영역을 어떻게 분할할 것인지의 범위?를 정하는 것
3번은 2번에서 구한 범위에 대한 설명
4번은 디스크립터 벡터 초기화
5~13 모든 포인트에 대해서 계산
먼저 3차원 픽셀이므로 중심으로부터 거리 계산하고
세타와 피를 구한다
그걸 2에서 정한 범위를 가지고 어디 빈에 카운팅 할지 정하고 카운팅 한다.
9~12번은 어느정도 오차를 줄이기 위해서 주위 이웃에도 조금씩 추가해주는 부분이다. 간단하게 생각해서
블러링?
마지막 14~16은 정규화 루틴이다.
여기서 문제는 디스크립터를 회전 불변하게 만들고 싶은것이다.
물론 키넥트를 사용할 경우에는 100% 회전 불변을 만족할 수는 없다. 키넥트로부터 입력되는 데이터가 3차원
데이터이긴 하지만, 카메라에 보이는 부분만 3차원 데이터를 가지고 있기 때문이다. 어찌됫던 이론적으로는
회전 불변을 만족한다.
여기서 T1와 T2는 디스크립터 중에서도 가장 큰 벡터와 두번째로 큰 벡터이다. 이 벡터는 디스크립터에서 빈의
위치가 세타와 피는 같고, r만 다른 모든 빈들의 합을 계산해서 가장 큰 것과 두번째로 큰 것을 찾는 것이다.
회전 불변을 위해서는 디스크립터를 항상 같은 기준으로 읽어야 회전 불변한 특성을 갖는다.
이러한 이유로 본 논문은 위의 두개의 벡터가 이루는 평면을 xy평면과 일치 시키고, T1, 즉 가장 큰 벡터를
x축과 일치시켜 기준을 맞춘다.
이렇게 하기 위한 방법은 다음과 같다.
1. T1 벡터를 ax 축에 일치시키는 쿼터니온을 구한다.(회전 행렬 R1을 구함)
2. T2벡터를 1에서 구한 쿼터니온으로 회전 시킨뒤에 yz 평면에 투영한다.
3. 투영된 벡터를 y축과 일치하는 쿼터니온 q2를 구한다( 회전 행렬 R2를 구함)
4. 위에서 구한 회전 행렬 R1, R2를 이용하여 디스크립터를 회전한다.
이 회전 행렬 부분에서 상당히 많은 고민을 했다. 위의 알고리즘은 사실 논문과는 다르다. T2를 이용해서 q2를
구할때 논문에서는 R1으로 회전하지 않고 구하는데, 그러면 정확하게 같은 디스크립터도 같은 기준으로 되지
않는다. 그래서 본인은 T1으로 구한 R1으로 먼저 T2를 회전 후, R2를 구하였다.
매트랩으로 간단한 예제를 만들어 실험 하였다.
T1 = [4,3,3]; T2 = [-3,-2,4]; OT1x = [10,3.4,3]; % 쿼터니온 벡터 ax = OT1x(1)/norm(OT1x); ay = OT1x(2)/norm(OT1x); az = OT1x(3)/norm(OT1x); % 쿼터니온 각도 구하기(내적을 이용) %쿼터니온 회전 메트릭스 구하기 angle=90.3; c = cos(angle/180*3.141592); s = sin(angle/180*3.141592); R =[c + ax^2*(1-c), ax*ay*(1-c)-az*s, ax*az*(1-c)+ay*s; ay*ax*(1-c)+az*s, c+ay^2*(1-c), ay*az*(1-c)-ax*s; az*ax*(1-c)-ay*s, az*ay*(1-c)+ax*s, c + az^2*(1-c) ] T1 = T1 * inv(R); T2 = T2 * inv(R); T1 T2 x = [1,0,0]; y = [0,1,0]; z = [0,0,1]; %T1과 x축의 수직 벡터 OT1x = cross(x,T1) % 쿼터니온 벡터 ax = OT1x(1)/norm(OT1x); ay = OT1x(2)/norm(OT1x); az = OT1x(3)/norm(OT1x); % 쿼터니온 각도 구하기(내적을 이용) quater_theta = acos( x*T1'/ (norm(x) * norm(T1) )); %쿼터니온 회전 메트릭스 구하기 angle=-quater_theta/3.141592 *180; c = cos(angle/180*3.141592); s = sin(angle/180*3.141592); R =[c + ax^2*(1-c), ax*ay*(1-c)-az*s, ax*az*(1-c)+ay*s; ay*ax*(1-c)+az*s, c+ay^2*(1-c), ay*az*(1-c)-ax*s; az*ax*(1-c)-ay*s, az*ay*(1-c)+ax*s, c + az^2*(1-c) ] (R)*T1' %======================================================================== T2yz =[ 0, 0, 0; 0,1,0; 0,0,1] *(R)* T2'; %T1과 x축의 수직 벡터 OT2x = cross(y,T2yz); % 쿼터니온 벡터 ax = OT2x(1)/norm(OT2x); ay = OT2x(2)/norm(OT2x); az = OT2x(3)/norm(OT2x); % 쿼터니온 각도 구하기(내적을 이용) quater_theta = acos( y*T2yz/ (norm(y) * norm(T2yz) )); angle=-quater_theta/3.141592 *180; c = cos(angle/180*3.141592); s = sin(angle/180*3.141592); R2 =[c + ax^2*(1-c), ax*ay*(1-c)-az*s, ax*az*(1-c)+ay*s; ay*ax*(1-c)+az*s, c+ay^2*(1-c), ay*az*(1-c)-ax*s; az*ax*(1-c)-ay*s, az*ay*(1-c)+ax*s, c + az^2*(1-c) ]; (R2)*(R)*T2' (R2)*(R)*T1' inv(R) R'
여튼 이론적으로 보면 회전 불변 특성을 갖는 듯하다. 이러한 아이디어는 3차원 객체를 다룰때 매우 유용할
것으로 보인다. 이제 구현을 해봐야겠다.
============================ 실험 결과 ============================
회전 불변 미적용 Nr = 10 , Nt = 9 로 놓고 실험한 결과
디스크립터는 3차원이지만 쉽게 보기 위해서 2차원으로 시각화하여 표현하였다. 헌데, 각 손 동작에 대한 뚜렷한 특징이 눈에 보이지 않아, 다른 방법으로 전환... 물론 SVM을 해보진 않았다. 하지만, 특징 자체가 그렇게 좋진 않다는게 주관적인 판단이다. 2차원으로 보면 템플릿과 유사하다고 볼 수 있지 않을까?
하지만 회전 불변의 방법에 대한 아이디어는 참으로 좋은 듯 함.
'Algorithm > Paper' 카테고리의 다른 글
Robust Object Detection Via Soft Cascade (0) | 2013.05.19 |
---|---|
보행자 검출 (0) | 2013.04.24 |
A Lagrangian Particle Dynamics Approach for Crowd Flow Segmentation and Stability Analysis (0) | 2013.02.16 |
Fast Crowd Segmentation Using Shape Indexing (0) | 2013.02.16 |
People-Tracking-by-Detection and People-Detection-by-Tracking (0) | 2013.02.16 |