Writing images' camera extrinsics as [R|t]

540 views
Skip to first unread message

kevi...@insightdigital.org

unread,
Oct 13, 2018, 11:23:43 PM10/13/18
to COLMAP
I'd like to export a sparse reconstruction, writing each participating image in the following form:
  • Extrinsic matrix: E = [R|t], which I believe we can express as 3x4 matrix composed of a 3x3 rotation matrix and 3x1 translation vector:

r1,1 r1,2 r1,3 | t1

r2,1 r2,2 r2,3 | t2

r3,1 r3,2 r3,3 | t3


  • Intrinsic matrix: Matrix composed of focal length (α), principal point (υ):

Here is an example of the desired output:

extrinsic output

0.970263 0.00747983 0.241939 -191.02

-0.0147429 0.999493 0.0282234 3.2883

-0.241605 -0.030951 0.969881 22.5401

0.0 0.0 0.0 1.0


intrinsic output

2892.33 0 823.205

0 2892.33 619.071

0 0 1


As shown in the snippet below, I've tried Colmap's RotationMatrix for extrinsics and, for intrinsics, focal length and principal point.

This seems to be the wrong approach to get R | t. Can anyone point out my errors, or a working approach?

for (const auto& image : images_) {
if (!image.second.IsRegistered()) {
continue;
}

Eigen::Matrix3d R_;
R_ = image.second.RotationMatrix();
// Write camera rotation matrix and translation vector
file << R_(0,0) << " " << R_(0,1) << " " << R_(0,1) << " " << image.second.Tvec(0) << std::endl;
file << R_(1,0) << " " << R_(1,1) << " " << R_(1,1) << " " << image.second.Tvec(1) << std::endl;
file << R_(2,0) << " " << R_(2,1) << " " << R_(2,1) << " " << image.second.Tvec(2) << std::endl;
file << "0.0 0.0 0.0 1.0" << std::endl;
file << std::endl;

// Write camera intrinsics
auto& camera = cameras_.at(image.second.CameraId());
file << camera.FocalLength() << " 0 " << camera.PrincipalPointX() << std::endl;
file << "0 " << camera.FocalLength() << " " << camera.PrincipalPointY() << std::endl;
file << "0 0 1" << std::endl;
file << std::endl;

...
}

Johannes Schönberger

unread,
Oct 14, 2018, 8:12:02 AM10/14/18
to col...@googlegroups.com

Hi,

 

This is the right approach, but you have a bug in your script. The last column of your rotation matrix must be index with 2 instead of 1.

 

I also suggest to use FocalLengthX() and FocalLengthY() instead of FocalLength(), because some camera models support different focal lengths in X and Y. Also note that with this code you are not exporting distortion parameters.

 

Cheers,

Johannes

 

From: <col...@googlegroups.com> on behalf of <kevi...@insightdigital.org>
Reply-To: <col...@googlegroups.com>
Date: Sunday, October 14, 2018 at 5:23 AM
To: COLMAP <col...@googlegroups.com>
Subject: [COLMAP] Writing images' camera extrinsics as [R|t]

 

I'd like to export a sparse reconstruction, writing each participating image in the following form:

  • Extrinsic matrix:
  • E = [R|t], which I believe we can express as 3x4 matrix composed of a 3x3 rotation matrix and 3x1 translation vector:

r1,1 r1,2 r1,3 | t1

r2,1 r2,2 r2,3 | t2

r3,1 r3,2 r3,3 | t3

 

  • Intrinsic matrix:
  • Matrix composed of focal length (α), principal point (υ):
  • Image removed by sender.

                    

--
You received this message because you are subscribed to the Google Groups "COLMAP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to colmap+un...@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/colmap/aaa10bc1-1c0a-424f-80ac-211b49ef7756%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

kevi...@insightdigital.org

unread,
Oct 14, 2018, 9:07:30 PM10/14/18
to COLMAP
Thanks for the fast reply. your suggestions, and for pointing out my error in my sample code.

It seems that I had the matrix indices right in my actual code, shown below, but my output is still malformed considering its results.  I've tried other options using the essential matrix between two given views and projection matrix, to name two, but without success.  Perhaps the problem is not understanding how to access the global reference frame to which the camera reference frame relates.

Regarding your point about ignoring Colmap's distortion parameters, I did see one such value (e.g., pba_camera.GetProjectionDistortion()), are there others?  It wasn't clear to me how to adapt intrinsics with this value, but if you could point me in the right direction I'll look into that.

My current export snippet follows for reference:

// Iterate through all aligned views
int currentCamera = 0;
for (const auto& image : images_) {
if (!image.second.IsRegistered()) {
continue;
}

// Write camera extrinsics
file << "extrinsic" << std::endl;

Eigen::Matrix3d R;
R = image.second.RotationMatrix();
// Write camera rotation matrix and translation vector
file << R(0,0) << " " << R(0,1) << " " << R(0,2) << " " << image.second.Tvec(0) << std::endl;
file << R(1,0) << " " << R(1,1) << " " << R(1,2) << " " << image.second.Tvec(1) << std::endl;
file << R(2,0) << " " << R(2,1) << " " << R(2,2) << " " << image.second.Tvec(2) << std::endl;
file << "0.0 0.0 0.0 1.0" << std::endl;

// Write camera intrinsics
file << std::endl;
file << "intrinsic" << std::endl;

// Reference to current image's camera
auto& camera = cameras_.at(image.second.CameraId());
// Note hard-coded zero value for skew

Johannes Schönberger

unread,
Oct 15, 2018, 11:47:37 AM10/15/18
to col...@googlegroups.com
R and T here define the world to camera coordinate system transformation. You might instead be interested in the inverse transformation R.transpose() and -R.transpose() * T.

Cheers,
Johannes
> --
> You received this message because you are subscribed to the Google
> Groups "COLMAP" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to colmap+un...@googlegroups.com.
> To post to this group, send email to col...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/colmap/02bd4302-1909-4fe2-9c0b-76a75d68f79e%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages