2.4. Recovery of affine and metric properties from images#
The Method to recover similarity properties from projective distored images#
평면에 projection되어 있는 이미지에서 사영 왜곡을 제거하면 각도, 길이 비율과 같은 similarity 속성을 원래 평면에서 측정할 수 있으며, 4개의 대응점을 지정하여 dof가 8인 projective transformation H를 계산해 사영 왜곡을 완전히 제거할 수 있습니다.
그러나 similarity transformation은 projective tranformation에 비해 dof가 4개 더 적습니다. 따라서 4 dof만 지정하여도 similarity 속성을 측정할 수 있습니다.
사영 왜곡된 이미지에서 similarity 속성을 복원하기 위한 4개의 dof는 line at infinity
이미지에서
2.4.1 The line at infinity#
사영 변환에 의해 왜곡된 이미지에서 무한선(the line at infinity)
2.4.2 Recovery of affine properties from images#
사영 변환에 의해 왜곡된 이미지에서 line at infinity
즉 이미지의 아핀 속성을 복원한 것입니다. 다음 그림에서 이 핵심 아이디어에 대해 잘 설명하고 있습니다. 그렇다면 사영 변환에 의해 왜곡된 이미지에서의 line at infinity
이 책에서는 2가지 방법을 소개합니다.
평행선의 교점을 이용한 방법
길이 비율을 이용한 방법
위 두 가지 중 저희는 1번 방법에 대한 실습을 함께 제공합니다.
Affine rectification#
아래 이미지는 3가지의 평면과 그 사이에서의 일어날 수 있는 2가지 변환으로 아핀 속성이 보정되는 과정을 보입니다. 3가지 평면은 왼쪽부터 순차적으로 아래와 같은 평면을 나타냅니다.
실제 세계에서 왜곡 없이 평면으로 사영된 평면
,projective transformation에 대해 변환되어 사영된 평면
, 에서 아핀 속성을 복원한
또한,
위 그림에서 알 수 있는 것은 2가지입니다.
projective transform에 의해 왜곡된 이미지에서 line at infinity
을 식별하여 affine 속성을 복원해 평행인 것을 평행으로 만들 수 있다는 것위와 같이 복원된 평면은 원본과 affine transforation의 관계를 가진다는 것
The Method using the intersection of parallel lines#
실세상 평면의 line at infinity는 원근 이미지에서 평면의 vanishing line이 됩니다. 다음 그림에서 나와있듯이, vanishing line
vanishing line을 식별하는 방법을 요약해보겠습니다.
실제 세계에서는 평행한 두 직선을 2 pair 찾습니다.
외적을 이용해서 각 쌍에 존재하는 두 직선의 접점을 계산합니다.
위 과정을 통해 구한 2개의 접접의 외적을 이용해 선의 좌표 계산합니다.
아래 실습 코드가 있습니다.
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('./figures/chessboard.jpg', cv2.IMREAD_COLOR)
st = [np.array([1381, 969]), np.array([1719, 392]), np.array([337, 711]), np.array([1382, 968])]
ed = [np.array([338, 711]), np.array([786, 195]), np.array([786, 194]), np.array([1719, 392])]
# Homogeneous vectorize
st = np.append(st, np.ones((4,1), dtype=np.int32), axis=1)
ed = np.append(ed, np.ones((4,1), dtype=np.int32), axis=1)
# Compute vanishing point Vx
Vx = np.cross(np.cross(st[0], ed[0]),np.cross(st[1], ed[1]))
Vx = Vx/Vx[2]
# Compute vanishing point Vy
Vy = np.cross(np.cross(st[2], ed[2]),np.cross(st[3], ed[3]))
Vy = Vy/Vy[2]
# Compute vanishing line Vl
Vl = np.cross(Vx,Vy)
Vl = Vl/Vl[2]
print('Vanishing line : ', Vl)
# compute affine rectification matrix
H_A = np.eye(3)
H_A[2] = Vl
# recover the affine properties
recovered_img = cv2.warpPerspective(img, H_A, (0,0))
concat = np.concatenate([img, recovered_img], axis=1)
plt.imshow(concat)
Vanishing line : [6.61317266e-07 2.85906628e-04 1.00000000e+00]
<matplotlib.image.AxesImage at 0x168e874d0>

