Hi Joshua, Sorry I haven't replied to you earlier. Once my email piles up, it takes some time for me to go over it.
We basically have two translations. The one implemented by Pablo, and used by Hugin, and the one implemented by Dev and I, which is not directly available from Hugin. I don't think we have this well documented, but let me try to explain you how it works. Any photo is mapped to the sphere, from the sphere, it is then remapped to the corresponding output projection. This imposes a big limitation in linear panoramas: they are not really linear, they are slices of the sphere. In a previous message I listed the order in which the remapping happens. Remember, it is done backwards (any point of the output projection is mapped back to each point in the source images. In the panotools model (also used by Nona and Hugin), the center of a photo is the center of the world, with X and Y in the usual direction, and normalized according to their field of view and input projection with respect to the area it would cover in the sphere. I really don't know the way the Tr[XYZ] parameters work, but the code is easy to read, and Pablo can probably answer any questions you have: plane_transfer_from_camera is the inverse, if I remember correctly. Some notes: * mp->distance is a used to normalize the distances in the image (to a unit sphere). * the pointer variables are the outputs, and the non-pointers, the inputs. /** transfer a point from the master camera through a plane into camera * at TrX, TrY, TrZ using the plane located at Te0 (yaw), Te1 (pitch) */ int plane_transfer_to_camera( double x_dest, double y_dest, double * x_src, double * y_src, void * params) { // params: distance, x1,y1,z1 double plane_coeff[4]; double p1[3]; double p2[3]; double intersection[3]; // compute ray of sight for the current pixel in // the master panorama camera. // camera point p1[0] = p1[1] = p1[2] = 0; // point on sphere. cart_erect(x_dest, y_dest, &p2[0], mp->distance); // compute plane description cart_erect(DEG_TO_RAD(mp->test[0]), -DEG_TO_RAD(mp->test[1]), &plane_coeff[0], 1.0); // plane_coeff[0..2] is both the normal and a point // on the plane. plane_coeff[3] = - plane_coeff[0]*plane_coeff[0] - plane_coeff[1]*plane_coeff[1] - plane_coeff[2]*plane_coeff[2]; /* printf("Plane: y:%f p:%f coefficients: %f %f %f %f, ray direction: %f %f %f\n", mp->test[0], mp->test[1], plane_coeff[0], plane_coeff[1], plane_coeff[2], plane_coeff[3], p2[0],p2[1],p2[2]); */ // perform intersection. if (!line_plane_intersection(plane_coeff, p1, p2, &intersection[0])) { // printf("No intersection found, %f %f %f\n", p2[0], p2[1], p2[2]); return 0; } // compute ray leading to the camera. intersection[0] -= mp->trans[0]; intersection[1] -= mp->trans[1]; intersection[2] -= mp->trans[2]; // transform into erect erect_cart(&intersection[0], x_src, y_src, mp->distance); /* printf("pano->plane->cam(%.1f, %.1f, %.1f, y:%1f,p:%1f): %8.5f %8.5f -> %8.5f %8.5f %8.5f -> %8.5f %8.5f\n", mp->trans[0], mp->trans[1], mp->trans[2], mp->test[0], mp->test[1], x_dest, y_dest, intersection[0], intersection[1], intersection[2], *x_src, *y_src); */ return 1; } /** transfer a point from a camera centered at x1,y1,z1 into the camera at x2,y2,z2 */ int plane_transfer_from_camera( double x_dest, double y_dest, double * x_src, double * y_src, void * params) { double phi, theta; double plane_coeff[4]; double p1[3]; double p2[3]; double intersection[3]; // params: MakeParams // compute ray of sight for the current pixel in // the master panorama camera. // camera point p1[0] = mp->trans[0]; p1[1] = mp->trans[1]; p1[2] = mp->trans[2]; // point on sphere (direction vector in camera coordinates) cart_erect(x_dest, y_dest, &p2[0], mp->distance); // add camera position to get point on ray p2[0] += p1[0]; p2[1] += p1[1]; p2[2] += p1[2]; // compute plane description cart_erect(DEG_TO_RAD(mp->test[0]), -DEG_TO_RAD(mp->test[1]), &plane_coeff[0], 1.0); // plane_coeff[0..2] is both the normal and a point // on the plane. plane_coeff[3] = - plane_coeff[0]*plane_coeff[0] - plane_coeff[1]*plane_coeff[1] - plane_coeff[2]*plane_coeff[2]; /* printf("Plane: y:%f p:%f coefficients: %f %f %f %f, ray direction: %f %f %f\n", mp->test[0], mp->test[1], plane_coeff[0], plane_coeff[1], plane_coeff[2], plane_coeff[3], p2[0],p2[1],p2[2]); */ // compute intersection if (!line_plane_intersection(plane_coeff, p1, p2, &intersection[0])) { //printf("No intersection found, %f %f %f\n", p2[0], p2[1], p2[2]); return 0; } // the intersection vector is the vector of the ray of sight from // the master panorama camera. // transform into erect erect_cart(&intersection[0], x_src, y_src, mp->distance); /* printf("cam->plane->pano(%.1f, %.1f, %.1f, y:%1f,p:%1f): %8.5f %8.5f -> %8.5f %8.5f %8.5f -> %8.5f %8.5f\n", mp->trans[0], mp->trans[1], mp->trans[2], mp->test[0], mp->test[1], x_dest, y_dest, intersection[0], intersection[1], intersection[2], *x_src, *y_src); */ return 1; } Joshua Stults twisted the bytes to say: Joshua> Hello Professor German, Joshua> I am trying to learn more of the details of the Hugin software and saw Joshua> your contributions on the mailing list about the new mosaic mode that Joshua> includes translations (TrX, TrY, TrZ). http://groups.google.com/group/hugin-ptx/browse_thread/thread/1de451748572c7cb/9f9c6270c2ef9a39?q=#9f9c6270c2ef9a39 http://groups.google.com/group/hugin-ptx/browse_thread/thread/8b98de416fc5e808/88fb71a3fd796e06?q=#88fb71a3fd796e06 Joshua> Is there a place that the coordinate system for these fits (all six Joshua> degrees of freedom) is documented? I assume that it is a standard Joshua> right-handed coordinate system (with yaw about y-axis, roll about Joshua> z-axis, pitch about x-axis), but how is the positive direction Joshua> defined? I am trying to use the fitted camera positions as a modeling Joshua> aid. Thanks for any help / pointers you can provide. Joshua> -- Joshua> Joshua Stults Joshua> daytondiode.blogspot.com -- -- Daniel M. German http://turingmachine.org/ http://silvernegative.com/ dmg (at) uvic (dot) ca replace (at) with @ and (dot) with . -- You received this message because you are subscribed to the Google Groups "Hugin and other free panoramic software" group. A list of frequently asked questions is available at: http://wiki.panotools.org/Hugin_FAQ To post to this group, send email to hugin-ptx@googlegroups.com To unsubscribe from this group, send email to hugin-ptx+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/hugin-ptx