Korrekturalgorithmus für die Fassverzerrung zur Korrektur des FishEye-Objektivs - Implementierung mit Java fehlgeschlagen

Ich habe eine große Menge Fotos mit einem Fischaugenobjektiv aufgenommen. Da ich einige Bildbearbeitungen (z. B. Kantenerkennung) an den Fotos vornehmen möchte, möchte ich die Laufverzerrung entfernen, die sich stark auf meine Ergebnisse auswirkt.

Nach einigen Recherchen und vielen gelesenen Artikeln habe ich dies gefundenSeite: Sie beschreiben einen Algorithmus (und einige Formeln), um dieses Problem zu lösen.

M = a * rcorr ^ 3 + b * rcorr ^ 2 + c * rcorr + d
rsrc = (a * rcorr ^ 3 + b * rcorr ^ 2 + c * rcorr + d) * rcorr

rsrc = Abstand eines Pixels von der Mitte des Quellbilds
rcorr = Abstand eines Pixels von der Mitte im korrigierten Bild
a, b, c = Verzerrung des Bildes d = lineare Skalierung des Bildes

Ich habe diese Formeln verwendet und versucht, dies in einer Java-Anwendung zu implementieren. Leider funktioniert es nicht und ich habe es nicht geschafft. "Korrigiertes" Bild ähnelt nicht dem Originalfoto und zeigt stattdessen einige mysteriöse Kreise in der Mitte. Schau hier:

http://imageshack.us/f/844/barreldistortioncorrect.jpg/ (Früher war dies ein Foto einer weißen Kuh vor einer blauen Wand.)

Hier ist mein Code:

protected int[] correction(int[] pixels) {

    //
    int[] pixelsCopy = pixels.clone();

    // parameters for correction
    double paramA = 0.0; // affects only the outermost pixels of the image
    double paramB = -0.02; // most cases only require b optimization
    double paramC = 0.0; // most uniform correction
    double paramD = 1.0 - paramA - paramB - paramC; // describes the linear scaling of the image

    //
    for(int x = 0; x < dstView.getImgWidth(); x++) {
        for(int y = 0; y < dstView.getImgHeight(); y++) {

            int dstX = x;
            int dstY = y;

            // center of dst image
            double centerX = (dstView.getImgWidth() - 1) / 2.0;
            double centerY = (dstView.getImgHeight() - 1) / 2.0;

            // difference between center and point
            double diffX = centerX - dstX;
            double diffY = centerY - dstY;
            // distance or radius of dst image
            double dstR = Math.sqrt(diffX * diffX + diffY * diffY);

            // distance or radius of src image (with formula)
            double srcR = (paramA * dstR * dstR * dstR + paramB * dstR * dstR + paramC * dstR + paramD) * dstR;

            // comparing old and new distance to get factor
            double factor = Math.abs(dstR / srcR);
            // coordinates in source image
            double srcXd = centerX + (diffX * factor);
            double srcYd = centerY + (diffX * factor);

            // no interpolation yet (just nearest point)
            int srcX = (int)srcXd;
            int srcY = (int)srcYd;

            if(srcX >= 0 && srcY >= 0 && srcX < dstView.getImgWidth() && srcY < dstView.getImgHeight()) {

                int dstPos = dstY * dstView.getImgWidth() + dstX;
                pixels[dstPos] = pixelsCopy[srcY * dstView.getImgWidth() + srcX];
            }
        }
    }

    return pixels;
}

Meine Fragen sind:
1) Ist diese Formel korrekt?
2) Habe ich einen Fehler gemacht, als ich diese Formel in eine Software verwandelt habe?
3) Es gibt andere Algorithmen (z.Wie simuliert man den Effekt eines Fischaugenobjektivs mit openCV? oder wiki / Distortion_ (Optik)), sind sie besser?

Danke für Ihre Hilfe!

Antworten auf die Frage(4)

Ihre Antwort auf die Frage