Débruitage d’images par
Analyse en Composantes Principales (ACP)
Projet Java implémentant une méthode de débruitage basée sur la
décomposition en composantes principales des patches d’image.
Interface JavaFX, calcul matriciel via Apache Commons Math,
utilitaires image et pipeline expérimentaux contenus sous
src/.
But et approche
L’objectif est de concevoir et d’implémenter un algorithme de
débruitage d’images reposant sur l’Analyse en Composantes
Principales (ACP / PCA). L’idée centrale : découper l’image en
petits patchs redondants, construire une matrice où chaque ligne
représente un patch, extraire les axes principaux (vecteurs
propres) de la covariance, projeter chaque patch sur un
sous-espace de faible dimension puis reconstruire l’image à partir
des contributions retenues.
Le pipeline est conçu pour être expérimental et pédagogique :
paramètres (taille de patch, nombre de composantes, méthode de
seuillage) sont ajustables via l’interface JavaFX et le code.
Stack technique & artefacts
Stack
Java (JDK 11+ / 17+ compatible)
JavaFX (interface graphique)
Apache Commons Math 3.6.1 — calculs matriciels & décomposition
Makefile (compilation / packaging)
Bibliothèque locale :
lib/commons-math3-3.6.1.jar et jars JavaFX
Contenu du dépôt
L’application est organisée de manière modulaire :
src/core (traitement d’image et algorithmes ACP),
src/gui (interface JavaFX) et
src/main (lancement & console).
- Chargement de l’image via ImageIO (utilisé à
plusieurs endroits ; on centralise la lecture/écriture dans
Image).
- Conversion RGB → niveaux de gris (luminosité) si nécessaire ;
l’algorithme opère sur des valeurs scalaires par pixel.
2. Découpage en patches
- Les patches sont des blocs carrés extraits de l’image : méthodes
utilitaires dans core/Image.java fournissent
decoupeImage, decoupeImageEnQuatre,
decoupeImageSelonCarreParfait selon le besoin
expérimental.
- Chaque patch est encapsulé dans core/Patch.java, et
la collection de patches est manipulée via
PatchCollection.java.
- Plusieurs stratégies d’extraction sont supportées : tirage
aléatoire de patches, partition régulière (grille) ou découpage en
sous-blocs égaux. L’implémentation convertit ensuite chaque patch en
vecteur (ligne de la matrice de données).
3. Construction de la matrice & centrage
- On construit une matrice X ∈ R^{N×p} où
N est le nombre de patches et p = s × s la
dimension d’un patch aplati.
- Le centrage (soustraction de la moyenne par colonne) est effectué
via PatchCollection.moyCov(...) qui renvoie la moyenne
et la matrice de covariance.
4. Calcul de l’ACP (vecteurs propres)
- La décomposition spectrale (EigenDecomposition) est effectuée via
Apache Commons Math : méthode
OutilsMathematiques.calculerVecteursPropres(RealMatrix).
- Les vecteurs propres sont triés par valeur propre décroissante
pour capturer d’abord la variance la plus importante.
5. Projection & seuillage
- Chaque patch centré est projeté sur la base des vecteurs propres :
OutilsMathematiques.projeterContributions calcule les
contributions (coefficients α_k).
- Optionnellement, on applique un seuillage sur ces coefficients
(méthodes implémentées dans Patch /
Critere) : seuillage dur ou doux, avec critères SV
(VisuShrink) ou BayesShrink.
6. Reconstruction
- Après seuillage, on reconstruit chaque patch : somme du vecteur
moyen + combinaison linéaire des vecteurs de base pondérés par les
coefficients seuillés (implémenté dans
Image.reconctructionSeuillage ; attention: accumulation
des contributions correctement implémentée pour additionner et non
écraser les valeurs).
- Les patches reconstruits sont ensuite remis en place dans l’image
finale (PatchCollection.reconstructPatchs2 ou
Image.reconstituerImage).
7. Post-traitement & métriques
- Calcul du PSNR (Peak Signal-to-Noise Ratio) et/ou MSE entre
l’image d’origine et l’image débruitée pour évaluer la qualité.
- Affichage des courbes de variance expliquée (somme cumulée des
valeurs propres) pour aider le choix du nombre de composantes
retenues.
- Lecture/écriture d’images, conversion en matrice pixels,
fonctions d’ajout de bruit (gaussien), découpage en
imagettes (patchs) et reconstitution.
- Méthodes notables : decoupeImage(...),
decoupeImageEnQuatre(...),
decoupeImageSelonCarreParfait(...),
reconstituerImage(...), imageDEN(...),
imageDENlocale(...),
reconctructionSeuillage(...).
- Gestion des imagettes : la classe interne
Image.Imagette encapsule la sous-image et la position
(x,y) dans l’image source.
core/Patch.java
- Représente un patch sous forme d’un vecteur (tableau de doubles)
avec getters/setters pour valeurs de pixels et opérations de
seuillage (dur/doux).
- Les méthodes de seuillage sont appliquées sur les coefficients
α, et la classe fournit des utilitaires pour manipuler et
convertir les données pixels.
core/PatchCollection.java
- Container pour une collection de Patch et leurs
positions. Fournit :
extractPatches(BufferedImage, patchSize) —
extraction de patches
moyCov(PatchCollection) — calcul du vecteur moyen
et de la matrice de covariance
reconstructPatchs2(...) — algorithme pour assembler
les patches en image finale
Accesseurs : getPatches(),
getPatchPositions()
core/OutilsMathematiques.java
- Fonctions numériques : conversion collection ↔ matrice, calcul
des vecteurs propres via EigenDecomposition, tri des
vecteurs propres, conversion de matrice en
PatchCollection et projection des contributions
(projeterContributions).
- Méthode importante :
calculerVecteursPropres(RealMatrix) qui encapsule
l'appel à la décomposition spectrale d'Apache Commons Math et trie
les composantes par valeur propre.
core/Critere.java
- Implémente des critères de seuillage / détermination du seuil
lambda : par exemple seuilVisuShrink (VisuShrink) et
seuilBayesShrink (BayesShrink). Ces méthodes servent
à définir la force du seuillage appliqué aux coefficients
projetés.
src/gui/* (JavaFX)
- Interface organisée en écrans : Accueil (point
d'entrée graphique), ChoixImage (sélection d'image),
ChoixParametres (taille patchs, sigma, méthode de
seuillage), Resultat (visualisation avant/après et
métriques).
- Les actions utilisateur déclenchent le pipeline via des appels
aux classes core (ex : lancer
Image.imageDEN).
src/main/Main.java & Console.java
- Main lance l’interface JavaFX (classe
Application) ; Console permet un mode
non-GUI (scriptable) pour tests batch.
Optimisations, limites numériques et pistes d’amélioration
Complexité & mémoire
- Matrice de patches : la mémoire augmente avec
N × p (N = nb patches, p = s*s). Pour images grandes ou
patchs grands, la matrice peut devenir volumineuse. - Approche :
réduire N (sous-échantillonnage), utiliser représentation en float
ou traitements par blocs, ou effectuer une ACP économe (SVD tronqué,
méthodes incrémentales).
Performances & parallélisme
- Les étapes d'extraction de patches et de projection sont
massivement parallélisables. On peut paralléliser :
l'extraction et conversion des patches (threads pour
sous-ensembles de l'image)
la projection des patches (ExecutorService)
- Pour une version JDK moderne, utiliser
ForkJoinPool ou les Streams parallèles avec attention
sur la création d'objets temporaires.
Améliorations algorithmiques
Utiliser SVD tronqué (algorithmes itératifs) pour éviter la
factorisation complète quand seules k premières composantes sont
nécessaires.
Tester des méthodes non-linéaires (ex. RPCA, NMF) pour différents
types de bruit.
Ajouter un pipeline de validation croisée pour choisir
automatiquement k (nombre de composantes).
Robustesse & qualité
- Ajout de contrôles sur les tailles de patch et sur le recouvrement
pour éviter les erreurs d’indice dans
getSubimage.
- Logging centralisé (java.util.logging ou SLF4J) pour tracer les
erreurs d’E/S et calculs numériques.
Utilisation — exemples
Mode GUI (JavaFX)
Lancer l’application : java -jar debruitage.jar ou directement via le Makefile :
make → compile et génère les JAR dans
dist/
make run → lance l’application avec les bons
modules JavaFX
Choisir une image depuis data/ (ex.
lena.jpg)
Régler : taille de patch (ex. 7), nombre de composantes k, sigma
estimé, méthode de seuillage (Dur/Doux), critère (SV/Bayes)
Lancer le traitement et visualiser le résultat dans l’onglet
Resultat — téléchargeable en JPG
Mesures
Le programme calcule et affiche :
PSNR avant/après
MSE
Variance expliquée par k composantes (courbe cumulative)
Utilisation du Makefile
make → compile les sources et génère
GM1Groupe9_Used.jar et
GM1Groupe1_Executable.jar dans dist/
make run → exécute directement l’application
(équivalent à java -jar dist/GM1Groupe9_Used.jar)
make archive → crée une archive complète du projet
(GM1Groupe9_Archive.jar)
make clean → nettoie les répertoires
bin/ et dist/ tout en restaurant les
images de test dans data/
Visuels & artefacts
Image Lena — original vs débruité (k = 20)
Exemple de patchs extraits (size = 7)
Courbe de variance expliquée (sélection de composantes)
public class Patch {
private double[] pixels; // dimension p = s*s
// getPixel(i), setPixel(i,val)
// seuillageDur(index, lambda)
// seuillageDoux(index, lambda)
}
Extrait : calcul de la projection (schéma)
# pseudo-code (inspiré de OutilsMathematiques.projeterContributions)
for each basis vector u_i:
for each centered patch v_k:
alpha[k][i] = dot(u_i, v_k)
# alpha : contributions (N x p)
# reconstruction: v_k_hat = mean + sum_i alpha[k][i] * u_i
Critères de seuillage
- seuilVisuShrink : règle basée sur bruit et taille
d'image (valeur scalaire λ calculée, méthode classique en
ondelettes).
- seuilBayesShrink : estimation statistique bayésienne
du seuil en fonction de la variance du bruit et de la variance
estimée du signal.
Conclusion et perspectives
Le projet est un cadre flexible pour expérimenter des méthodes de
débruitage basées sur des décompositions linéaires. À l’état actuel,
la version JavaFX propose une interface complète et un pipeline
reproductible ; les axes prioritaires d’amélioration sont :
Optimisation mémoire (SVD tronqué, traitements par blocs)
Parallélisation des étapes d’extraction/projection
Ajout d’un module d’évaluation automatisée (benchmarks, PSNR sur
datasets standards)
Ajout d’un packaging Maven/Gradle et tests unitaires JUnit