Bronger, thank you for your response.

 But from the code of "mod-coord.cpp" (this file locates in
~/lensfun-0.2.7/libs/lensfun/mod-coord.cpp), we can see the following
code (for example for poly3 model, but the other models follow the
similar rule):

void lfExtModifier::ModifyCoord_Dist_Poly3 (void *data, float *iocoord, int 
count)
{
    const float inv_k1 = *(float *)data;
    const float one_minus_k1_div_k1 = (1 - 1.0 / inv_k1) * inv_k1;

    for (float *end = iocoord + count * 2; iocoord < end; iocoord += 2)
    {
        float x = iocoord [0];
        float y = iocoord [1];
        double ru = sqrt (x * x + y * y);
        if (ru == 0.0)
            continue;

         float ru_div_k1 = ru * inv_k1;

        // Use Newton's method to avoid dealing with complex numbers
        // When carefully tuned this works almost as fast as Cardano's
        // method (and we don't use complex numbers in it, which is
        // required for a full solution!)
        //
        // Original function: Ru = k1 * Rd^3 + (1 - k1) * Rd
        // Target function:   k1 * Rd^3 + (1 - k1) * Rd - Ru = 0
        // Divide by k1:      Rd^3 + Rd * (1 - k1)/k1 - Ru/k1 = 0
        // Derivative:        3 * Rd^2 + (1 - k1)/k1
        double rd = ru;
        for (int step = 0; ; step++)
        {
            double frd = rd * rd * rd + rd * one_minus_k1_div_k1 - ru_div_k1;
            if (frd >= -NEWTON_EPS && frd < NEWTON_EPS)
                break;
            if (step > 5)
                // Does not converge, no real solution in this area?
                goto next_pixel;

            rd -= frd / (3 * rd * rd + one_minus_k1_div_k1);
        }
        if (rd < 0.0)
            continue; // Negative radius does not make sense at all

        rd /= ru;
        iocoord [0] = x * rd;
        iocoord [1] = y * rd;

    next_pixel:
        ;
    }
}

void lfExtModifier::ModifyCoord_UnDist_Poly3 (void *data, float *iocoord, int 
count)
{
    // Ru = Rd * (1 - k1 + k1 * Rd^2)
    const float k1 = *(float *)data;
    const float one_minus_k1 = 1.0 - k1;

    for (float *end = iocoord + count * 2; iocoord < end; iocoord += 2)
    {
        const float x = iocoord [0];
        const float y = iocoord [1];
        const float poly2 = one_minus_k1 + k1 * (x * x + y * y);

        iocoord [0] = x * poly2;
        iocoord [1] = y * poly2;
    }
}

 It seems that: given a distorted radius (Rd), we can directly compute
the undistorted radius (Ru), according the distortion forumula.
While given a undistorted radius (Ru), we need a Newton method to
solve the distorted radius (Rd).

 So I think that  Rd is measured in the original image (taken by the
camera), whereas Ru is measured in the destination picture (which is
supposed to be undistorted)?

 Do you agree ? Anyone else have comments ?

------------------------------------------------------------------------------
Put Bad Developers to Shame
Dominate Development with Jenkins Continuous Integration
Continuously Automate Build, Test & Deployment 
Start a new project now. Try Jenkins in the cloud.
http://p.sf.net/sfu/13600_Cloudbees
_______________________________________________
Lensfun-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lensfun-users

Reply via email to