2012-10-27 3 views
4

회전 변환 행렬 [R T] (3x4)이 있습니다.opencv에서 행렬 R과 T (외래 매개 변수 행렬)를 사용하여 이미지를 변환하는 방법은 무엇입니까?

opencv에서 [R T]로 설명한 회전 변환을 수행하는 함수가 있습니까?

+0

네,하지만 내재적 매개 변수가 필요합니다. 또한 이미지의 초기 위치에 대해 약간의 가정을해야하지만 보통 문제가되지 않습니다. – Hammer

+0

예, 본질적인 매개 변수가 있습니다. –

+1

다음 질문입니다. R 및 T 행렬은 무엇입니까? 카메라 원래 위치? 세계 공간의 일부 위치? ect. – Hammer

답변

9

이 질문에 대한 많은 해결책은 숨겨진 가정이라고 생각합니다. 나는이 문제에 대해 어떻게 생각하는지 (나는 과거에 많은 것을 생각해야만했다)에 대한 간단한 요약을하려고 노력할 것이다. 두 이미지 간의 워핑은 호모 그래피 (homography) 라 불리는 3x3 매트릭스로 수행되는 2 차원 프로세스입니다. 가지고있는 것은 3 차원에서 변환을 정의하는 3x4 행렬입니다. 이미지를 3 차원 공간에서 평평한면으로 처리하여 두면을 변환 할 수 있습니다. 트릭은 이미지면의 세계 공간에서 초기 위치를 결정하는 것입니다. 그런 다음 카메라 내장 함수 행렬을 사용하여 위치를 변형하고 새로운 이미지 평면으로 투영 할 수 있습니다.

첫 번째 단계는 초기 이미지가 세계 공간에있는 위치를 결정하는 것입니다. 처음의 R 및 T 행렬 지정과 같을 필요는 없습니다. 그것들은 세계 좌표계에 있고, 우리는 그 세계에 의해 생성 된 이미지에 대해 이야기하고 있으며, 이미지의 모든 객체는 평면으로 평평하게되어 있습니다. 여기서 가장 간단한 결정은 이미지를 z 축의 고정 된 변위 및 회전없이 설정하는 것입니다. 이 시점에서 나는 아무런 교체도하지 않을 것입니다. 일반적인 경우를보고 싶다면 좀 더 복잡 할 수 있습니다.

다음은 3D 공간에서 두 이미지 간의 변환을 정의합니다. 동일한 원점에 대해 두 가지 변형이 모두 있기 때문에 [A]에서 [B] 로의 변형은 [A]에서 원점으로의 변형과 동일하며 원점에서 [B] 로의 변형이 뒤 따른다. 당신은 3 차원 공간에서 이미지의 기하학적 해석에 프로젝트,

transform = [B]*inverse([A]) 

에 의해 이제 개념적으로 무엇을 당신이해야 할 것은 첫 번째 이미지를 촬영하는 것입니다 자사의 픽셀을 얻을 수 있습니다, 다음 변환에 의해 3 차원 공간에서 그 픽셀을 변환 그런 다음 카메라 매트릭스를 사용하여 새로운 2D 이미지 위에 다시 투사하십시오. 이러한 단계는 단일 3x3 매트릭스로 결합되어야합니다.

cv::Matx33f convert_3x4_to_3x3(cv::Matx34f pose, cv::Matx33f camera_mat, float zpos) 
{ 
//converted condenses the 3x4 matrix which transforms a point in world space 
//to a 3x3 matrix which transforms a point in world space. Instead of 
//multiplying pose by a 4x1 3d homogeneous vector, by specifying that the 
//incoming 3d vectors will ALWAYS have a z coordinate of zpos, one can instead 
//multiply converted by a homogeneous 2d vector and get the same output for x and y. 

cv::Matx33f converted(pose(0,0),pose(0,1),pose(0,2)*zpos+pose(0,3), 
         pose(1,0),pose(1,1),pose(1,2)*zpos+pose(1,3), 
         pose(2,0),pose(2,1),pose(2,2)*zpos+pose(2,3)); 

//This matrix will take a homogeneous 2d coordinate and "projects" it onto a 
//flat plane at zpos. The x and y components of the incoming homogeneous 2d 
//coordinate will be correct, the z component is dropped. 
cv::Matx33f projected(1,0,0, 
         0,1,0, 
         0,0,zpos); 
projected = projected*camera_mat.inv(); 

//now we have the pieces. A matrix which can take an incoming 2d point, and 
//convert it into a pseudo 3d point (x and y correspond to 3d, z is unused) 
//and a matrix which can take our pseudo 3d point and transform it correctly. 
//Now we just need to turn our transformed pseudo 3d point back into a 2d point 
//in our new image, to do that simply multiply by the camera matrix. 

return camera_mat*converted*projected; 
} 

이것은 아마도 당신이 찾고 있었던 것보다 더 복잡한 대답 일 것입니다. 그러나 이것은 당신이 무엇을 요구하고 있는지에 대한 아이디어를 줄 수 있기를 바랍니다. 이것은 매우 혼란 스러울 수 있으며, 신속하게 그 일부분을 유약로 바꿔 설명해 줄 것을 요청하십시오. 초기 이미지가 회전없이 나타났다는 가정없이 솔루션을 사용해야하는 경우 알려주겠습니다. 필요 이상으로 복잡하게 만들고 싶지 않았습니다.

+0

비슷한 일을하려고 할 때 답을 따르려고 노력했습니다. 아마도 도움이 될 수 있습니다. 함수 pose 및 camera_mat에 대한 입력은? 정확히이게 뭐야? Carlo는 두 카메라의 고유 및 외적 행렬을 가지고 있다고 언급 했었습니다 (어떻게합니까) View 1의 (x, y) 점을 View 2의 해당 (x, y) 점으로 어떻게 매핑합니까? 함수에서 반환 된 3x3 행렬에 뷰 1의 (x, y) 점을 곱하면 되겠습니까? –

+0

@LukeZammit 포인트를 변환하려면 (x, y) 포인트를 3 벡터 [x, y, 1]로 변환하고 3x3 매트릭스로 곱하십시오. Camera_mat는 카메라 내장 함수 행렬입니다. 내장 매트릭스가 온라인으로 작동하는 방법에 대한 설명은 찾을 수 있지만 개념적으로는 카메라의 초점 길이를 나타냅니다. 포즈는 '3D 공간'에서 이미지에 적용 할 변형입니다. 아직 질문이 있으면 알려주세요. – Hammer