Computing a vanishing point from a length ratio#
또는 길이 비율이 알려진 두 개의 간격이 주어지면 소실점을 결정할 수 있습니다. 일반적인 경우는 이미지의 한 직선에서 세 점이 식별된 경우입니다.
이미지에서 거리 비율
을 측정합니다.점
를 직선 상의 좌표계에서 좌표 로 표기합니다. 계산을 위해 이러한 점들을 2차원 동차 벡터 로 표시합니다. 같은 방법으로 는 좌표 을 가지고 동차 벡터로 표시할 수 있습니다.위의 두 좌표계를 이용해
으로 가는 1차원 사영변환 를 계산합니다. 에 의한 무한점의 이미지가 의 소실점이 됩니다.
2.4.3 The circular points and their dual#
사영 왜곡된 이미지에서 원형점(the circular points)
아래 그림은 circular points가 similarity transformation에 invariant 하다는 것을 보여줍니다.
The conic dual to the circular points#
사영 왜곡된 이미지에서 circular points에 대한 dual conic
※ circular points에 대한 duality conic
따라서 Conic
2.4.4 Angles on the projective plane#
사영 평면에서
위 수식은 사영 변환에서 불변량이며,
2.4.5 Recovery of metric properties from images#
원형점을 표준 위치
Metric Rectification using #
다음과 같이
Metric rectification from affine distorted images#
이미지가 아핀 보정이 됐다고 가정하면, 거리 보정을 위해 원형점의 자유도 2를 결정하는 제약 조건 2개가 필요합니다. 실세상 평면에서 직각인 두 개의 이미지에서 제약 조건을 얻을 수 있습니다.
아핀 정정 이미지의 직선
이것은 2 X 2 행렬
따라서 두 선의 직교 조건은
아래 해당 코드를 첨부합니다.
img = cv2.imread('./figures/chessboard.jpg', cv2.IMREAD_COLOR)
# select two orthogonal pairs
st = [np.array([1157, 676]), np.array([989, 638]), np.array([1055, 544]), np.array([1221, 582])]
ed = [np.array([989, 638]), np.array([1055, 544]), np.array([1221, 582]), np.array([1157, 676])]
st = np.append(st, np.ones((4,1), dtype=np.int32), axis=1)
ed = np.append(ed, np.ones((4,1), dtype=np.int32), axis=1)
l1 = np.cross(st[0], ed[0])
l2 = np.cross(st[1], ed[1])
m1 = np.cross(st[2], ed[2])
m2 = np.cross(st[3], ed[3])
# constraints
ortho_constraint = np.array([[l1[0]*m1[0], l1[0]*m1[1]+l1[1]*m1[0], l1[1]*m1[1]],
[l2[0]*m2[0], l2[0]*m2[1]+l2[1]*m2[0], l2[1]*m2[1]]
])
# decompose orthogonal constraint using SVD to gain S
U,S,V = np.linalg.svd(ortho_constraint, full_matrices=True)
S_matrix = np.diag(S)
# S = KK^T
# decompose S using Cholesky decomposition to gain K
K = np.linalg.cholesky(S_matrix)
K = K/K[1][1]
# Compute metric rectification matrix
H_m = np.eye(3)
H_m[:2,:2] = K
H_m = np.linalg.inv(H_m)
# recover the metric properties
dst = cv2.warpPerspective(img, H_m*H_A, (0,0))
cv2.line(img, st[0][:2], ed[0][:2], (255,0,0),3)
cv2.line(img, st[1][:2], ed[1][:2], (255,0,0),3)
cv2.line(img, st[2][:2], ed[2][:2], (0,0,255),3)
cv2.line(img, st[3][:2], ed[3][:2], (0,0,255),3)
concat = np.concatenate([img, dst], axis=1)
plt.imshow(concat)
<matplotlib.image.AxesImage at 0x169db0650>

Angle measurement code#
위 보정된 이미지에서 좌표를 찍어 측정해본 결과입니다.
st = [np.array([992, 621]), np.array([872, 583])]
ed = [np.array([872, 583]), np.array([916, 492])]
st = np.append(st, np.ones((2,1), dtype=np.int32), axis=1)
ed = np.append(ed, np.ones((2,1), dtype=np.int32), axis=1)
conic = np.array([[1,0,0],
[0,1,0],
[0,0,0]])
l = np.cross(st[0], ed[0])
l = l/l[2]
m = np.cross(st[1], ed[1])
m = m/m[2]
# calulate the angle using conic
cos_theta = l.T@conic@m
val = np.sqrt((l.T@conic@l)*(m.T@conic@m))
cos_theta = cos_theta / val
theta = np.arccos(cos_theta) * 180 / np.pi
print('angle between l and m : ', theta)
cv2.line(dst, st[0][:2], ed[0][:2], (255,0,0),3)
cv2.line(dst, st[1][:2], ed[1][:2], (0,255,0),3)
plt.imshow(dst)
angle between l and m : 81.7667263783753
<matplotlib.image.AxesImage at 0x168e465d0>

Metric rectification from original images#
아핀 왜곡된 이미지에서 거리 속성 복원한 위 사례와 유사하게, 원본 이미지에서 바로 거리 속성을 복원할 수 있습니다. 직선
여기에서
Stratification#
Reference#
Multiple view geometry in computer vision chapter 2.7