Calibration de caméra modèle sténopé, approche linéaire/non linéaire

drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009 - 7 mai 2009 à 15:03
drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009 - 7 mai 2009 à 15:23

4 réponses

drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009
7 mai 2009 à 15:05
Bonjour à tous,
Je suis actuellement sur un stage dont l'objet est entre autres de réaliser la calibration d'une caméra. Je cherche donc à extraire les paramètres intrinsèques et extrinsèques de la caméra. J'ai opté pour le modèle de sténopé et je pense avoir à peu près réussi l'approche linéaire puisque j'obtiens des résultats cohérents, bien que sujets à une erreur venant des distorsions subies par la lentille. Afin de corriger cette erreur, j'ai donc essayé d'implémenter une méthode non linéaire prenant en compte la distorsion radiale et tangentielle et visant à minimiser une erreur.
Mon vecteur d'erreur pouvant donc s'écrire de la façon suivante :
V=L-A*DeltaPhi ou L est le vecteur d'erreur courant, A le jacobien du système autour de la valeur du critère courante et DeltaPhi la correction à déterminer.
On en déduit DeltaPhi de la facon suivante :
DeltaPhi=((At*A)^-1)*(At*L) où At=transposée de A

Ce système itératif vise à réinjecter la correction dans le vecteur du critère courant jusqu'à la convergence du système. Cependant Mon système ne converge pas mais diverge et je n'arrive pas à trouver la source de mon erreur.

J'espère que vous pourrez m'apporter une aide quelconque et je vous joins mon code ci après,
merci d’avance
0
drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009
7 mai 2009 à 15:05
package calibration;

public class Calibration {

public static double[][] ParamIntr=new double[3][4];
public static double[][] ParamExtr=new double[4][4];
public static double[][] M=new double[3][4];
public static double[][] DeltaPhitemp;
public static double[][] Deltaphi;

public static double[] CalibrationInit(double[][] Coord3D,double[][] Coord2D)
{
//On a déterminé 6 points expérimentaux de coordonnées Xw,Yw,Zw en 3D et u,v en pixel sur l'image 2D

double[] tabAretourner=new double[10];
double[][] tab=new double[2*Coord3D.length][11];
double[][] tab1=new double[2*Coord3D.length][1];
//On va resoudre un pb de la forme Ax=B grace a la SVD
//On ecrit B
for(int i=0;i1);//J'ai défini ici un seuil d'erreur fixé arbitrairement
}

public static void main(String[] args)
{
// On cree les tableaux de coord 3D et ses correspondances 2D, tableaux déterminés manuellement

double[][] Coord3D={{30,24,0},{59,24,0},{88,24,0},{117,24,0},{146,24,0},
{30,63.5,0},{59,63.5,0},{88,63.5,0},{117,63.5,0},{146,63.5,0},
{30,102,0},{59,102,0},{88,102,0},{117,102,0},{146,102,0},
{30,140.5,0},{59,140.5,0},{88,140.5,0},{117,140.5,0},{146,140.5,0},
{30,147,30},{59,147,30},{88,147,30},{117,147,30},{146,147,30},
{30,147,69},{59,147,69},{88,147,69},{117,147,69},{146,147,69}};/*,
{30,147,103},{59,147,103},{88,147,103},{117,147,103},{146,147,103}};*/
double[][] Coord2D={{533,80},{539,162},{544,246},{547,333},{548,421},
{490,60},{493,150},{497,244},{503,339},{509,436},
{433,37},{434,137},{440,239},{445,346},{445,454},
{367,6},{367,119},{369,234},{371,353},{374,476},
{282,26},{286,131},{289,240},{291,350},{293,465},
{217,55},{221,149},{227,246},{226,345},{228,446}};/*,
{173,79},{172,164},{174,251},{175,340},{178,431}};*/

//On lance la premiere determination des param
double[] ParamInit1=CalibrationInit(Coord3D,Coord2D);

// On affiche la mat intrinsèque ainsi créée
System.out.println("Matrice Intrinsèque :"+'\n');
Jama.Matrix MatInt=new Jama.Matrix(ParamIntr);
MatInt.print(2, 2);

// On affiche la mat extrinsèque ainsi créée
System.out.println("Matrice Extrinsèque :"+'\n');
Jama.Matrix MatExt=new Jama.Matrix(ParamExtr);
MatExt.print(2, 2);
/*
// On affiche la matrice Mint*Mext

System.out.println("Matrice Mint*Mext :");
Jama.Matrix MintMext=MatInt.times(MatExt);
MintMext.print(5, 3);

//On crée un point réel pour vérifier sa correspondance 2D

double[][] PointReel={{34},{24},{0},{1}};
Jama.Matrix PtReel=new Jama.Matrix(PointReel);
MintMext.times(PtReel).print(2, 2);
*/
//On lance la fonction de calibrage
CalibrationFinale(ParamInit1,Coord3D,Coord2D);
}

}
0
drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009
7 mai 2009 à 15:22
package calibration;

