[영상 Geometry #3] 2D 변환 (Transformations)

영상처리 2013.07.08 15:26

(3D 비전 geometry 3번째 파트 2D 변환입니다)


3. 2D 변환 (2D Transformations)


변환에 대해서는 2D 변환과 3D 변환을 구분해서 설명하겠습니다. 2D 변환은 detection 또는 tracking 문제에 있어서 아래 그림과 같이 두 이미지 사이의 매칭(matching) 관계를 이미지 평면에서 직접 모델링할때 사용되는 방법입니다.


<그림 1>


이러한 2D 변환 관계를 모델링 할때, 어떤 변환 모델을 사용할지는 문제에 따라 다를 것입니다. 회전변화만을 허용할지, 스케일 변화까지 고려할지, 아니면 affine 또는 원근(perspective) 변화까지 고려할지를 잘 선택해야 합니다. 물론 perspective 변환을 사용하는 경우가 가장 일반적이긴 하지만 그만큼 자유도가 높기 때문에 잘못된 결과를 낼 가능성도 높습니다.


먼저 용어(기호)를 정의하고 넘어가면, 이미지 I에서의 점들은 X = (xi, yi), 이미지 I'에서 X에 대응되는 점들을 X' = (xi', yi'), X와 X' 사이의 변환 관계 중 회전변화(rotation)는 R, 평행이동(translation)은 T라 표기하겠습니다. 변환에 대한 기본적인 내용은 http://blog.daum.net/shksjy/228를 참조하기 바랍니다. 변환(Transformation)에 대한 전반적인 내용이 직관적으로 잘 정리되어 있습니다.


그러면 2D 변환들을 rigid 변환부터 homography까지 단계적으로 하나씩 살펴보겠습니다.


3.1 Rigid Transformation

3.2 Similarity Transformation

3.3 Affine Transformation

3.4 Homography (Projective Transformation)

3.5 OpenCV에서의 2D 변환 함수들

3.6 2D 변환 모델의 선택

3.7 참고 자료(references)



3.1 Rigid Transformation (강체 변환)


가장 기본적인 변환은 rigid(강체) 변환입니다. Rigid 변환은 다른 말로 유클리디언 변환(Euclidean transformation)이라고도 하는데, 형태와 크기를 유지한체 위치와 방향(rotation)만 바뀔 수 있는 변환입니다. 즉, 회전(rotation)과 평행이동(translation)만을 허용하는 변환입니다.


일반적인 rigid 변환을 다루기 전에 rigid 변환 중에서도 더욱 제약조건이 심한 경우부터 살펴보겠습니다.


3.1.1 평행이동(translation)만을 허용한 경우


영상 이동체 추적 문제에 있어서 추적 대상의 크기가 고정이고 회전도 일어나지 않는 경우에는 위치 변화만을 추적하면 됩니다.


--- (1)


이 경우, tx는 xi' - xi 들의 평균, ty는 yi' - yi 들의 평균으로 손쉽게 변환 관계를 구할 수 있습니다.


 --- (2)



3.1.2 회전(rotation)만을 허용한 경우


(x, y)를 반시계 방향으로 θ 라디안(radian)만큼 회전시키는 변환행렬은 다음과 같습니다.


 --- (3)


회전변환에서 주의할 점은 회전의 기준은 원점이라는 사실입니다. 즉, 물체가 제자리에서 도는 것이 아니라 (0, 0)을 기준으로 크게 도는 것입니다.


회전변환의 자유도(degree of freedom)[각주:1]는 1입니다. 따라서 하나의 매칭 쌍만 있으면 회전변환을 유일하게 결정할 수 있습니다. 그렇다면 점 (x1, y1)을 점 (x1', y1')로 회전시키는 변환행렬은 어떻게 구할 수 있을까요?


식 (3)을 직접 이용하는 것은 좋은 방법이 아닙니다. 회전변환은 원점을 기준으로 하기 때문에 만일 두 점의 원점과의 거리가 서로 다르다면 이러한 회전변환 행렬을 존재하지 않게 됩니다.


이 문제를 해결하는 방법은 일단 스케일(scale) 변화까지 고려하여 변환을 구한 후, 나중에 스케일 변화를 제거하는 것입니다. 스케일 변화까지를 고려한 회전변환은 일반적으로 다음과 같이 표현할 수 있습니다 (a = s*cosθ, b = s*sinθ인 셈).


 --- (4)


이 식을 전개한 후에, 다시 a, b에 관해 묶으면 다음과 같은 형태로 바꿀 수 있습니다.


 --- (5)


이제 식 (5)에 매칭 쌍을 하나만 대입해도 역행렬을 이용하여 a, b를 구할 수 있습니다. 만일, 매칭쌍이 여러 개인 경우에는 다음과 같이 식을 세우고 최소자승법(Least Square method) 즉, pseudo inverse를 이용하면 a, b를 손쉽게 구할 수 있습니다.


 --- (6)


이렇게 a, b를 구하고 나면 스케일(scale) s와 회전각 θ는 다음과 같이 계산됩니다.


 --- (7)


이제 s는 버리고 θ만 이용하면 두 점 집합 사이의 매핑 관계를 회전변환만으로 설명할 수 있게 됩니다. 물론 영상에서 물체의 크기 변화까지 허용한다면 s도 같이 이용하면 됩니다.


그런데, 실제 문제에 있어서는 이미지 원점(이미지 왼쪽 상단 모서리)을 중심으로 한 회전변환은 현실적이지 못합니다. 보통의 경우는 현재 물체의 위치에서 제자리 회전이 일어나는 경우가 대부분이겠지요.. 이런 경우는 위 회전변환만으로는 표현이 불가능하며 일반적인(general한) rigid 변환 모델을 필요로 합니다.


3.1.3 Rigid 변환


일반적인 rigid 변환을 행렬식으로 나타내면 다음과 같습니다.


 --- (8)


Full rigid 변환을 이용하면 이제 임의의 회전 및 위치이동이 가능해집니다. 예를 들어, 어떤 물체가 제자리에서 θ만큼 회전하는 경우는 먼저 영상 원점을 중심으로 θ만큼 회전한 후에 원래 있던 자리로 평행이동해 오면 됩니다.


Rigid 변환은 식에서 알 수 있듯이 자유도가 3이며, 변환을 추정하기 위해서는 최소 2개 이상의 매칭쌍을 필요로 합니다. 주어진 매칭쌍들로부터 rigid 변환을 추정할 때에는 앞서 회전변환에서와 같이 일단은 스케일 변화까지 같이 고려하는 것이 좋습니다. 식 (8)을 스케일 변환까지 포함하도록 확장하여 다시 쓰면 아래와 같습니다 (a = s*cosθ, b = s*sinθ, s는 스케일).


 --- (9)


이를 전개한 후, a, b, c, d에 대한 행렬식으로 다시 묶으면 다음과 같습니다.


 --- (10)


 --- (11)


주어진 매칭쌍들을 (x1,y1)-(x1',y1'), (x2,y2)-(x2',y2'), ... 라 할 때, 이 점들을 식 (11)에 대입하여 다음과 같은 형태로 행렬식을 세웁니다.


 --- (12)


이제 식 (12)에서 역행렬(매칭쌍이 2개인 경우) 또는 pseudo inverse(매칭쌍이 2개 이상이고 전체 매칭쌍을 가장 잘 근사하는 rigid 변환을 찾을 경우)를 이용하면 a, b, c, d를 결정할 수 있습니다. 또한 앞서와 마찬가지로 식 (7)을 이용하면 스케일 s와 회전각 θ를 구할 수 있게 됩니다.


마지막으로 이렇게 구한 θ와 c, d를 식 (8)에 대입하면 우리가 원하던 rigid 변환을 얻게 됩니다. ◇


여기서 한가지 짚고 넘어갈 점이 있습니다. 식 (8)에서 제가 평행이동(translation) 부분을 [tx, ty]라 쓰지 않고 [c, d]라 한 이유가 있습니다. 그건 [c, d]가 물체의 평행이동량 뿐만 아니라 (영상원점을 중심으로 한) 회전변환으로 인한 이동량까지 같이 포함된 값이기 때문입니다.


그렇다면 위에서 구한 rigid 변환으로부터 실제 물체가 얼마나 평행이동했는지를 알아낼 수 있을까요? (물체가 얼마나 이동했는지 알아내는 것은 영상 이동체 추적 분야에서는 매우 중요한 문제입니다)


사실 이 부분에서 저도 굉장히 햇갈렸는데.. 저의 결론은 rigid 변환식 자체에서는 알아낼 수 없다 입니다. 예를 들어, 아래 탁구라켓 그림을 살펴보도록 하죠. 만일 아래 그림과 같이 영상 내에서 탁구 라켓이 이동했다면 이 라켓의 평행이동량은 얼마일까요?


<그림 2>


조금만 생각해 보면 이건 어떤 절대적인 문제가 아니라 기준의 문제임을 파악할 수 있을 것입니다. (만일 라켓의 손잡이만 놓고 본다면 평행이동량은 꽤 큽니다. 하지만 라켓의 라바 부분만 놓고 보면 이번엔 평행이동량이 매우 작습니다).


사실 무엇을 기준으로 삼을지는 우리의 주관의 영역이며 그 기준에 따라 평행이동량은 다르게 계산될 수 있습니다. 하지만 문제는 rigid 변환은 우리가 무엇을 기준으로 삼는지에 관계없이 수식적으로 유일하게(동일하게) 결정된다는 점입니다. rigid 변환을 결정하기 위해서는 매칭쌍 2개만 있으며 되기 때문에, p1-p1'과 p2-p2'을 이용해 구한 rigid 변환과 p2-p2', p3-p3'을 이용한 rigid 변환이 동일해야 합니다. 또한 p1-p1', p2-p2'에서 구한 rigid 변환으로 p3를 변환시키면 p3'이 나와야 합니다.


결론적으로 rigid 변환식 자체에서는 평행이동량을 구할 수 없습니다. 그렇다면 평행이동량(또는 물체의 변화된 새로운 위치)을 어떤 식으로 구해야 할까요?


그건 우리가 정한 기준점이 rigid 변환에 의해 어디로 이동하는지를 살펴보면 될 것입니다 (기준점은 당연 물체의 무게중심으로 잡는게 좋겠죠..)



3.2 Similarity Transformation (닮음 변환)


Similarity 변환 즉, 닮음 변환은 rigid 변환에 추가적으로 스케일 변화까지 허용한 변환입니다 (중학교때 배우는 닮은 도형을 생각하면 됩니다). 즉, similarity 변환은 회전(rotation), 평행이동(translation), 크기변화(scaling)로 구성되는 변환이며 앞서 나왔듯이 그 일반식은 다음과 같습니다 (단, a2+b2≠0).


 --- (13)


Similarity 변환의 자유도는 4이며[각주:2] similarity 변환을 유일하게 결정하기 위해서는 2개의 매칭쌍이 필요합니다.


Similarity 변환은 사실 rigid 변환에서 이미 모두 다루었기 때문에 여기서 다시 설명할 필요는 없을 것 같습니다. 다만 여기서는 위 회전, 평행이동, 스케일변화를 하나의 단일(single) 행렬로 표현할 수 있는 homogeneous 표현법에 대해서만 언급하고 넘어가겠습니다.


[컴퓨터 비전에서의 Geometry #2]에서 다루었던 homogeneous 좌표 표현을 사용하면 similarity 변환은 다음과 같이 하나의 행렬 변환으로 표현될 수 있습니다.


 --- (14)


즉, 회전, 스케일링, 평행이동이 행렬 변환 하나로 표현된 것입니다.


X' = AX인 행렬 A는 X에서 X'로의 선형 변환(linear transformation)입니다. 이렇게 homogeneous 형태의 선형변환으로 표현했을 때 가장 큰 장점은 여러 변환들을 행렬 곱으로 자유롭게 결합(composition)할 수 있다는 점입니다. 예를 들어 변환 A1, 변환 A2, 변환 A3를 순서대로 적용하는 것은 X' = A3A2A1X가 되며, 또한 A = A3A2A1인 행렬을 구해서 X' = AX와 같이 하나의 변환으로 표현할 수도 있습니다.



3.3 Affine Transformation


Affine 변환은 직선, 길이(거리)의 비, 평행성(parallelism)을 보존하는 변환이며 그 일반식은 다음과 같습니다.


 --- (15)


또는 다음과 같은 homogeneous 형태로도 표현할 수 있습니다.


 --- (16)


좀더 쉽게 말하면 Affine 변환은 회전, 평행이동, 스케일 뿐만 아니라 shearing, 반전(reflection)까지를 포함한 변환입니다.


Affine 변환의 자유도는 6이고, 따라서 3쌍의 매칭쌍이 있으면 affine 변환을 유일하게 결정할 수 있습니다. 임의의 세 점 (x1,y1), (x2,y2), (x3,y3)를 (x1',y1'), (x2',y2'), (x3',y3')로 매핑시키는 affine 변환은 다음과 같이 계산할 수 있습니다 (식 15를 전개하여 a,b,c,d,e,f에 대해 묶은 후 세 점을 대입).


 --- (17)


물론 매칭쌍이 3개 이상인 경우에는 pseudo inverse를 이용하여 affine 변환을 구할 수 있습니다.


2D 평면에서의 affine 변환을 직관적으로 이해하는 한 방법은 임의의 삼각형을 임의의 삼각형으로 매핑시킬 수 있는 변환이 affine이다 (단, 평행성을 보존하면서) 라고 이해하는 것입니다.


<그림 3>


평행성을 보존한다는 의미는 예를 들어 위 그림과 같이 점 p1, p2, p3를 p1', p2', p3'으로 매핑시키는 affine 변환을 구했을 때, 이 affine 변환을 가지고 p4를 매핑시키면 p4'이 나와야 한다는 의미입니다. 


정말 그렇게 되는지는 식 (15)를 가지고 설명해 보겠습니다. 식 (15)를 X'=AX+B로 놓고 p1, p2, p3를 가지고 affine 변환 즉, A와 B를 결정했다고 해 보죠. 그러면 p1' = Ap1 + B, p2' = Ap2 + B, p3' = Ap3 + B는 당연히 만족해야 하는 것입니다. 벡터 p1p4 = p1p2 + p1p3이므로 p4 = p2 + p3 - p1입니다. 따라서 p4의 affine 변환인 Ap4 + B는 A(p2+p3-p1) + B = Ap2 + Ap3 - Ap1 + B = (p2'-B) + (p3'-B) - (p1'-B) + B = p2' + p3' - p1'가 됩니다. 즉, p4가 p2' + p3' - p1'으로 매핑된다는 것인데, p2'+p3'-p1'은 바로 p1'p2', p1'p3'을 두 변으로 하는 평행사변형의 꼭지점입니다.


사실 여기까지는 수학적인 관점에서의 내용이고 정작 중요한 것은 과연 affine 변환이 우리가 풀고자 하는 문제에 있어서 영상에서의 물체의 변화를 모델링하기에 가장 적합한 모델이냐 여부일 것입니다. 특히나 affine 변환부터는 reflection 즉, 뒤집힘이 허용되기 때문에 이러한 자유도가 문제에 득이 될지 실이 될지를 잘 따져보고 모델을 선택해야 할 것입니다.



3.4 Homograpy (Projective Transformation)


Planer surface 물체의 경우에는 3D 공간에서의 2D 이미지로의 임의의 원근투영변환(perspective projective transformation)을 두 이미지 사이의 homography로 모델링할 수 있습니다. 즉, 어떤 planar surface가 서로 다른 카메라 위치에 대해 이미지 A와 이미지 B로 투영되었다면 이미지 A와 이미지 B의 관계를 homography로 표현할 수 있다는 것입니다.


그래서 homography를 planar homography라고도 부르며, homography는 평면물체의 2D 이미지 변환관계를 설명할 수 있는 가장 일반적인 모델입니다. 또한 Homography는 projective transformation과 같은 말입니다.


Homography는 homogeneous 좌표계에서 정의되며 그 일반식은 다음과 같습니다.


 --- (18)


Homography는 자유도가 8이며 따라서 homography를 결정하기 위해서는 최소 4개의 매칭쌍을 필요로 합니다. Homography의 자유도가 9가 아니라 8인 이유는 (x,y,1), (wx',wy',w)이 homogeneous 좌표이므로 homography의 scale을 결정할 수 없기 때문입니다 (∵ homography 변환 X'=HX에서 X, X'은 homogeneous 좌표이기 때문에 X'=kHX도 성립하게 됩니다. 즉, H가 homography 행렬이라면 임의의 0이 아닌 k에 대해 kH도 또한 동일한 homography 행렬이 됩니다).


주어진 매칭쌍들로부터 homography를 실제 구하는 과정에 대해서는 Elan Dubrofsky, "Homography Estimation", 2009 글을 참조하기 바랍니다. Homography를 구할 수 있는 다양한 방법들이 잘 정리되어 있습니다.


Homography를 직관적으로 이해하기 위한 한 좋은 방법은 2D 평면에서 임의의 사각형을 임의의 사각형으로 매핑시킬 수 있는 변환이 homography다 라고 생각하는 것입니다. 물론 사각형이 뒤집혀질 수도 있습니다.


<그림 4>



3.5 OpenCV에서의 2D 변환 함수들


OpenCV에서는 다음과 같이 homography만 3×3 행렬로 표현하고, affine 등 그 외 변환은 2×3 행렬로 표현합니다 (두 행렬 모두 원소 타입은 double 입니다, CV_64FC1).


 --- (19)


--- (20)


OpenCV에서 2D 변환과 관련된 함수들을 정리해 보았습니다.

  • estimateRigidTransform(): 다수의 매칭쌍으로부터  similarity 변환이나 affine 변환을 구할 때 사용 (파라미터로 선택 가능). 내부적으로 RANSAC을 이용. opencv2/video/video.hpp
  • getAffineTransform(): 3쌍의 입력 매칭쌍으로부터 affine 변환을 구해줌. opencv2/imgproc/imgproc.hpp
  • invertAffineTransform(): affine 변환의 역변환을 구해줌, opencv2/imgproc/imgproc.hpp
  • getPerspectiveTransform(): 4쌍의 입력 매칭쌍으로부터 homography 행렬을 계산해 줌. opencv2/imgproc/imgproc.hpp
  • findHomography(): 다수의 매칭쌍으로부터 homography 행렬을 계산해 줌 (근사 방법은 전체 데이터 fitting, RANSAC, LMedS 중 선택), opencv2/calib3d/calib3d.hpp
  • transform(): 2×2 또는 2×3 변환행렬(similarity, affine 등)을 이용하여 좌표변환을 할 때 사용
  • perspectiveTransform(): 3x3 homography 변환행렬 또는 4×4 변환행렬을 이용하여 좌표변환을 할 때 사용


이 외에 OpenCV API 목록에는 없지만 opencv/modules/video/src/lkpyramid.cpp에 보면 icvGetRTMatrix 라는 함수가 하나 숨어있습니다. 이 함수를 이용하면 RANSAC이 아닌 전체 매칭쌍을 근사한 similarity 변환 또는 affine 변환을 구할 수 있습니다.



3.6 2D 변환 모델의 선택


그러면 실제 자신의 영상인식 문제에 사용할 2D 변환 모델을 선택할 때 고려할 사항 또는 참고사항을 몇 가지 적어보겠습니다.


먼저, homography는 위 <그림 1>의 고양이 그림판과 같은 planar한 물체에 대한 변환 모델입니다 (homography 뿐만 아니라 affine, similarity 등도 모두 평면형 물체에 대한 변환 모델입니다). 따라서 주사위 등과 같은 3차원 (입체) 물체의 매핑 관계는 homography만으로는 표현이 안됩니다 (이 경우는 3D 변환 모델이 필요할 것입니다).  물론 주사위의 각각의 면은 homography로 매핑시킬 수 있습니다. 그렇다고 3D 물체에 2D 변환을 사용하지 못하는 것은 아닙니다. 카메라에 아주 근접한 경우가 아니라면 대부분의 물체는 평면으로 가정해도 큰 무리가 없기 때문입니다. 예를 들어, 사람 얼굴을 찾거나 추적하는 경우에 고개를 옆으로 돌리지 않는 한 얼굴 모습은 크게 바뀌지 않습니다.


Homography는 가장 일반적인 2D 변환 모델이며 planar한 물체의 모든 가능한 3D 변화를 표현할 수 있는 모델입니다. 하지만 일반적인 만큼 데이터에 overfitting 될 수 있는 위험성도 가지고 있습니다. 따라서 이 위험도를 줄이기 위해서는 문제의 특성에 따라 가능한 낮은 자유도의 변환을 사용하는 것이 좋습니다. 하지만 위 <그림 1>처럼 3D 공간에서 자유롭게 움직이는 물체를 검출하기 위해서는 어쩔 수 없이 homography를 사용해야 합니다.


Detection과 Tracking의 차이. Detection 문제에 있어서는 문제 특성에 따라 적절한 변환을 선택하면 되지만, tracking의 경우에 있어서는 3D 모션이 있더라도 굳이 homography를 사용할 필요가 없으며 대부분 similarity나 affine으로 충분합니다. 그 이유는 인접한 영상 프레임 사이에는 변화가 그리 크지 않기 때문입니다.


마지막으로, homography나 affine을 사용하면 가끔 말도 안되게 매핑이 되는 경우를 종종 발견할 수 있을 것입니다. 그 경우는 바로 매핑이 뒤집혀진(reflected) 경우인데, 그건 affine과 homography가 reflection을 포함하기 때문입니다. 그런데 영상인식 관점에서는 이 reflection이 불필요한 경우가 대부분입니다. 예를 들어, <그림 1>에서 고양이 그림판이 뒤집혀서 뒷면이 보이는 경우까지를 고려하는게 합당할까요? DB에 저장된 고양이 그림과 그림판의 뒷면(뒷면에는 과연 뭐가 있을까요?)을 매칭시키는 것은 패턴매칭 관점에서 말도 안되며 가능하지도 않습니다. 따라서 homography나 affine을 사용할 경우에는 추정된(estimated) 변환에 reflection이 포함되었는지를 조사하여 reflection이 들어간 경우에는 추정이 잘못된 것으로 판단하는게 좋습니다.



3.7 참고 자료(references)


http://blog.daum.net/shksjy/228

Elan Dubrofsky, "Homography Estimation", 2009

위키피디아 Homography



by 다크 프로그래머


  1. 그냥 쉽게 미지수의 개수라고 생각해도 무방합니다. [본문으로]
  2. 회전, 스케일, x축이동, y축이동 [본문으로]
  • 이전 댓글 더보기
  • 비전 시작자 2014.01.13 16:16 신고 ADDR 수정/삭제 답글

    글 잘 읽어보았어요.
    이쪽으로 막 공부를 시작하고 있습니다. 지금 하고자 하는것이 평면 운동(2자유도)으로 움직이는 카메라를 통해 기존에 알고있는 마커(크기도 알고있음, 점은 4점의 위치를 알고있음)와 현재 위치(카메라의 x, y 좌표)도 알고 있다고 할때 마커의 4점을 보는순간 마커의 위치를 알수 있을까요?

    • BlogIcon 다크pgmr 2014.01.13 16:49 신고 수정/삭제

      네 가능합니다. opencv의 solvePnP 함수를 이용하면 물체의 4점으로부터 카메라-물체의 3차원 관계를 알 수 있습니다. solvePnP 사용법에 대해서는 http://darkpgmr.tistory.com/99 글을 참고하시기 바랍니다.

  • Program 2014.08.25 17:53 신고 ADDR 수정/삭제 답글

    안녕하세요^^ homography쪽을 공부하다 의문이 생겨 질문드립니다.
    혹시 처음 네모서리를 2d좌표와 3d좌표로 준다면 camera matrix를 구할 수 있을까요?
    또한 findhomography함수(위와 같이 2d, 3d좌표를 주었을 때)를 이용하여 camera matrix를 용이하게 찾아낼 수 있는 방법이 잇나요?.(내부적으로 determine되는지 궁금합니다..)
    마지막으로 일반적으로 detection되는 keypoint만으로 camera matrix를 구할 수 있는 방법이 있는지.. 여쭤보고 싶습니다..
    감사합니다..

    • BlogIcon 다크pgmr 2014.08.26 10:36 신고 수정/삭제

      안녕하세요. 저는 잘은 모르지만 혹시 auto calibration 쪽에 그러한 방법이 있을지도 모르겠습니다.

  • anytime2736 2015.01.09 16:30 신고 ADDR 수정/삭제 답글

    안녕하세요 궁금한점 문의드립니다!

    "실제 문제에 있어서는 이미지 원점(이미지 왼쪽 상단 모서리)을 중심으로 한 회전변환은 현실적이지 못합니다. " 라고 말씀하셨는데, 제가 영사처리 수업시간에는 분명 회전을 할때는 이미지의 중심을 원점으로 잡았는데, 제가 잘못 배운건가요???

    • BlogIcon 다크pgmr 2015.01.11 19:51 신고 수정/삭제

      이미지 자체를 회전시키고자 하는 것이 아니라.. 이미지 내에서 물체의 회전 변화를 표현하고자 하는 것이 목적입니다. 이미지 자체를 회전시키는 것은 이미지의 중심, 이미지의 한 꼭지점, 이미지의 내부의 임의의 한점 등 어떤 점을 잡아도 회전이 가능합니다.

  • okipoki 2015.01.15 17:18 신고 ADDR 수정/삭제 답글

    안녕하세요 궁금한 점이 있습니다.
    perspectivetransform()함수는 3x3homography변환행렬을 구할 때 사용한다고 말씀하셨는데요. 3x3homography를 어떤형식으로 변환시키는 것이죠?
    그리고 왜 findfundamentalmat()으로나온 행렬로는 계산되어지지않는지 궁금합니다.
    사실fundamental matrix와essential matrix그리고 homography matix의 정확 한차이점을 잘모르겠네요..ㅠㅠ 항상 다크프로그래머님의 포스팅을 보면서 감탄을 하고갑니다 감사합니다.

    • BlogIcon 다크pgmr 2015.01.15 17:45 신고 수정/삭제

      관계식에 차이가 있는데요.. H, E, F 사이에는 p가 p'으로 변환되었다고 했을 때, p = Hp', p'Fp = 0, p'Ep = 0의 차이가 있습니다. 또한 p'Fp = 0에서는 p가 이미지 픽셀좌표이고 p'Ep = 0에서는 p가 정규화된 이미지 좌표라는 차이점이 있습니다.

  • 파노라마으아 2015.07.20 10:40 신고 ADDR 수정/삭제 답글

    안녕하세요 다크님!
    매번 다크님의 블로그를 통해서 공부하다 질문을 올립니다.
    파노라마영상을 제작하는 중에 궁금증이 생겨서 질문드립니다.
    특징점과 디스크립터를 추출하고, 매칭 후 호모그래피를 생성한 후 perspectiveTransform을
    이용해서 영상을 붙이고 있습니다.

    그런데 perspectiveTransform 을 사용하는 중에, 제 경험 상으로는
    두 가지 영상이 있을때, 왼쪽영상에 오른쪽 영상이 붙는 현상이 발생합니다.
    이건 opencv 내의 함수적인 문제 일까요? 아니면 제가 함수를 사용할 때,
    입력을 잘못해준 결과일까요....?

    또한, 다른 질문이 있는데, plane 한 변환이 아닌, spherical 이나 cylindrincal 한 변환은
    3D 변환에 속하는 것일까요.....?

    매번 강좌를 보면서 감사한 마음이 들었는데, 이자리를 빌어 감사드립니다 ㅠ

    • BlogIcon 다크pgmr 2015.07.20 22:10 신고 수정/삭제

      안녕하세요. 왼쪽 영상에 오른쪽 영상이 붙는다는게 어떤 의미인가요? 잘 붙으면 좋은 것 아닌지요 -_-
      평면 좌표계를 실린더 좌표계나 구면 좌표계로 바꾸는 것은 3차적원인 해석이 필요한 작업인 건 맞습니다.

  • 파노라마으아 2015.07.22 12:12 신고 ADDR 수정/삭제 답글

    음...제가 설명이 미숙한 것 같습니다.

    예를 들면, 두개의 카메라를 이용해서 영상을 붙일 때,
    기준이 되는 영상은 왼쪽에 있는 영상이 되는 현상을 보입니다.

    이게 warpPerspectiveTransform 함수의 특성인 것 같기도 합니다..
    여기서, 혹시 warpPerspectiveTransform 함수를 사용할 때, 오른쪽 영상이
    기준이 될수 없을까? 함에 여쭤봅니다.

    그런데, 생각하면생각할수록, warpPerspectiveTransform 여기서 원인을 찾기보다는...
    매칭할때, 호모그래피를 생성할때, 원인이 있는것 같기도합니다 ㅠㅠ..

    • BlogIcon 다크pgmr 2015.07.22 12:30 신고 수정/삭제

      네.. 아직도 잘 이해가 안갑니다.
      warpPerspective(src, dst, M, dsize) 함수는 src에 M을 적용하여 dst를 만드는 함수입니다. 오른쪽 영상을 기준으로 하고 싶으면 src에 왼쪽 영상을 입력하고, M에는 왼쪽 영상을 오른쪽 영상으로 변환시키는 변환행렬을 넣으면 되는 것 아닌지요..? 질문하신 의도를 잘 모르겠습니다.

  • 파노라마으아 2015.07.23 13:49 신고 ADDR 수정/삭제 답글

    저도 그렇게 생각하고
    query와 train 을 잘 생각해서 변경을 해봤는데,
    호모그래피에서의 문제인지...
    dst안에서 src 가 잘리는 문제점이 발생하더라구요...

    보통 오른쪽영상을 왼쪽영상으로 붙였을때에는, dst 안에 왼쪽영상이 좌표(0,0) 을
    왼쪽 상단 꼭지점을 기준으로 붙기 때문에, 오른쪽 영상이 생기면서 dst 에 그려지는 방식인데,

    왼쪽영상을 오른쪽영상으로 붙였을때에도, dst 안에 오른쪽영상이 좌표 (0,0) 부터
    그려진다고 판단하에, src 가 dst 에 그려지는데, 그러면 dst안에서 왼쪽영상은
    거진 반이 날아가게 됩니다.... 이 문제가.. homography 문제일것같은데...

    호모그래피를 찾는 것을
    findHomography 로 RANSAC 을 이용해 얻어내고 있습니다...

    사진 첨부하여 질문을 해야할 것같은데... 메일을 따로 알수 있을까요..?

    • 파노라마으아 2015.07.23 14:25 신고 수정/삭제

      자답입니다만.... M 에 다른 매트릭스를 곱해줘야할 것 같습니다...

  • 전압전류저항 2015.11.09 15:54 신고 ADDR 수정/삭제 답글

    여쭙고싶은게 있습니다.
    Homography에서 Perspective를 제거할려고 하고있습니다.
    일단 내부,외부 파라미터는 없다고 가정하면
    Chessboard로 카메라로 찍어 4개의 코너점 좌표를 얻고
    가상의 점(체스보드의 간격을 1로하는 단위벡터)로 좌표를 만든후
    cvGetPerspectiveTransform을 통해 Homography를 구하였습니다.
    그런데 1920*1080 인데 거의 한 1/4정도로 줄어드네요...
    보통 이런식으로 Homography를 구하였을때, scale이 이렇게 많이 작아지나요?
    또한 scale곱을 할려면 어디서 해야할까요...?

    • BlogIcon 다크pgmr 2015.11.09 18:09 신고 수정/삭제

      안녕하세요. homographt에서 perspective를 제거하는다는 의미는 어떤 것인지 잘 모르겠습니다. 스케일은 가상의 점의 간격을 변화시키면 되리라 생각합니다.

  • 전압전류저항 2015.11.09 19:24 신고 ADDR 수정/삭제 답글

    일단 카메라로 찍은 체스보드에서 4개의 코너점을 구합니다. conerPoint라고하죠
    위 사진은 원근법때문에 사다리꼴 모양입니다.

    그 뒤, 체스보드에 대한 정보(몇 by 몇 체스보드인지)를 가지고
    가상의 4개의 점을 만듭니다. (normalPoint라고 하겠습니다)
    예를들어 7x10이라면 6x9의 점이 생깁니다.
    그럼 (0,0) (5,0) (0,8) (5,8) 이라는 4개의 점으로 이루어진 직사각형이 생기겟죠

    그뒤, cvGetPerspectiveTransform(normalPoint,conerPoint,homography)
    를 통해 3x3 homography를 얻습니다.

    그뒤 cvWarpPerspective에 CV_WARP_INVERSEMAP 인자를 추가하여,
    homography의 역행렬로 계산된 이미지를 얻고
    이는 아까 카메라로 획득한 사다리꼴 모양의 체스보드가 직사각형으로 변환됩니다.

    여기서 어떤 인자를 잘못썻는지 scale이 줄어듭니다.
    제가 잘못쓴건지 아니면, 위 방법에서 이러한 문제가 야기되는지가 궁금합니다

    • BlogIcon 다크pgmr 2015.11.10 10:51 신고 수정/삭제

      네, 이해되었습니다. normalPoint를 예를 들어 (0,0), (50,0), (0, 80), (50,80)과 같이 크게 잡고 homography를 구하면 scale 줄어드는 정도가 감소할 것입니다. homography는 임의의 사각형을 임의의 사각형으로 매핑시킬 수 있는 변환이며 입력된 크기대로 변환을 구해줍니다.

  • 전압전류저항 2015.11.10 11:33 신고 ADDR 수정/삭제 답글

    다크님 말씀대로 normalPoint를 2.5배정도 하니 꽉차게 나오는것 같습니다.
    그런데 한가지 이해가 안가는데, 임의의 사각형에서 임의의사각형으로 매핑하는 Homography를 구하는데 nomalPoint의 scale값이 중요한지가 궁금합니다. scale보다 ratio가 중요하지 않나요?

    만약 (0,0) (5,0) (0,8) (5,8) 이렇게 임의의 사각형을 주어지면
    맵핑할 사다리꼴 모양의 4점의 좌표가 (0,0) (5,0) (0,8) (5,8) 이 되야하는것 아닌가요?

    • BlogIcon 다크pgmr 2015.11.10 11:45 신고 수정/삭제

      사실 저는 왜 이해가 안가시는지 잘 모르겠는데요.. {(0,0), (1,0), (1,1), (0,1)}을 {(0,0), (4,0), (4,4), (0,4)}로 매핑시키는 호모그래피를 구하면 스케일을 4배로 확대하는 변환이 구해지고, {(0,0), (0.1,0), (0.1,0.1), (0,0.1)}로 가는 호모그래피를 구하면 1/10로 축소시키는 변환이 구해집니다. 이미지에서 구한 체스보드의 코너점으로 이루어진 사각형의 변의 길이가 d 픽셀이라 가정하면 변환하고자 하는 사각형에서의 변의 길이가 5 픽셀 (y축은 8 픽셀)이므로 5/d 만큼 스케일이 축소되도록 호모그래피가 구해질 것입니다.

    • 전압전류저항 2015.11.10 15:44 신고 수정/삭제

      감사합니다..
      어이없는 곳에서 해결했네요
      3x3 마지막 행렬 인자를 고정해놨었네요...ㅎ

  • JO 2016.02.20 13:39 신고 ADDR 수정/삭제 답글

    다크님 안녕하세요~
    카메라 칼리브레이션, 이미지 리타게팅을 공부하다가 갑자기 떠오른 생각인데요.
    직사각형으로 생긴 전체 이미지를 perspective transform(z축 y축 회전)을 하게되면 rectangularity를 잃은 사다리 꼴의 영상으로 매핑될텐데, 이것을 crop하지 않고 모든 픽셀 정보사용해서 rectangularity를 유지하는 방법이 제안된적이 있나요?
    관련 키워드들을 사용해서 찾아보고 있는데, 그렇게 관심 받는 분야가 아닌 것인지 정보를 찾기가 힘드네요..

    • JO 2016.02.20 13:41 신고 수정/삭제

      의도를 말씀드리면, 영상내의 객체들은 perspective transform 시키지만 영상에서 의미가 적은 부분들과 영상 경계 부분에 또 다른 처리를 시켜줘서 영상 전체 크기와 모양을 유지시키고 싶어서요.
      떠오르는 것은 배경과 객체를 분리해서 따로따로 처리하는 방법도 있겠고...

    • BlogIcon 다크pgmr 2016.02.22 10:49 신고 수정/삭제

      글쎄요. 잘 모르겠습니다. 그냥 crop시키지 않고 transform된 영상 전체를 그대로 사용하면 되지 않나요?

  • BlogIcon 길똥고 2016.04.22 17:49 신고 ADDR 수정/삭제 답글

    잘 보았습니다.
    혹시 저런 리지드 영상 말고
    초음파영상처럼 스페클 들이 지글지글한
    두개의 영상을 정합(Registration) 하려면
    어떤 유사도 피쳐가 적당할까요?

    감사드리며~

    • BlogIcon 다크pgmr 2016.04.22 18:51 신고 수정/삭제

      sift 를 한번 써보시기 바랍니다. 수중영상을 연구하는 사람에게서 수중영상에 모든 feature가 동작하지 않았지만 유일하게 sift가 동작했다는 말을 들은 적이 있습니다.

  • EunSeop 2016.10.06 16:21 신고 ADDR 수정/삭제 답글

    다크pgmr님 글 잘보고 있습니다 ㅠㅠ

    저 글을 읽다가 질문이 있는데,

    1) rotaion부분에
    "식 (3)을 직접 이용하는 것은 좋은 방법이 아닙니다. 회전변환은 원점을 기준으로 하기 때문에 만일 두 점의 원점과의 거리가 서로 다르다면 이러한 회전변환 행렬을 존재하지 않게 됩니다." 이런 문맥이 있는데, 이 문맥에서 "두 점의 원점과의 거리가" 이 부분이 로테이션 하기 전 점과 로테이션 한 후 점을 말하는건가요?

    그렇다고 할 때 rotation시 각각의 object들의 거리가 다르기 때문에 스케일 값을 준다고 했는데, 이 부분이 잘 이해가 되지 않네요...

    제가 생각하기론, 원점으로 translation시킨 뒤 로테이션 하고 다시 복원하면 되지 않을까 하면 이해가 되는데말이죠...

    한수 부탁드립니다 ㅠㅠ

    • BlogIcon 다크pgmr 2016.10.06 17:48 신고 수정/삭제

      네 좋은 방법이라 생각됩니다. 물체의 제자리 회전은 rigid 변환을 이용해서 일반적으로 구할 수도 있고 말씀하신 것처럼 일단 원점으로 평행이동시킨 후 회전변환을 구할 수도 있습니다. 그리고 말씀하신 방법이 좀더 효율적인 것 같습니다.

  • 비전돌이 2016.11.11 17:14 신고 ADDR 수정/삭제 답글

    감사합니다!
    항상 궁금한거 검색하다보면 이곳으로 찾아오게 되는군요 ^^
    각각 변환을 깔끔하게 정리해주셔서 이해가 잘되네요!!
    (혹시 책 출판하시면 꼭 사겠습니다)

  • 댕이냥 2017.03.23 22:41 신고 ADDR 수정/삭제 답글

    포스팅하신 내용덕에 많은 도움을 얻고있습니다. 감사합니다.

    지금 공부하고 있는게 있는데,
    P점에서 어떤 평면물체 사진을 찍고, P점에서 열발자국 뒤로간 지점에서 사진을 찍었을 때,
    두 사진을 통해서 제가 열발자국 이동한 거리가 몇 센티인지 위 변환들을 통해서 추론 할 수 있을까요? 호모그래피를 통해서 하려고 했는데, 하려고보니 스케일이 제거되서 구하지 못하더라구요.
    (calibration으로 카메라 파라메터는 구했다고 했을때요)

    • BlogIcon 다크pgmr 2017.03.24 11:48 신고 수정/삭제

      일반적으로 영상매칭에서 스케일은 결정하지 못하는 것으로 알고 있습니다 (http://darkpgmr.tistory.com/83 글의 그림 2 참조). 평면형 물체의 실제 크기를 알고 있거나 카메라의 지면에서의 높이를 알고 영상에서 매칭된 점들이 지면에 붙어있는 점들이라는 가정 등의 부가적인 정보가 있어야만 스케일 결정이 가능합니다. 그리고 영상의 기하학적인 해석은 위의 2D 변환으로는 해결이 힘들고 3D 영상기하학에 대한 이해와 공부가 필요합니다.

  • soc 2017.04.11 14:05 신고 ADDR 수정/삭제 답글

    이렇게 자료올려주신것도 감사한데 질문남겨요...
    homograpy 구하려면 planar scene에서만 가능한거 같은데 planar한게 일상생활에서 어떤걸 말하는지 잘모르겠네요 ㅜ.ㅜ 제가 생각하기에는 벽면은 planar한것 같은데 잘 와닿지가 않네요. 그리고 fundamental은 planar하지 않아도 구할수 있는게 맞나요??

    • BlogIcon 다크pgmr 2017.04.11 15:47 신고 수정/삭제

      네, 벽이나 도로 표면 등이 planar한 사물입니다. 또 멀리서 보면 지구 표면도 planar하기 때문에 근사적으로 homography를 적용하기도 합니다. 그리고 fundamental matrix는 planar하지 않은 사물에 대해서도 일반적으로 적용할 수 있습니다.

    • soc 2017.04.11 21:05 신고 수정/삭제

      한가지 더 물어볼께요 ㅜ.ㅜ
      homography를
      h=[h1 h2 h3; h4 h5 h6; h7 h8 1] 이렇게 해서 8자유도라고 생각하는건 틀린건가요??

    • BlogIcon 다크pgmr 2017.04.12 13:05 신고 수정/삭제

      네 그렇게 8자유도로 보시면 됩니다.

  • FMD 2017.05.17 22:51 신고 ADDR 수정/삭제 답글

    안녕하세요. 영상처리 공부중인 학생입니다.
    공부하다 막히는 부분이 있어 이렇게 힌트를 얻고자 질문 남깁니다.

    OpenCV에서 제공하는 SURF를 이용해서 object를 scene에 매칭하여 코너점을 연결하고 싶습니다.
    Tutorial Document에 Homography와 Perspective Transform을 이용해서 같은 결과를 얻는 부분이 있어 따라해보았는데 잘 되지 않아 디버깅하면서 보니, Perspective Transform을 수행한 뒤 scene의 4개의 코너점이 약 1~2픽셀 정도 붙어있는 결과를 반환하게 되는걸 보았습니다. 같은 코드에 예제 이미지를 구하여 실험했음에도 불구하고 이런 결과가 나와 Homography의 문제인지 의심하는 중에 혹시 아시는 부분인가 해서 질문 남깁니다. 아신다면 답변 해주시면 감사하겠습니다.

    • BlogIcon 다크pgmr 2017.05.18 11:08 신고 수정/삭제

      scene의 4개의 코너점이 붙어있다는 것이 무슨 뜻인가요?

    • FMD 2017.05.18 14:14 신고 수정/삭제

      제가 1~2픽셀 정도 붙어있다고 얘기했는데, scene 영상에서 매칭하려는 object 크기가 50x50정도라고 했을 때,
      object 내에서 2x2정도만 object라고 나타납니다.

    • BlogIcon 다크pgmr 2017.05.18 14:52 신고 수정/삭제

      object에 있는 특징점들을 homography로 변환해 보면 입력 scene 영상의 object 영역으로 매핑되는 것이 아니라 그 내부의 아주 작은 영역으로 매핑된다는 말씀이시죠? 일단은 homography를 구하기 위해서는 매칭점(object 특정점 - scene 특징점)들이 있어야 할텐데요, 특징점 매칭은 정상적으로 이루어진 것인가요? 매칭점들을 선으로 연결해 보면 확인이 가능할 터인데요..

    • FMD 2017.05.18 15:00 신고 수정/삭제

      답변 감사합니다.
      scene 영상을 확대한 후에 매칭해보니 제대로 매칭이 되었습니다. scene 영상의 크기가 작아서 매칭이 정상적으로 이루어지지 않았던 것 같습니다. 두서 없이 적어서 문제를 이해하기 힘드셨을텐데 감사합니다.

    • BlogIcon 다크pgmr 2017.05.18 15:15 신고 수정/삭제

      네.. ^^

  • dan 2017.05.30 18:22 신고 ADDR 수정/삭제 답글

    안녕하세요. 다크프로그래머님. 항상 많은 정보와 지식을 얻고 갑니다.
    호모그래피 관련해서 여쭤볼 것이 있어 질문드립니다 ㅠ.ㅠ
    카메라로 획득한 영상을 왜곡 보정 후에, 호모그래피 과정을 통해 2D화면으로 바꾸고자 합니다.
    ** 이 때에는 제가 카메라로 획득후 왜곡 보정한 영상(그림1), 투사하고자 하는 평면의 영상(그림2)과의 Homography를 구해서 투사하고자 하는 평면에 최종 투사한 결과물 (그림3:output) 이 나오는것이 맞는 건가요? **
    ** 이때 OpenCV환경에서 findhomography 등 내장함수를 사용하려고 합니다. (RANSAC의 방법이 가장 좋은 것으로 알아 RANSAC을 사용할 듯 합니다) 4쌍의 특징점을 잡기 위해서는 findhomography 이전에 다른 일련의 과정이 필요한 건가요? **

    • BlogIcon 다크pgmr 2017.05.30 21:56 신고 수정/삭제

      첫번째는 생각하신 바가 맞습니다. 그리고 두번째는 영상에서 특징점을 뽑고 서로 매칭하는 과정이 필요합니다.

  • nuke 2017.11.13 23:03 신고 ADDR 수정/삭제 답글

    안녕하세요 다크프로그래머님
    그래픽스 책을 읽다가 기하변환에 대해 궁금증이 있어서 질문드립니다.
    평행이동에서 덧셈으로 표기해 주셨는데 나중에 보니 이것을 왜 동차좌표계로 바꾸는 것일까요...?
    그냥 순서대로 더해서 처리하면 안되는 문제점이있나요...?

    • BlogIcon 다크pgmr 2017.11.14 01:39 신고 수정/삭제

      선형변환을 하나의 행렬 곱으로 표현할 수 있기 때문입니다. 그러면 일련의 선형변환을 순차적으로 적용한다고 했을 때 이들을 하나의 행렬로 미리 곱해놓고 사용할 수 있는 장점이 있습니다.

  • 나사 2017.12.13 17:12 신고 ADDR 수정/삭제 답글

    궁금한게있습니다
    Rigid 변환에서 R의 행렬식이 음수이면 reflection 이라고 하는데 왜 그런가요

    • BlogIcon 다크pgmr 2017.12.14 09:07 신고 수정/삭제

      글쎄요.. 직교행렬(orthogonal matrix)이면서 행렬식 값이 +1이 행렬이 rotation 행렬이고 행렬식 값이 -1인 행렬이 reflection 행렬입니다. rigid 변환은 크기와 형태가 보존되는 변환이기 때문에 R*p + t (t: 평행이동) 형태가 되어야 하고, R의 행렬식이 -1이라면 reflection 행렬이겠네요..