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

Reply via email to