Salut!
Voici ma première contribution, il s'agit d'une procédure écrite en C++ qui applique une transformation affine sur une image. Je remercie Flo et Pseudocode pour les précisions qu'ils m'ont apportées dans le Forum Traitement d'image.
Je me permet d'ajouter une citation que j'aime bien concernant l'origine du mot "transformation affine" :
Paramètres de la procédures :C’est Euler, en 1748, qui est à l’origine du terme « transformation affine », car dit-il, « deux courbes images l’une de l’autre par une telle transformation présentent entre elles une certaine affinité ».
Source :WIKIPEDIA/APPLICATION AFFINE
- Dest : l'image Transformée.
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 void AffineTransformation(TColor **dest,TColor **source,float (*T)[3],byte InterpolationOrder)
- Source : L'image en entrée.
- T : Matrice de transformation affine (3*3).
-InterpolationOrder : indique le type d'interpolation utilisé :
InterpolationOrder=0 ==> Interpolation au plus proche voisin.
InterpolationOrder=1 ==> Interpolation Bilinéaire.
Corps de la procédure AffineTransformation :
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 void AffineTransformation(TColor **dest,TColor **source,float (*T)[3],byte InterpolationOrder) { //Elements de la matrice de transformation T. float a,b,c,d,e,f,g,h,i; //Elements de la matrice de transformation inverse T1 float a1,b1,c1,d1,e1,f1,g1,h1,i1; //matrice de transformation Inverse float T1[3][3]; //Determinant de T float det; a=T[0][0]; b=T[0][1]; c=T[0][2]; d=T[1][0]; e=T[1][1]; f=T[1][2]; g=T[2][0]; h=T[2][1]; i=T[2][2]; // T = // a b c // d e f // g h i //Calcul du determinent de T det=a*((e*i)-(f*h)); det = det - (b*((d*i)-(f*g))); det = det + (c*((d*h)-(e*g))); if (det==0) {exit;} //Transformation Impossible, le Déterminant est nul} //calcul des éléments de la Matrice de //transformation inverse : T1 a1= ((e*i)-(f*h))/det; b1= ((c*h)-(b*i))/det; c1= ((b*f)-(c*e))/det; d1= ((f*g)-(d*i))/det; e1= ((a*i)-(c*g))/det; f1= ((c*d)-(a*f))/det; g1= ((d*h)-(e*g))/det; h1= ((b*g)-(a*h))/det; i1= ((a*e)-(b*d))/det; T1[0][0]=a1; T1[0][1]=b1; T1[0][2]=c1; T1[1][0]=d1; T1[1][1]=e1; T1[1][2]=f1; T1[2][0]=g1; T1[2][1]=h1; T1[2][2]=i1; //Matrice de transformation Inverse T1 // T1 = // a1 b1 c1 // d1 e1 f1 // g1 h1 i1 TColor couleur; TPoint p; for (int x=0;x<out_w;x++) { for (int y=0;y<out_h;y++) { p.x=x; p.y=y; couleur=GetAntecedentColor(p,T1,InterpolationOrder,source); dest[x][y]=couleur; } } }
Corps de la fonction GetAntecedentColor
Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 TColor GetAntecedentColor(TPoint p,float (*t)[3],Byte InterpolationOrder,TColor **source) { TPoint pnt; pnt.x=(t[0][0]*p.x)+(t[0][1]*p.y)+t[0][2]; pnt.y=(t[1][0]*p.x)+(t[1][1]*p.y)+t[1][2]; if((pnt.x<0)||(pnt.y<0)||(pnt.x>=in_w)||(pnt.y>=in_h)) { return clBlack; exit; } if(InterpolationOrder==0) { pnt.x=RoundTo(pnt.x,0); pnt.y=RoundTo(pnt.y,0); return (source[pnt.x][pnt.y]); } if(InterpolationOrder==1) { TPoint p1,p2,p3,p4; p1.x=RoundTo(pnt.x,0); p1.y=RoundTo(pnt.y,0); p2.x=p1.x+1; p2.y=p1.y; p3.x=p1.x; p3.y=p1.y+1; p4.x=p1.x+1; p4.y=p1.y+1; byte r,g,b; r=RoundTo(abs((pnt.x-p1.x)*(pnt.y-p1.y))*GetRValue(source[p1.x][p1.y]),0); r=RoundTo(r+abs((pnt.x-p2.x)*(pnt.y-p2.y))*GetRValue(source[p2.x][p2.y]),0); r=RoundTo(r+abs((pnt.x-p3.x)*(pnt.y-p3.y))*GetRValue(source[p3.x][p3.y]),0); r=RoundTo(r+abs((pnt.x-p4.x)*(pnt.y-p4.y))*GetRValue(source[p4.x][p4.y]),0); g=RoundTo(abs((pnt.x-p1.x)*(pnt.y-p1.y))*GetGValue(source[p1.x][p1.y]),0); g=RoundTo(g+abs((pnt.x-p2.x)*(pnt.y-p2.y))*GetGValue(source[p2.x][p2.y]),0); g=RoundTo(g+abs((pnt.x-p3.x)*(pnt.y-p3.y))*GetGValue(source[p3.x][p3.y]),0); g=RoundTo(g+abs((pnt.x-p4.x)*(pnt.y-p4.y))*GetGValue(source[p4.x][p4.y]),0); b=RoundTo(abs((pnt.x-p1.x)*(pnt.y-p1.y))*GetBValue(source[p1.x][p1.y]),0); b=RoundTo(b+abs((pnt.x-p2.x)*(pnt.y-p2.y))*GetBValue(source[p2.x][p2.y]),0); b=RoundTo(b+abs((pnt.x-p3.x)*(pnt.y-p3.y))*GetBValue(source[p3.x][p3.y]),0); b=RoundTo(b+abs((pnt.x-p4.x)*(pnt.y-p4.y))*GetBValue(source[p4.x][p4.y]),0); return RGB(r,g,b); } }
La fonction GetAntecedentColor prend en paramètre un point p de l'image destination et retourne la couleur de l'antécédent du point p dans l'image source suivant, le type d'interpolation(InterpolationOrder) et la transformation inverse (T1).
Exemple :
- Source :
- T:
Cisaillement (Shearing) sur l'axe x : Sh = -0.8.
Translation sur l'axe x : Tx = 140.
- Dest :
Au cas où ça intéresserait quelqu'un, le programme exécutable est MEGAUPLOAD - The leading online storage and file delivery service@@AMEPARAM@@Filename:</font> <font style="font-family:arial; color:#FF6700; font-size:22px; font-weight:bold;">Project1.exe@@AMEPARAM@@Project1.exe , cependant l'ihm est pourrie )
Toutes question,suggestion ou correction serait la bienvenue.
Partager