EP07_05 — 🔴 Histogramme des orientations d’une cellule HOG
7.18.5 EP07_05 🔴 Histogramme des orientations d’une cellule HOG
La fonction hog de scikit-image, utilisée dans le projet de classification de chiffres, divise l’image en petites cellules et, pour chacune, construit un histogramme des orientations du gradient pondéré par la magnitude — exactement l’étape centrale décrite dans la section sur le descripteur HOG du chapitre.
Vous êtes chargé d’implémenter ce calcul pour une seule cellule, à partir des valeurs de magnitude et d’orientation du gradient déjà calculées pour chaque pixel de la cellule (ce qui évite le calcul des dérivées partielles).
7.18.5.1 📋 Directives d’implémentation
Dimensions : Lire les entiers \(n\) (la cellule a \(n \times n\) pixels) et \(B\) (nombre de compartiments de l’histogramme).
Magnitudes : Lire \(n\) lignes avec chacune \(n\) valeurs réelles, représentant \(|\nabla f(x,y)|\) pour chaque pixel de la cellule.
Orientations : Lire encore \(n\) lignes avec chacune \(n\) valeurs réelles, représentant \(\theta(x,y)\) en degrés, déjà converties dans l’intervalle non signé\([0^\circ, 180^\circ)\), comme conventionnellement utilisé par le HOG.
Compartiments : Les \(B\) compartiments couvrent \([0^\circ, 180^\circ)\) en bandes égales de largeur \(180/B\) degrés. Un pixel avec une orientation \(\theta\) appartient au compartiment \(\lfloor \theta / (180/B) \rfloor\) ; si cet indice est égal à \(B\) (possible uniquement lorsque \(\theta\) est exactement \(180^\circ\), ce qui ne devrait pas se produire selon la directive du point 3), utilisez le compartiment \(B-1\).
Histogramme brut : Pour chaque pixel, accumulez sa magnitude (et non son compte) dans le compartiment correspondant : \[
H[b] = \sum_{(x,y)\, :\, \text{bin}(\theta(x,y)) = b} |\nabla f(x,y)|.
\]
Normalisation L2 : Après avoir construit \(H\), normalisez-le pour obtenir \(\hat H\) : \[
\hat H[b] = \frac{H[b]}{\sqrt{\sum_{j=0}^{B-1} H[j]^2 + \epsilon}}, \qquad \epsilon = 10^{-6}.
\]
Sortie : Imprimez l’histogramme brut \(H\) (arrondi à 2 décimales) sur une ligne, suivi de l’histogramme normalisé \(\hat H\) (arrondi à 4 décimales) sur une autre ligne, tous deux avec les \(B\) valeurs séparées par des espaces, dans l’ordre des compartiments.
7.18.5.2 📌 Contraintes computationnelles
Binning non signé : l’intervalle des orientations est \([0,180)\), pas \([0,360)\) — les gradients dans des directions opposées (différence de \(180^\circ\)) contribuent au même compartiment, convention standard du HOG pour la détection d’objets.
Accumulation par magnitude, pas par compte : l’histogramme pondère chaque pixel par sa magnitude de gradient, il ne compte pas simplement combien de pixels tombent dans chaque compartiment.
Constante de stabilisation : le \(\epsilon = 10^{-6}\) dans le dénominateur de la normalisation évite la division par zéro lorsque la cellule est complètement homogène (toutes les magnitudes nulles).
7.18.5.3 📐 D’où proviennent les matrices d’entrée
Avant cet EP, chaque pixel \((x,y)\) de l’image passe par :
Comme le HOG ignore la polarité du contraste, l’angle est replié dans l’intervalle non signé :
\[
\theta = \theta_{\text{signé}} \bmod 180°
\]
En répétant cela pour tous les pixels d’une cellule \(n\times n\), on obtient les deux matrices d’entrée de cet exercice : les magnitudes\(|\nabla f|\) et les orientations\(\theta \in [0°,180°)\).
7.18.5.4 🧠 Fondement théorique
Étape
Rôle
Magnitude du gradient
Pondère la contribution de chaque pixel — les bords forts pèsent plus que le bruit faible
Orientation non signée
Rend le descripteur invariant à la polarité du contraste (clair→sombre vs. sombre→clair)
Histogramme par cellule
Résume la distribution locale des bords en un vecteur compact
Normalisation L2
Réduit la sensibilité du descripteur aux variations globales d’éclairage et de contraste
La concaténation des histogrammes normalisés de toutes les cellules de l’image — non implémentée dans cet exercice — forme le vecteur de caractéristiques HOG complet, utilisé comme entrée du classifieur k-NN dans le projet du chapitre.
7.18.5.5 📦 Spécification d’entrée et de sortie (VPL)
Entrée :
Ligne 1 : entiers \(n\) et \(B\).
Les \(n\) lignes suivantes : \(n\) magnitudes réelles chacune.
Ajustez B et suivez comment la matrice d'orientations (indépendante de celle des magnitudes) est mappée
vers les compartiments via bin = floor(θ / (180/B)), et comment les magnitudes sont additionnées dans chaque bin.
2
📄 Entrée (exactement comme le programme la lit via stdin)
🔢 Matrice des magnitudes |∇f|
📐 Matrice des orientations θ (degrés) — colorée par bin
📏 Où chaque θ tombe sur la règle [0°, 180°) — bin = floor(θ / largeur)
📊 Plages de chaque compartiment (largeur = 180° / B)
🧩 Chaque pixel : magnitude + orientation → bin
🧮 Calcul pas à pas (division entière + somme des magnitudes par bin)
Figure 7.25: Simulateur EP07_05 : Histogramme HOG d’une cellule (mapping des angles vers les bins)
%%writefile EP07_05.py# Code Python
Overwriting EP07_05.py
TestSuite("EP07_05.py").run()
✔️ EP07_05.cases existe déjà dans casos/
📋 5 cas chargé(s) depuis casos/EP07_05.cases
🔍 Test de Python : EP07_05.py
⚠️ EP07_05.py : fichier vide (moins de 3 lignes). Tests ignorés.