Bonsoir,
je travaille actuellement (dans le cadre des TIPE, je suis étudiant en spé) sur un programme de compression fractale d'images en ocaml. Je programme actuellement l'algorithme le plus "naïf" qui puisse exister avant de passer à des choses plus poussées (arbres, réseaux de neurones...), et j'arrive à la fin.
Pour rappeler brièvement le principe, il s'agit de trouver des parties qui se ressemblent dans les images, pour cela on constitue 2ensembles, un ensemble de départ (les "Di", i etant un indice) et un ensemble d'arriver (les "Ri", idem). Le but est de trouver pour chaque élément de l'ensemble d'arrivé (Ri) l'élément de l'ensemble de départ (Di) qui lui soit le plus proche (au sens d'une distance préalablement définie).
Pour ce faire, dans l'algorithme programmé, on compare chaque élément de l'ensemble de départ aux 8 isométries (nos éléments sont des carrés) de chaque élément de l'ensemble d'arrivée, apres avoir préalablement effectué une opération de contrastage adéquate, et l'on répertorie ces distances dans un tableau final.
Le problème ce situe là exctement : la fonction qui crée cette matrice (car c'en est une) laisse des "cases vides". Si quelqu'un a une idée... je m'arrache les cheveux depuis quelques temps déjà dessus.
Voilà la fonction en question :
Quelques explications :
Code : 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 let compare n ensemble_ri ensemble_di = let nvx_di = resize_di ensemble_di in let result = make_array2D 8 nbri (0.,0,(0.,0.)) in let d = ref (foi max_int) in for i = 0 to (nbri-1) do for j = 0 to 7 do for k = (((n-1)*nbdiv)/10) to ((n*nbdiv)/10 - 1) do let (s,o) = minimise j nvx_di.(k) ensemble_ri.(i) in let distance = dist.(j) (s,o) nvx_di.(k) ensemble_ri.(i) in if !d > distance then begin d:=distance; (result,i,j) <== (!d,k,(s,o)); end done; done; done; result;;
- les éléments des ensembles sont des images considérées comme des tableaux de points.
Code : Sélectionner tout - Visualiser dans une fenêtre à part type point = {x:float; y:float; z:int};; (*z est le niveau de gris*)- l'indice n dans la boucle vient du fait de l'extrême lenteur du programme (plusieurs heures...) et permet de le faire tourner par "petits bouts".
- la fonction resize permet simplement de mettre les Di à la taille des Ri, ceux ci étant plus grands
- la fonctin make_array2D crée un élément de type :
une matrice qui contient ses dimensions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part type 'a array2D = {mutable l:int; mutable h:int; mutable m: 'a array};; (* l=largeur, h=hauteur, m=matrice *)- les fonctions (<==) et (==>) correspondent à . et (<-) pour le type array2D
- minimise renvoi un couple d'arguments relatifs à la modification de contraste.
- dist est un tableau de fonctions de distances pour comparer deux images ; elles représentent la même distance mais parcourent les tableaux différement pour ne pas avoir à créer les 8 isométries pour élément de l'ensemble d'arrivée.
- dans minimise et dist, l'argument j est relatif a l'isométrie utilisée.
Enfin voilà le résultat que me donne ocaml :
Code : 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 val distances_1 : (float * int * (float * float)) array2D = {l = 8; h = 256; m = [|(1837.7342502382164, 1068, (-0.391495902739304, 244.02251712247994)); (291.4579768289891, 954, (-0.25382715282694412, 217.67660388802841)); (158.45695204940708, 1260, (-0.10027961452777623, 184.22643549835834)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (119.88876626215378, 761, (-0.074536402037438776, 179.37773960370492)); (0., 0, (0., 0.)); (33.358573672923484, 954, (-0.069710805193329631, 214.877416080155)); (1772.6080616405955, 1020, (0.36380218370732209, 155.20730250285166)); (0., 0, (0., 0.)); (137.51816702819963, 142, (0.15595973079704098, 148.8907614439068)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (118.88483261873802, 771, (-0.064263054363027233, 177.34547825572159)); (0., 0, (0., 0.)); (30.08391824429351, 800, (0.0708221806709118, 198.76268753249187)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (112.37994194191872, 112, (-0.19982617090941432, 200.47882574488057)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (21.418990720563656, 373, (-0.08941144795550951, 216.88315759437529)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., 0, (0., 0.)); (0., ...); ...|]}
PS : si besoin je peux fournir d'autres parties du code, celui ci étant relativement important j'ai préféré vous éviter des fonctions inutiles. Si vous voulez l'intégralité du code, je préfère l'envoyer par mp, pour de simples raisons de confidentialité dans le cadre des TIPE...
Merci d'avance et bonne soirée
Partager