Vision tridimensionelle

TP 0 : Geométrie projective et Mathematica

Soit le modele de camera suivant (en geometrie projective):

Illustrez ce modele de camera en 3D.

Initialisation

Cette section initialise Mathematica.

Pour ne pas avoir certains message d'erreur ennuyants....

Off[General::spell1];

Fonctions de base

Dans cette section, on declare les fonction de base qui sont utilisee souvent.

Homogenize (passe de projectif a euclidien)

h[v_] := Delete[v, -1]/v[[-1]];

h[{x, y, h}]

h[{x, y, z, h}]

Extraire une sous-matrice

sousmatrice[m_, r1_, r2_, c1_, 
          c2_] := Take[#, {c1, c2}] &   /@  
          Take[m, {r1, r2}];

m = Partition[Table[i, {i, 1, 16}], 4]; m // MatrixForm

sousmatrice[m, 1, 3, 2, 4] // MatrixForm

sousmatrice[m, 1, 3, 1, 3] // MatrixForm

sousmatrice[m, 1, 3, 4, 4] // MatrixForm

Matrice de changement d'echelle 3D (4x4)

scaleMatrix[v_] := DiagonalMatrix[{v, v, v, 1}];

scaleMatrix[{sx_, sy_, sz_}] := DiagonalMatrix[{sx, sy, sz, 1}];

scaleMatrix[a] // MatrixForm

scaleMatrix[{a, b, c}] // MatrixForm

Matrice de translation 3D (4x4)

transMatrix[v_] := 
      Transpose[{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, Append[v, 1]}];

transMatrix[{a, b, c}] // MatrixForm

Matrice de rotation arbitraire 3D (4x4)

\(\(rotMatrix[a_, u_] := 
      Block[{m, s, x, y, z, nu}, 
        \((
\ \ \ \ \ \ \ \ {x, y, z} = u/Sqrt[u.u]; 
\ \ \ \ \ \ \ \ 
          s = {{0, \(-z\), y}, {z, 0, \(-x\)}, {\(-y\), x, 0}}; 

          \ \ \ \ \ \ \ \ nu = {{x}, {y}, {z}}; 
\ \ \ \ \ \ \ \ 
          m = nu.Transpose[nu] + 
              Cos[a] \((IdentityMatrix[3] - nu.Transpose[nu])\) + Sin[a] s; 

          \ \ \ \ \ \ 
\ \ \ \ \ \ \ \ 
          Join[\(Append[#, 0]&\)\ /@\ m, {{0, 0, 0, 1}}]
\ \ \ \ \ \ \ \ )
          \)]; \)\)

\({rotMatrix[a, {1, 0, 0}] // MatrixForm, 
	
      rotMatrix[a, {0, 1, 0}] // MatrixForm, 
	
      rotMatrix[a, {0, 0, 1}] // MatrixForm}\)

Matrice de parametres internes (passe de camera -> image)

Centre de l'image (cx,cy), distance focal (fx,fy)

internMatrix[cx_, cy_, fx_, fy_]
         := {{fx, 0, cx, 0}, {0, fy, cy, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};

internMatrix[128, 128, 256, 256] // MatrixForm

Projection d'un point 3D vers un point 2D

projete[{x_, y_, z_}, m_] := h[Take[m.{x, y, z, 1}, 3]];

Creation d'une systeme d'axe (x,y,z)

axes[] := axes[IdentityMatrix[4]];

\(\(axes[t_] := 
      Module[{p}, 
        \((
			
          p = {{0, 0, 0, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 1}}; 

          			q = \(\((h[t.#])\)&\)\ /@\ p; 
			
          r = \(\((h[t.scaleMatrix[{1.1, 1.1, 1.1}].#])\)&\)\ /@\ p; 
			
          Graphics3D[{
			Thickness[0.015], 
			
              Line[q[\([{1, 2}]\)]], 
			Line[q[\([{1, 3}]\)]], 
			
              Line[q[\([{1, 4}]\)]], 
			Text["X", r[\([2]\)]], 

              			Text["Y", r[\([3]\)]], 
			
              Text["Z", r[\([4]\)]]
			}]
		)\)]; \)\)

Show[axes[]];

\(\(Show[axes[], 
	
      axes[transMatrix[{1, 1, 1}].rotMatrix[Pi/4, {1, 0, 0}]], 
	
      axes[transMatrix[{2, 0, 1}].rotMatrix[
            Pi/4, {0, 1, 1}].scaleMatrix[{0.5, 0.5, 0.2}]]]; \)\)

Fonctions principales

Dans cette section, on declare les fonctions les plus importantes

Geometrie de camera

Affiche la geometrie de la camera, pour une taille d'image connue et une matrice de passage m

On "deprojete" les coins de l'image, et l'origine est directement la translation de im.
La distance entre le plan de projection et l'origine est donne par f.

\(\(geomCamera[imgx_, imgy_, f_, m_] := 
      Module[{orig, coins, cs, im}, 
        \((
			im = Inverse[m]; 
			
          orig = Flatten[sousmatrice[im, 1, 3, 4, 4]]; 
			
          coins = {{0, 0, f, 1}, {f*imgx, 0, f, 1}, {f*imgx, f*imgy, f, 1}, {
                0, f*imgy, f, 1}}; 
			
          cs = \(Take[im.#, 3]&\)\ /@\ coins; 
			
          Graphics3D[{\(Line[{orig, #}]&\)\ /@\ cs, Polygon[cs]}]
			)
          \)]; \)\)

Test

Creation de quelques points 3D a projeter

\(p = 
      Table[{
			Random[Real, {15, 25}], 
			Random[Real, {15, 25}], 
          
			Random[Real, {15, 25}]}, {i, 1, 12}]; 
p // MatrixForm\)

s0 = 
      Show[axes[scaleMatrix[10]], 
        Graphics3D[{PointSize[0.025], Point /@ p}]]

Fabrique une matrice camera m test

Pas de rotation, pas de translation
Seulement une image 256x256 (angle de vue 90 degres)

campos = {2, 2, 2};

mext = N[rotMatrix[Pi/4, {1, -1, 0}].transMatrix[-campos]]; 
    mext // MatrixForm

mint = internMatrix[100, 100, 200, 200]; mint // MatrixForm

m = mint.mext; m // MatrixForm

Inverse de m : image -> camera -> scene

im = Inverse[m]; im // MatrixForm

Projete tous les points sur le plan z=1 de la camera

\(pcam = \(Append[projete[#, m], 1]&\)\ /@\ p; 
N[pcam] // MatrixForm\)

"Deprojete" les points images vers la scene

\(pcamscene = \(\((Take[im.Append[#, 1], 3])\)&\)\ /@\ \((10*pcam)\); 

    pcamscene // MatrixForm\)

\(\(Show[s0, Graphics3D[{PointSize[0.015], Point\ /@\ pcamscene}], 
	
      Graphics3D[\(Line[{campos, #}]&\)/@\ p], 
	
      geomCamera[200, 200, 10, m], 
	PlotRange -> All, 
      ViewPoint -> {\(-0.75\), 1, 0.2}]; \)\)