-
[python] Procrustes shape analysis코딩/Python 2020. 10. 20. 15:40
최근 서로 다른 실루엣의 유사도를 비교하는 방법을 찾던 중 논문에서 Procrustes Shape Analysis라는 서로 다른 두 도형의 유사도를 비교하는 방법을 공부해보았다. 한글로된 설명이 많이 없어 나중에 보기 편하게 포스팅을 남겨본다.
해당 포스팅에서 이미 Procrustes Shape Analysis에 대해서 잘 설명되어 있으나, 최근 많이 사용되고 있는 python 코드로 변환과 동시에 한글로된 설명을 남겨본다. 위 포스팅에서는 두 도형(원반, 조약돌)을 비교하는 예시를 들고 있는데, 이 포스팅에서는 두개의 사각형 모형 유사도를 비교해본다.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots()
plt.xlim(-6, 6), plt.ylim(-6, 6)
plt.plot([6, -6], [0, 0], 'k')
plt.plot([0, 0], [-6, 6], 'k')
rect1 = [[-3,-3],[-1,-3],[-1,-1],[-3,-1]]
rect2 = [[2,0],[4,2],[2,4],[0,2]]
for i in range(len(rect1)):
if i != len(rect1)-1:
plt.plot([rect1[i][0], rect1[i+1][0]], [rect1[i][1], rect1[i+1][1]], 'r')
else:
plt.plot([rect1[0][0], rect1[i][0]], [rect1[0][1], rect1[i][1]], 'r')
for i in range(len(rect2)):
if i != len(rect2)-1:
plt.plot([rect2[i][0], rect2[i+1][0]], [rect2[i][1], rect2[i+1][1]], 'b')
else:
plt.plot([rect2[0][0], rect2[i][0]], [rect2[0][1], rect2[i][1]], 'b')
plt.show()위 파이썬 코드를 실행 시키면 아래와 같은 두 도형을 확인할 수 있다.
두 정사각형 도형은 (위치, 회전, 크기)라는 특성을 가지고 있는데, 이제부터 Procrustes Shape Analysis 방법을 활용하여 두 도형의 특성(위치, 회전, 크기)을 제외하고 모형이라는 유사도를 확인해본다. Procrustes Shape Analysis방법은 총 4단계로 구성된다.
def translate_mean_to_center(np_set):
np_set -= np.mean(np_set, 0)
return np_set
# Translate mean to 0.
rect1 = translate_mean_to_center(rect1)
rect2 = translate_mean_to_center(rect2)
print(rect1)
print(rect2)1. 먼저 Translation을 이용하여 두 도형의 중심점을 맞춘다.
1. Translate the shapes so they have mean zero.
# scale so RMSD is 1
rect1 = rect1 / np.linalg.norm(rect1)
rect2 = rect2 / np.linalg.norm(rect2)
print(rect1)
print(rect2)2. Normalization을 통해 두 도형의 크기(Scale)를 맞춘다.
2. Scale so the shapes have Root Mean Squared Distance (RMSD) to the origin of one.
from scipy.linalg import orthogonal_procrustes
R, s = orthogonal_procrustes(rect1, rect2)
rect2 = np.dot(rect2, R.T) * s
print(rect1)
print(rect2)3. 회전하여 두 모형을 정렬 시킴
3. Rotate to align major axis.
(rect2가 회전하여 rect1을 가릴껄 생각 못했었음;)
disparity = np.sum(np.square(rect1 - rect2))
print(disparity)4. 마지막으로 두 변환된 사각형의 disparity를 구한다. disparity가 0에 가까울 수록 두 도형의 모형이 유사도가 높다는 것을 의미한다. 위 예제의 경우 두 도형이 정사각형이 였기 때문에 코드를 실행해보면 disparity가 0이 나오는것을확인 할 수 있다.
지금까지 두 도형의 특성인(위치, 회전, 크기)와 상관없이 모형의 형태를 비교해보는 Procrustes Shape Analysis방법을 활용해 보았다.
'코딩 > Python' 카테고리의 다른 글
python 코딩 관련 공부할 리스트 (0) 2022.11.10