public class Calibration {

public static double[][] ParamIntr=new double[3][4];
public static double[][] ParamExtr=new double[4][4];
public static double[][] M=new double[3][4];
public static double[][] DeltaPhitemp;
public static double[][] Deltaphi;

public static double[] CalibrationInit(double[][] Coord3D,double[][] Coord2D)
{
//On a déterminé 6 points expérimentaux de coordonnées Xw,Yw,Zw en 3D et u,v en pixel sur l'image 2D

double[] tabAretourner=new double[10];
double[][] tab=new double[2*Coord3D.length][11];
double[][] tab1=new double[2*Coord3D.length][1];
//On va resoudre un pb de la forme Ax=B grace a la SVD
//On ecrit B
for(int i=0;i<Coord3D.length;i++)
{
tab1[2*i][0]=Coord2D[i][0];
tab1[2*i+1][0]=Coord2D[i][1];
}
//On ecrit A
for(int i=0;i<Coord3D.length;i++)
{
tab[2*i][0]=Coord3D[i][0];
tab[2*i][1]=Coord3D[i][1];
tab[2*i][2]=Coord3D[i][2];
tab[2*i][3]=1;
tab[2*i][4]=0;
tab[2*i][5]=0;
tab[2*i][6]=0;
tab[2*i][7]=0;
tab[2*i][8]=-Coord2D[i][0]*Coord3D[i][0];
tab[2*i][9]=-Coord2D[i][0]*Coord3D[i][1];
tab[2*i][10]=-Coord2D[i][0]*Coord3D[i][2];
tab[2*i+1][0]=0;
tab[2*i+1][1]=0;
tab[2*i+1][2]=0;
tab[2*i+1][3]=0;
tab[2*i+1][4]=Coord3D[i][0];
tab[2*i+1][5]=Coord3D[i][1];
tab[2*i+1][6]=Coord3D[i][2];
tab[2*i+1][7]=1;
tab[2*i+1][8]=-Coord2D[i][1]*Coord3D[i][0];
tab[2*i+1][9]=-Coord2D[i][1]*Coord3D[i][1];
tab[2*i+1][10]=-Coord2D[i][1]*Coord3D[i][2];
}

//on déclare une matrice correspondant aux tableaux precedents

Jama.Matrix A=new Jama.Matrix(tab);
Jama.Matrix B=new Jama.Matrix(tab1);

//on fait une decmposition en valeurs propres

Jama.SingularValueDecomposition D= A.svd();
Jama.Matrix U=D.getU();
Jama.Matrix V=D.getV();
Jama.Matrix S=D.getS();

//La pseudo inverse de X est le vecteur solution
Jama.Matrix X=((V.times(S.inverse())).times(U.transpose())).times(B);
X.print(2, 2);
double[][] VPr=X.getArray();

double m11=VPr[0][0],m12=VPr[1][0],m13=VPr[2][0],m14=VPr[3][0],
m21=VPr[4][0],m22=VPr[5][0],m23=VPr[6][0],m24=VPr[7][0],
m31=VPr[8][0],m32=VPr[9][0],m33=VPr[10][0],m34=1;

//On remplit la matrice M
for(int i=0;i<2;i++)
{
for(int j=0;j<4;j++) M[i][j]=VPr[4*i+j][0];
}
Jama.Matrix MatM=new Jama.Matrix(M);
MatM.print(2, 2);


//il ne reste plus qu'à remplir les matrices intrinsèques et extrinsèques

for(int i=0;i1);//J'ai défini ici un seuil d'erreur fixé arbitrairement
}


public static void main(String[] args)
{
// On cree les tableaux de coord 3D et ses correspondances 2D, tableaux déterminés manuellement

double[][] Coord3D={{30,24,0},{59,24,0},{88,24,0},{117,24,0},{146,24,0},{30,63.5,0},{59,63.5,0},{88,63.5,0},{117,63.5,0},{146,63.5,0},{30,102,0},{59,102,0},{88,102,0},{117,102,0},{146,102,0},{30,140.5,0},{59,140.5,0},{88,140.5,0},{117,140.5,0},{146,140.5,0},{30,147,30},{59,147,30},{88,147,30},{117,147,30},{146,147,30},{30,147,69},{59,147,69},{88,147,69},{117,147,69},{146,147,69},{30,147,103},{59,147,103},{88,147,103},{117,147,103},{146,147,103}};


double[][] Coord2D={{533,80},{539,162},{544,246},{547,333},{548,421},{490,60},{493,150},{497,244},{503,339},{509,436},{433,37},{434,137},{440,239},{445,346},{445,454},{367,6},{367,119},{369,234},{371,353},{374,476},{282,26},{286,131},{289,240},{291,350},{293,465},{217,55},{221,149},{227,246},{226,345},{228,446},{173,79},{172,164},{174,251},{175,340},{178,431}};

//On lance la premiere determination des param
double[] ParamInit1=CalibrationInit(Coord3D,Coord2D);

// On affiche la mat intrinsèque ainsi créée
System.out.println("Matrice Intrinsèque :"+'\n');
Jama.Matrix MatInt=new Jama.Matrix(ParamIntr);
MatInt.print(2, 2);

// On affiche la mat extrinsèque ainsi créée
System.out.println("Matrice Extrinsèque :"+'\n');
Jama.Matrix MatExt=new Jama.Matrix(ParamExtr);
MatExt.print(2, 2);
/*
// On affiche la matrice Mint*Mext

System.out.println("Matrice Mint*Mext :");
Jama.Matrix MintMext=MatInt.times(MatExt);
MintMext.print(5, 3);

//On crée un point réel pour vérifier sa correspondance 2D

double[][] PointReel={{34},{24},{0},{1}};
Jama.Matrix PtReel=new Jama.Matrix(PointReel);
MintMext.times(PtReel).print(2, 2);
*/
//On lance la fonction de calibrage
CalibrationFinale(ParamInit1,Coord3D,Coord2D);
}

}
0
drillerdolls Messages postés 8 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 7 mai 2009
7 mai 2009 à 15:23
Désolé pour le cafouillage j'ai pas l'habitude de poster des mais bon le tout c'ets d'y arriver. :) Si vous avez des questions n'hésitez pas à me les poser.
0
Rejoignez-nous