bbrister / SIFT3D

Analogue of the scale-invariant feature transform (SIFT) for three-dimensional images. Includes an image processing and linear algebra library with feature matching and RANSAC regression. Also includes IO functions supporting a variety of image formats.
MIT License
134 stars 47 forks source link

How rotation matrix is computed? #18

Closed snitchjinx closed 5 years ago

snitchjinx commented 6 years ago

Hello! Thank you very much for your nice project!

I'm learning 3D-SIFT with your code. I run it by a script in matlab while refering to C. But I can't quite find how the 33 rotation matrix is computed for each keypoint. I noticed: `Keypoint const key = kp->buf + i;
const Image const level = SIFT3D_PYR_IM_GET(&sift3d->gpyr, key->o, key->s);
Mat_rm
const R = &key->R;
const Cvec vcenter = {key->xd, key->yd, key->zd};
const double sigma = ori_sig_fctr key->sd;` in the function "static int assign_orientations(SIFT3D const sift3d, Keypoint_store *const kp)" in sift.c.

Can you please give me some instructions on how &key->R is computed? Thanks a lot!

snitchjinx commented 6 years ago

And one more question is that, since C code and matlab index coordinates differently, is it necessary to invert key.coords and transpose array im before calling the API? Thank you!

bbrister commented 6 years ago

Hello, thanks for your interest in this work.

The rotation matrix is computed in the assign_eig_ori function, line 1341 of sift3d/sift.c. This function actually contains a subtle bug that degrades accuracy, which will soon be fixed in the next release.

The mathematical details are described in this paper: http://ieeexplore.ieee.org/abstract/document/

The Matlab wrapper actually uses the same coordinate indices as the underlying C code. This means that each coordinate is an (x, y, z) tuple. The program assumes that the image is stored in the same order, where the first dimension is x and the second dimension is y. This is transposed from the way 2D images are usually stored in Matlab, where the first image dimension is y, or the second coordinate component. Depending on how you store the 3D image, you may need to shuffle the x and y dimensions. For reference, you can use the imRead3D.m function in the toolbox, which will load images in the correct ordering.

Thanks for bringing this issue to my attention. I will include some more documentation about image indexing in the next release.

Please let me know if you have any more questions.

hecatezxx commented 6 years ago

Hello, thanks for your interest in this work.

The rotation matrix is computed in the assign_eig_ori function, line 1341 of sift3d/sift.c. This function actually contains a subtle bug that degrades accuracy, which will soon be fixed in the next release.

The mathematical details are described in this paper: http://ieeexplore.ieee.org/abstract/document/

The Matlab wrapper actually uses the same coordinate indices as the underlying C code. This means that each coordinate is an (x, y, z) tuple. The program assumes that the image is stored in the same order, where the first dimension is x and the second dimension is y. This is transposed from the way 2D images are usually stored in Matlab, where the first image dimension is y, or the second coordinate component. Depending on how you store the 3D image, you may need to shuffle the x and y dimensions. For reference, you can use the imRead3D.m function in the toolbox, which will load images in the correct ordering.

Thanks for bringing this issue to my attention. I will include some more documentation about image indexing in the next release.

Please let me know if you have any more questions.

Hello, what you mentioned helps me a lot. But i still have a question about the transformation matrix. I used imRead3D.m function to load my 3D data and then only introduced translation to the volume as the src data manually. Like the translation was [0 10 0], but the transformation matrix showed the translation was [10 0 0]. So was that the same problem you mentioned above? Should I shuffle the x and y dimensions for that?

bbrister commented 5 years ago

Yes, it is likely due to the same issue as above. Basically, Matlab treats [0 10 0] as a translation in the x-axis, whereas in SIFT3D the x-coordinate is the first one, so the translation returned is [10 0 0]. If you shuffle the x- and y-dimensions on the output transform, you will get the matrix in Matlab's coordinate system.