Пример #1
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);
}
Пример #2
0
int main (int argc, char **argv)
{
	QCoreApplication app(argc, argv);
	printf("Loading mask...\n");
    QTRGB24Loader  ::registerMyself();
    QTG12Loader    ::registerMyself();
    QTRuntimeLoader::registerMyself();

	QImage imageMask    ("data/adopt/orig.png");
	QImage imageAlpha   ("data/adopt/alpha.bmp");
    QImage imageFace    ("data/adopt/face.png");

    RGB24Buffer *alpha24 = QTFileLoader::RGB24BufferFromQImage(&imageAlpha);
    RGB24Buffer *mask    = QTFileLoader::RGB24BufferFromQImage(&imageMask);
    RGB24Buffer *face    = QTFileLoader::RGB24BufferFromQImage(&imageFace);

    G8Buffer *alpha = alpha24->getChannel(ImageChannel::GRAY);

    Vector3dd meanMask(0.0);
    Vector3dd meanFace(0.0);
    double count = 0;

	/* Get hole statistics */
    for (int i = 0; i < mask->h; i++)
    {
        for (int j = 0; j < mask->w; j++)
        {
            if (alpha->element(i,j) > 10)
                continue;

            count++;
            meanFace += face->element(i,j).toDouble();
            meanMask += mask->element(i,j).toDouble();
        }
    }

    meanFace /= count;
    meanMask /= count;

    cout << "Mean face value is" << meanFace << endl;
    cout << "Mean face value is" << meanMask << endl;

    EllipticalApproximationUnified<Vector3dd> facePrincipal;
    EllipticalApproximationUnified<Vector3dd> maskPrincipal;

    for (int i = 0; i < mask->h; i++)
    {
       for (int j = 0; j < mask->w; j++)
       {
           facePrincipal.addPoint(face->element(i,j).toDouble() - meanFace);
           maskPrincipal.addPoint(mask->element(i,j).toDouble() - meanMask);
       }
    }
    facePrincipal.getEllipseParameters();
    maskPrincipal.getEllipseParameters();

    cout << "Face Principals" << endl;
    cout << facePrincipal.mAxes[0] << "->" << facePrincipal.mValues[0] << endl;
    cout << facePrincipal.mAxes[1] << "->" << facePrincipal.mValues[1] << endl;
    cout << facePrincipal.mAxes[2] << "->" << facePrincipal.mValues[2] << endl;

    cout << "Mask Principals" << endl;
    cout << maskPrincipal.mAxes[0] << "->" << maskPrincipal.mValues[0] << endl;
    cout << maskPrincipal.mAxes[1] << "->" << maskPrincipal.mValues[1] << endl;
    cout << maskPrincipal.mAxes[2] << "->" << maskPrincipal.mValues[2] << endl;

    Vector3dd scalers;
    scalers.x() = sqrt(maskPrincipal.mValues[0]) / sqrt(facePrincipal.mValues[0]);
    scalers.y() = sqrt(maskPrincipal.mValues[1]) / sqrt(facePrincipal.mValues[1]);
    scalers.z() = sqrt(maskPrincipal.mValues[2]) / sqrt(facePrincipal.mValues[2]);

    /* Making correction for face */
    RGB24Buffer *faceCorr = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr->h; i++)
    {
       for (int j = 0; j < faceCorr->w; j++)
       {
           Vector3dd color = face->element(i,j).toDouble() - meanFace;
           Vector3dd projected(color & facePrincipal.mAxes[0],
                      color & facePrincipal.mAxes[1],
                      color & facePrincipal.mAxes[2]);

           projected = projected * scalers;

           Vector3dd newColor =
                   maskPrincipal.mAxes[0] * projected.x() +
                   maskPrincipal.mAxes[1] * projected.y() +
                   maskPrincipal.mAxes[2] * projected.z() + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr->element(i,j) = newrgb;
       }
    }

    /* With Matrix*/
    Matrix33 scalerM    = Matrix33::Scale3(scalers);
    Matrix33 toUnityM   = Matrix33::FromRows(facePrincipal.mAxes[0], facePrincipal.mAxes[1], facePrincipal.mAxes[2]);
    Matrix33 fromUnityM = Matrix33::FromColumns(maskPrincipal.mAxes[0], maskPrincipal.mAxes[1], maskPrincipal.mAxes[2]);

    Matrix33 transform = fromUnityM * scalerM * toUnityM;

    RGB24Buffer *faceCorr2 = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr2->h; i++)
    {
       for (int j = 0; j < faceCorr2->w; j++)
       {
           Vector3dd newColor = transform * (face->element(i,j).toDouble() - meanFace) + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr2->element(i,j) = newrgb;
       }
    }


    /* Without roots */
    scalers.x() = maskPrincipal.mValues[0] / facePrincipal.mValues[0];
    scalers.y() = maskPrincipal.mValues[1] / facePrincipal.mValues[1];
    scalers.z() = maskPrincipal.mValues[2] / facePrincipal.mValues[2];


    /* Making correction for face */
    RGB24Buffer *faceCorr1 = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr1->h; i++)
    {
       for (int j = 0; j < faceCorr1->w; j++)
       {
           Vector3dd color = face->element(i,j).toDouble() - meanFace;
           Vector3dd projected(color & facePrincipal.mAxes[0],
                      color & facePrincipal.mAxes[1],
                      color & facePrincipal.mAxes[2]);

           projected = projected * scalers;

           Vector3dd newColor =
                   maskPrincipal.mAxes[0] * projected.x() +
                   maskPrincipal.mAxes[1] * projected.y() +
                   maskPrincipal.mAxes[2] * projected.z() + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr1->element(i,j) = newrgb;
       }
    }



    /* Make a final blending */
    BMPLoader().save("output0.bmp", mask);


    RGB24Buffer *result = alphaBlend(mask, face, alpha);
	BMPLoader().save("output1.bmp", result);

	RGB24Buffer *result1 = alphaBlend(mask, faceCorr, alpha);
	BMPLoader().save("output2.bmp", result1);

	RGB24Buffer *result2 = alphaBlend(mask, faceCorr1, alpha);
    BMPLoader().save("output3.bmp", result2);

    RGB24Buffer *result3 = alphaBlend(mask, faceCorr2, alpha);
    BMPLoader().save("matrix-out.bmp", result3);


	delete_safe(alpha);
    delete_safe(mask);
    delete_safe(face);
    delete_safe(faceCorr);
    delete_safe(faceCorr1);
    delete_safe(faceCorr2);

    delete_safe(result);
    delete_safe(result1);
    delete_safe(result2);
    delete_safe(result3);
    return 0;
}