Perspektivische Korrektur



  • Hallo,

    ich möchte ein perspektisch verzerrtes Bild, wieder zurücktransformieren.
    Dazu hab ich folgenden Algorithmus verwendet wie er hier auf Seite 13 beschrieben ist. Komischerweise habe ich wohl irgendwo noch einen Fehler drin, denn bei mir wird fast gar nichts angezeigt.
    http://www.grefab.de/dl/publications/fabritius_interaktive_bildrekonstruktion_mit_perspektivischer_korrektur.pdf

    float[,] src = { { 53, 136 }, { 392, 137 }, { 29, 285 }, { 422, 290 } };
                float[,] dst = { { 33, 0 }, { 412, 0 }, { 33, 300 }, { 412, 300 } };
    
                //float[,] src = { { coordImage[0, 0], coordImage[0, 1] }, { coordImage[1, 0], coordImage[1, 1] }, 
                //                 { coordImage[2, 0], coordImage[2, 1] }, { coordImage[3, 0], coordImage[3, 1] } };
                //float[,] dst = { { coordImage[0, 0]-5, coordImage[0, 1]-5 }, { coordImage[1, 0], coordImage[0, 1] -5}, 
                //                 { coordImage[0, 0]-5, coordImage[2, 1]+5 }, { coordImage[3, 0]+5,coordImage[0, 1] -5 } };
    
                Sparse2DMatrix<int, int, double> mat = new Sparse2DMatrix<int, int, double>();//{{3,2 ,-1},{2,-2, 4},{-1,0.5,-1} };
                SparseArray<int, double> bVector = new SparseArray<int, double>();
                SparseArray<int, double> xVector = new SparseArray<int, double>();
    
                const int numberEquations = 8;
                int xCoord=0;
                int yCoord=0;
                int homCoord;
    
                //Stelle Gleichungssystem auf
                for (int i = 0; i < 4; i++)
                {
                    mat[i, 0] = src[i, 0];
                    mat[i, 1] = src[i, 1];
                    mat[i, 2] = 1;
                    mat[i, 3] = mat[i, 4] = mat[i, 5] = 0;
                    mat[i, 6] = -src[i, 0] * dst[i, 0];
                    mat[i, 7] = -dst[i, 0] * src[i, 1];
                    //mat[i, 8] = dst[i, 0];
    
                    mat[i + 4, 0] = mat[i + 4, 1] = mat[i + 4, 2] = 0;
                    mat[i + 4, 3] = src[i, 0];
                    mat[i + 4, 4] = src[i, 1];
                    mat[i + 4, 5] = 1;
                    mat[i + 4, 6] = -dst[i, 1] * src[i, 0];
                    mat[i + 4, 7] = -dst[i, 1] * src[i, 1]; 
    
                    bVector[i] = dst[i,0] ;
                    bVector[i + 4] = dst[i, 1];
                }
                //Löse Gleichungssystem
                LinearEquationSolver.Solve(numberEquations, mat, bVector, xVector);
    
                int width  = originalImage.Width;
                int height = originalImage.Height;
    
                newImage = new Bitmap(700, 700);
                Color col = new Color();
    
                //Baue 3x3 Matrix auf
                CSML.Matrix mat1 = new CSML.Matrix(3,3);
                mat1[1, 1] = new CSML.Complex(xVector[0]);
                mat1[1, 2] = new CSML.Complex(xVector[1]);
                mat1[1, 3] = new CSML.Complex(xVector[2]);
    
                mat1[2, 1] = new CSML.Complex(xVector[3]);
                mat1[2, 2] = new CSML.Complex(xVector[4]);
                mat1[2, 3] = new CSML.Complex(xVector[5]);
    
                mat1[3, 1] = new CSML.Complex(xVector[6]);
                mat1[3, 2] = new CSML.Complex(xVector[7]);
                mat1[3, 3] = new CSML.Complex(xVector[8]);
    
                //Berechne Inverse der Matrix
                CSML.Matrix matInv = mat1.Inverse();
    
                //Multipliziere mit inverser Matrix und erhalte ursprüngliche Pixel zurück
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0 ; j < height; j++)
                    {
                        col = originalImage.GetPixel(i, j);
                        //Matrix Multiplication
                        homCoord = (int)(matInv[3, 1].Re * i + matInv[3, 2].Re * j + /*matInv[3,3].Re*/ 0 * 1);
                        xCoord = (int)((matInv[1, 1].Re * i + matInv[1, 2].Re * j + matInv[1, 3].Re * 1) /*/ homCoord*/);
                        yCoord = (int)((matInv[2, 1].Re * i + matInv[2, 2].Re * j + matInv[2, 3].Re * 1) /*/ homCoord*/);
                    }
    
                     newImage.SetPixel(xCoord, yCoord, col);
                }
                //Weise PictureBox neues Bild zu
                pictureBox2.Image = newImage;
            }
    


  • Wär echt cool wenn sich jemand mal den Code anschauen könnte. Irgendwas ist wohl noch falsch. In diesem Dokument ist der Algorithmus auch nochmal beschrieben.

    Siehe ab Seite 13

    http://www.gm.fh-koeln.de/~konen/WPF-BV/BV08.PDF



  • Also nochmal das ist mein Algorithmus, der irgendwie noch nciht geht.
    Eigentlich sollte das simple sein.

    //Koordinaten Paare Bild
                float[,] src = { { 53, 136 }, { 392, 137 }, { 29, 285 }, { 422, 290 } };
                float[,] dst = { { 33, 0 }, { 412, 0 }, { 33, 300 }, { 412, 300 } };
    
                //float[,] src = { { coordImage[0, 0], coordImage[0, 1] }, { coordImage[1, 0], coordImage[1, 1] }, 
                //                 { coordImage[2, 0], coordImage[2, 1] }, { coordImage[3, 0], coordImage[3, 1] } };
    
                //float[,] dst = { { coordImage[2, 0], coordImage[0, 1] }, { coordImage[3, 0], coordImage[1, 1] }, 
                //                 { coordImage[2, 0], coordImage[2, 1] }, { coordImage[3, 0],coordImage[3, 1]  } };
    
                Sparse2DMatrix<int, int, double> mat = new Sparse2DMatrix<int, int, double>();//{{3,2 ,-1},{2,-2, 4},{-1,0.5,-1} };
                SparseArray<int, double> bVector = new SparseArray<int, double>();
                SparseArray<int, double> xVector = new SparseArray<int, double>();
    
                const int numberEquations = 8;
                double xCoord=0;
                double yCoord = 0;
                double homCoord = 0;
    
                //Stelle Gleichungssystem auf
                for (int i = 0; i < 4; i++)
                {
                    mat[i, 0] = src[i, 0];
                    mat[i, 1] = src[i, 1];
                    mat[i, 2] = 1;
                    mat[i, 3] = mat[i, 4] = mat[i, 5] = 0;
                    mat[i, 6] = -src[i, 0] * dst[i, 0];
                    mat[i, 7] = -dst[i, 0] * src[i, 1];
                    //mat[i, 8] = dst[i, 0];
    
                    mat[i + 4, 0] = mat[i + 4, 1] = mat[i + 4, 2] = 0;
                    mat[i + 4, 3] = src[i, 0];
                    mat[i + 4, 4] = src[i, 1];
                    mat[i + 4, 5] = 1;
                    mat[i + 4, 6] = -dst[i, 1] * src[i, 0];
                    mat[i + 4, 7] = -dst[i, 1] * src[i, 1]; 
    
                    bVector[i] = dst[i,0] ;
                    bVector[i + 4] = dst[i, 1];
                }
                //Löse Gleichungssystem
                LinearEquationSolver.Solve(numberEquations, mat, bVector, xVector);
    
                int width  = originalImage.Width;
                int height = originalImage.Height;
    
                newImage = new Bitmap(width, height);
                Color col = new Color();
    
                //Baue 3x3 Matrix auf
                CSML.Matrix mat1 = new CSML.Matrix(3,3);
                mat1[1, 1] = new CSML.Complex(xVector[0]);
                mat1[1, 2] = new CSML.Complex(xVector[1]);
                mat1[1, 3] = new CSML.Complex(xVector[2]);
    
                mat1[2, 1] = new CSML.Complex(xVector[3]);
                mat1[2, 2] = new CSML.Complex(xVector[4]);
                mat1[2, 3] = new CSML.Complex(xVector[5]);
    
                mat1[3, 1] = new CSML.Complex(xVector[6]);
                mat1[3, 2] = new CSML.Complex(xVector[7]);
                mat1[3, 3] = new CSML.Complex(xVector[8]);
    
                //Berechne Inverse der Matrix
                CSML.Matrix matInv = mat1.Inverse();
    
                //Multipliziere mit inverser Matrix und erhalte ursprüngliche Pixel zurück
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0 ; j < height; j++)
                    {
                        col = originalImage.GetPixel(i, j);
                        //Matrix Multiplication
                        homCoord = (matInv[3, 1].Re * i + matInv[3, 2].Re * j + matInv[3,3].Re * 1);
                        xCoord = ((matInv[1, 1].Re * i + matInv[1, 2].Re * j + matInv[1, 3].Re * 1) / homCoord);
                        yCoord = ((matInv[2, 1].Re * i + matInv[2, 2].Re * j + matInv[2, 3].Re * 1) / homCoord);
    
                        if (homCoord != 0)
                        {
                            xCoord = xCoord / -homCoord;
                            yCoord = yCoord / -homCoord;
                        }
                        if(xCoord>0 && yCoord < height)
                        newImage.SetPixel((int)xCoord,(int) yCoord, col);
                    }
                }
                //Weise PictureBox neues Bild zu
                pictureBox2.Image = newImage;
    


  • Wäre echt cool wenn sich eine mal kurz Zeit nehmen könnte und das anzuschauen.
    Muss das nämlich nächste Woche abgeben 😞



  • Das Problem ist mittlerweile gelöst. Dieses Forum war auch schon mal besser. Keine Kritik. Aber ein Kollege hat das im Nu gehabt 🙂



  • Ein Forum ist genau dann Scheisse wenn mir bei meinem so wichtigen Problem keiner geholfen hat ... ich sage es zwar nicht offen, deute es aber an.


Log in to reply