コード例 #1
0
    static RadialCorrection updateWithModel(const RadialCorrection &input, const double in[])
    {
        LensDistortionModelParameters params = input.mParams;
        params.setTangentialX(in[TANGENT_X]);
        params.setTangentialY(in[TANGENT_Y]);
        for (unsigned i = 0; i < MODEL_POWER; i++)
        {
            params.mKoeff[i] = in[i + RADIAL_FIRST];
        }

        return RadialCorrection(params);
    }
コード例 #2
0
ファイル: test_deform.cpp プロジェクト: Aldrog/corecvs
void testRadialInversion(int scale)
{
    RGB24Buffer *image = new RGB24Buffer(250 * scale, 400 * scale);

    auto operation = [](int i, int j, RGBColor *pixel)
    {
        i = i / 100;
        j = j / 200;
        if ( (i % 2) &&  (j % 2))   *pixel = RGBColor::Green();
        if (!(i % 2) &&  (j % 2))   *pixel = RGBColor::Yellow();
        if ( (i % 2) && !(j % 2))   *pixel = RGBColor::Red();
        if (!(i % 2) && !(j % 2))   *pixel = RGBColor::Blue();
    };
    touchOperationElementwize(image, operation);

    LensDistortionModelParameters deformator;
    deformator.setPrincipalX(image->w / 2);
    deformator.setPrincipalY(image->h / 2);

    deformator.setTangentialX(0.000001);
    deformator.setTangentialY(0.000001);

    deformator.setAspect(1.0);
    deformator.setScale(1.0);

    deformator.mKoeff.push_back( 0.0001);
    deformator.mKoeff.push_back(-0.00000002);
    deformator.mKoeff.push_back( 0.00000000000003);

    RadialCorrection T(deformator);
    PreciseTimer timer;

    cout << "Starting deformation... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *deformed = image->doReverseDeformationBlTyped<RadialCorrection>(&T);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    /* */
    cout << "Starting invertion... " << flush;
    RadialCorrection invert = T.invertCorrection(image->h, image->w, 30);
    cout << "done" << endl;

    cout << "Starting backprojection... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *backproject = deformed->doReverseDeformationBlTyped<RadialCorrection>(&invert);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;
    cout << "done" << endl;

    BMPLoader().save("input.bmp"      , image);
    BMPLoader().save("forward.bmp"    , deformed);
    BMPLoader().save("backproject.bmp", backproject);

    delete_safe(image);
    delete_safe(deformed);
    delete_safe(backproject);
}
コード例 #3
0
void testRadialApplication(int scale)
{
    cout << "Starting test: testRadialApplication ()" << endl;
    RGB24Buffer *image = new RGB24Buffer(250 * scale, 400 * scale);

    auto operation = [](int i, int j, RGBColor *pixel)
    {
        i = i / 100;
        j = j / 200;
        if ( (i % 2) &&  (j % 2))   *pixel = RGBColor::Green();
        if (!(i % 2) &&  (j % 2))   *pixel = RGBColor::Yellow();
        if ( (i % 2) && !(j % 2))   *pixel = RGBColor::Red();
        if (!(i % 2) && !(j % 2))   *pixel = RGBColor::Blue();
    };
    touchOperationElementwize(image, operation);
    LensDistortionModelParameters deformator;
    deformator.setPrincipalX(image->w / 2);
    deformator.setPrincipalY(image->h / 2);

    deformator.setTangentialX(0.000001);
    deformator.setTangentialY(0.000001);

    deformator.setAspect(1.0);
    deformator.setScale(1.0);

    deformator.mKoeff.push_back( 0.0001);
    deformator.mKoeff.push_back(-0.00000002);
    deformator.mKoeff.push_back( 0.00000000000003);

    RadialCorrection T(deformator);
    PreciseTimer timer;

    /**
     * 1. Compute reverse image
     *
     *  Radial coorection stores transformation from real image to ideal.
     *  However to transform buffer we need to find inverse image of the pixel
     *
     *  We can either compute the inverse with the "analytical method" -
     *  the example is in testRadialInversion()
     *
     *  Or cache the inverse like we are doing here
     *
     **/
    cout << "Starting deformation inversion... " << flush;

    timer = PreciseTimer::currentTime();
    DisplacementBuffer *inverse = DisplacementBuffer::CacheInverse(&T,
        image->h, image->w,
        0.0,0.0,
        (double)image->w, (double)image->h, 0.5
    );
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    cout << "Applying deformation inversion... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *deformed = image->doReverseDeformationBlTyped<DisplacementBuffer>(inverse);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    /**
     * 2. We have 4 ways to invert the transform.
     *   1. Apply T directly
     *   2. Create distortion buffer that will cache the invert
     *
     **/

    /*2.1*/
    cout << "Applying forward deformation... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *corrected21 = deformed->doReverseDeformationBlTyped<RadialCorrection>(&T);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    RGB24Buffer *diff21 = RGB24Buffer::diff(image, corrected21);

    /*2.2*/
    cout << "Preparing forward deformation cache... " << flush;
    timer = PreciseTimer::currentTime();
    DisplacementBuffer *forward = new DisplacementBuffer(&T, image->h, image->w, false);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    cout << "Applying forward deformation cache... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *corrected22 = deformed->doReverseDeformationBlTyped<DisplacementBuffer>(forward);
    cout << "done in: " << timer.usecsToNow()  << "us"  << endl;

    RGB24Buffer *diff22 = RGB24Buffer::diff(image, corrected22);


    BMPLoader().save("input.bmp"                , image);
    BMPLoader().save("forward.bmp"              , deformed);
    BMPLoader().save("backward-direct.bmp"      , corrected21);
    BMPLoader().save("backward-direct-diff.bmp" , diff21);

    BMPLoader().save("backward-cached.bmp"      , corrected22);
    BMPLoader().save("backward-cached-diff.bmp" , diff22);

    delete_safe(image);
    delete_safe(deformed);
    delete_safe(forward);
    delete_safe(inverse);
    delete_safe(diff21);
    delete_safe(diff22);
    delete_safe(corrected21);
    delete_safe(corrected22);

}
コード例 #4
0
void testRadialInversion(int scale)
{
    RGB24Buffer *image = new RGB24Buffer(250 * scale, 400 * scale);

    auto operation = [](int i, int j, RGBColor *pixel)
    {
        i = i / 100;
        j = j / 200;
        if ( (i % 2) &&  (j % 2))   *pixel = RGBColor::Green();
        if (!(i % 2) &&  (j % 2))   *pixel = RGBColor::Yellow();
        if ( (i % 2) && !(j % 2))   *pixel = RGBColor::Red();
        if (!(i % 2) && !(j % 2))   *pixel = RGBColor::Blue();
    };
    touchOperationElementwize(image, operation);

#if 0
    LensDistortionModelParameters deformator;
    deformator.setPrincipalX(image->w / 2);
    deformator.setPrincipalY(image->h / 2);
    deformator.setNormalizingFocal(deformator.principalPoint().l2Metric());

    deformator.setTangentialX(0.001);
    deformator.setTangentialY(0.001);

    deformator.setAspect(1.0);
    deformator.setScale(1.0);

    deformator.mKoeff.push_back( 0.1);
    deformator.mKoeff.push_back(-0.2);
    deformator.mKoeff.push_back( 0.3);
#else
    LensDistortionModelParameters deformator;
    deformator.setMapForward(false);
    deformator.setPrincipalX(480);
    deformator.setPrincipalY(360);
    deformator.setNormalizingFocal(734.29999999999995);

    deformator.setTangentialX(0.00);
    deformator.setTangentialY(0.00);

    deformator.setShiftX(0.00);
    deformator.setShiftY(0.00);


    deformator.setAspect(1.0);
    deformator.setScale (1.0);

    deformator.mKoeff.clear();
    deformator.mKoeff.push_back( 0);
    deformator.mKoeff.push_back( -0.65545);
    deformator.mKoeff.push_back( 0);
    deformator.mKoeff.push_back( 8.2439);
//    deformator.mKoeff.push_back( 0);
//    deformator.mKoeff.push_back( 8.01);
#endif


    RadialCorrection T(deformator);
    PreciseTimer timer;

    cout << "Initial deformation... " << endl;
    cout << T.mParams << flush;;

    cout << "Starting deformation... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *deformed = image->doReverseDeformationBlTyped<RadialCorrection>(&T);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;

    /* */
    int inversionGridStep = 30;

    cout << "Starting invertion... " << flush;
    RadialCorrection invert = T.invertCorrection(image->h, image->w, inversionGridStep);
    cout << "done" << endl;

    cout << "Starting backprojection... " << flush;
    timer = PreciseTimer::currentTime();
    RGB24Buffer *backproject = deformed->doReverseDeformationBlTyped<RadialCorrection>(&invert);
    cout << "done in: " << timer.usecsToNow() << "us" << endl;
    cout << "done" << endl;


    RGB24Buffer *debug = new RGB24Buffer(image->getSize());
    /* Show visual */
    double dh = (double)image->h / (inversionGridStep - 1);
    double dw = (double)image->w / (inversionGridStep - 1);
    for (int i = 0; i < inversionGridStep; i++)
    {
        for (int j = 0; j < inversionGridStep; j++)
        {
             Vector2dd point(dw * j, dh * i);
             debug->drawCrosshare1(point, RGBColor::Yellow());
             Vector2dd deformed    = T.mapToUndistorted(point); /* this could be cached */
             Vector2dd backproject = invert.mapToUndistorted(deformed);

             debug->drawCrosshare1(backproject, RGBColor::Green());
        }
    }

    BMPLoader().save("input.bmp"      , image);
    BMPLoader().save("debug.bmp"      , debug);
    BMPLoader().save("forward.bmp"    , deformed);
    BMPLoader().save("backproject.bmp", backproject);

    delete_safe(image);
    delete_safe(debug);
    delete_safe(deformed);
    delete_safe(backproject);
}
コード例 #5
0
RadialCorrection RadialCorrection::invertCorrection(int h, int w, int step)
{
    LensDistortionModelParameters input = this->mParams;
    LensDistortionModelParameters result;

    /* make initial guess */

    result.setPrincipalX(input.principalX());
    result.setPrincipalY(input.principalY());
    result.setNormalizingFocal(input.normalizingFocal());

    result.setTangentialX(-input.tangentialX());
    result.setTangentialY(-input.tangentialY());

    result.setScale(1.0 / input.scale());

    result.setAspect(1.0 / input.scale()); /*< bad guess I believe */

    result.mKoeff.resize(RadialCorrectionInversionCostFunction::MODEL_POWER);
    for (unsigned i = 0; i < RadialCorrectionInversionCostFunction::MODEL_POWER; i++)
    {
        if (i < input.mKoeff.size()) {
            result.mKoeff[i] = -input.mKoeff[i];
        } else {
            result.mKoeff[i] = 0.0;
        }
    }

    /* Pack the guess and launch optimization */
    RadialCorrection guess(result);
    RadialCorrectionInversionCostFunction cost(*this, guess, step, h, w);

    LevenbergMarquardt lmFit;
    lmFit.maxIterations = 101;
    lmFit.maxLambda = 10e8;
    lmFit.lambdaFactor = 8;
    lmFit.f = &cost;
    lmFit.traceCrucial  = true;
    lmFit.traceProgress = true;
    lmFit.traceMatrix   = true;

    vector<double> initialGuess(cost.inputs);
    RadialCorrectionInversionCostFunction::fillWithRadial(guess, &(initialGuess[0]));
    cout << guess.mParams << endl;

    EllipticalApproximation1d stats;
    stats = cost.aggregatedCost(&(initialGuess[0]));
    SYNC_PRINT(("Start Mean Error: %f px\n", stats.getRadiusAround0()));
    SYNC_PRINT(("Start Max  Error: %f px\n", stats.getMax()));

    vector<double> target(cost.outputs, 0.0);
    vector<double> optimal = lmFit.fit(initialGuess, target);

    guess = RadialCorrectionInversionCostFunction::updateWithModel(guess, &(optimal[0]));

    /* Cost */

    cout << guess.mParams << endl;
    stats = cost.aggregatedCost(&(optimal[0]));
    SYNC_PRINT(("Final Mean Error: %f px\n", stats.getRadiusAround0()));
    SYNC_PRINT(("Final Max  Error: %f px\n", stats.getMax()));


    return guess;
}