v0.26 — Édition 2026. Un programme de 5 épisodes sur l'utilisation de scikit-image v0.26 (Édition 2026) comme moteur principal de prétraitement d'images et d'augmentation de données dans les pipelines modernes d'IA et de deep learning.
Traitement d'imagesScience des donnéesVision par ordinateur
Découvrez comment scikit-image représente les images sous forme de ndarrays NumPy. Apprenez pourquoi cette conception en fait le moteur de prétraitement idéal pour les frameworks de deep learning comme PyTorch et TensorFlow.
3m 46s
2
Parler le même langage : Dtypes et OpenCV
Maîtrisez les types de données d'images pour éviter les bugs silencieux les plus courants en vision par ordinateur. Apprenez à intégrer de manière transparente scikit-image avec OpenCV et les entrées de réseaux de neurones.
4m 00s
3
Contraste, exposition et robustesse de l'IA
Apprenez à utiliser l'ajustement du contraste et l'égalisation d'histogramme pour standardiser les jeux de données. Ces techniques sont cruciales pour rendre les modèles d'IA robustes face aux variations de conditions d'éclairage.
3m 41s
4
Transformations géométriques pour l'augmentation de données
Découvrez comment redimensionner les images pour les adapter aux entrées des réseaux de neurones et appliquer des transformations affines. Essentiel pour construire des pipelines robustes d'augmentation de données.
3m 47s
5
La segmentation classique pour amorcer l'IA
Découvrez comment utiliser la segmentation classique watershed pour générer automatiquement des masques d'entraînement parfaits au pixel près pour les modèles de deep learning, vous faisant ainsi gagner des heures d'étiquetage manuel.
3m 16s
Épisodes
1
Le pipeline d'images pour l'IA : NumPy au cœur
3m 46s
Découvrez comment scikit-image représente les images sous forme de ndarrays NumPy. Apprenez pourquoi cette conception en fait le moteur de prétraitement idéal pour les frameworks de deep learning comme PyTorch et TensorFlow.
Salut, c'est Alex de DEV STORIES DOT EU. scikit-image : The AI Image Pipeline, épisode 1 sur 5. Avant qu'un modèle de deep learning puisse reconnaître un visage, il doit digérer une grille de nombres. Si tu fournis cette grille dans le mauvais ordre, ton modèle n'apprend rien, et ton processing devient extrêmement lent. The AI Image Pipeline: NumPy at the Core, c'est la solution pour structurer cette grille correctement.
Quand tu charges une image avec scikit-image, tu n'obtiens pas un objet image propriétaire. Tu obtiens un array à N dimensions standard, connu sous le nom de ndarray. Une image, c'est tout simplement une matrice de pixels. Comme c'est un simple array NumPy, tu peux utiliser n'importe quelle opération standard pour slicer, masker, ou manipuler directement les données de l'image.
Voici le point clé. La façon dont scikit-image indexe ces arrays piège beaucoup de développeurs. En géométrie classique, tu utilises les coordonnées x et y, où x est l'horizontale et y la verticale. scikit-image abandonne ça pour une notation matricielle. Le premier index est la ligne, qui correspond à la position verticale. Le deuxième index est la colonne, qui correspond à la position horizontale. Si tu as une image en couleur, le troisième index est le channel de couleur. Une image en couleur standard en deux dimensions est en fait un array en trois dimensions ordonné en ligne, colonne, channel.
Supposons que tu prépares un batch d'images en couleur pour les passer à un Convolutional Neural Network. Ton réseau s'attend à une shape spécifique. Si ton image fait 256 pixels de haut et 256 pixels de large avec les channels rouge, vert et bleu, la shape d'une seule image est 256, 256, 3. Mais un batch de ces images ajoute une quatrième dimension au début, qui représente le nombre d'images.
Quand tu appliques des fonctions scikit-image à ces données, la fonction a besoin de savoir quelle dimension contient les valeurs de couleur pour ne pas les traiter comme des données spatiales. C'est géré par l'argument channel axis. En réglant l'argument channel axis sur -1, tu dis à la fonction que les channels de couleur sont toujours dans la dernière dimension de l'array. Ça garantit que la fonction cible les bonnes données de couleur, peu importe si tu lui passes une seule image ou un grand batch avec des dimensions spatiales supplémentaires.
Ce qui nous amène à la mémoire. C'est la partie qui compte pour la vitesse de processing. Les arrays NumPy sont stockés dans des blocs de mémoire contigus, en utilisant un ordre de type C par défaut. Ça veut dire que la dernière dimension dans la shape de l'array est celle qui change le plus vite dans la mémoire physique. Pour notre array d'image standard en ligne, colonne, channel, les channels de couleur individuels pour un seul pixel se trouvent juste à côté les uns des autres dans ta RAM.
Si tu écris du code custom pour boucler sur ces pixels, tu dois respecter ce memory layout. La règle est absolue : la dimension la plus à droite de ton array doit être traitée dans la boucle la plus interne. Tu itères sur les lignes dans la boucle externe, puis les colonnes, puis les channels à l'intérieur. Si tu inverses ça et que tu boucles sur les lignes à l'intérieur, tu forces le CPU à faire des allers-retours sur des adresses mémoire fragmentées. Ça détruit la cache locality et rend l'exécution de ton code beaucoup plus lente.
La chose la plus critique à retenir, c'est que scikit-image n'utilise pas de coordonnées horizontales et verticales ; il utilise un indexage matriciel strict en ligne, colonne et channel, et c'est en faisant correspondre tes boucles à cet ordre mémoire exact que tu gardes ton data pipeline rapide.
Si tu veux aider à faire vivre ce podcast, tu peux soutenir l'émission en cherchant DevStoriesEU sur Patreon. C'est tout pour aujourd'hui. Merci d'avoir écouté, et continue de développer !
2
Parler le même langage : Dtypes et OpenCV
4m 00s
Maîtrisez les types de données d'images pour éviter les bugs silencieux les plus courants en vision par ordinateur. Apprenez à intégrer de manière transparente scikit-image avec OpenCV et les entrées de réseaux de neurones.
Bonjour, c'est Alex de DEV STORIES DOT EU. scikit-image : Le pipeline d'images pour l'IA, épisode 2 sur 5. Le bug silencieux le plus courant en computer vision n'est pas dans l'architecture du réseau de neurones. C'est une incompatibilité de data type. Tu passes une image à un modèle, le code s'exécute sans renvoyer d'erreur, mais les outputs sont du grand n'importe quoi. Ça arrive quand tes librairies ne sont fondamentalement pas d'accord sur la façon dont un pixel doit être représenté numériquement. Aujourd'hui, on va régler ça en parlant le même langage : les dtypes et OpenCV.
Dans scikit-image, les images sont stockées comme des arrays numpy standards. Mais les nombres à l'intérieur de ces arrays se comportent différemment selon leur data type exact. Le format par défaut qui vient des webcams et des fichiers images standards est un entier non signé de huit bits, connu sous le nom de uint8. Ces valeurs vont de zéro à 255, où zéro est le noir absolu et 255 l'intensité maximale.
Cependant, les fonctions de traitement d'images scientifiques et les frameworks de deep learning préfèrent presque toujours les nombres à virgule flottante. Dans scikit-image, une image en float s'attend à ce que les intensités des pixels soient mises à l'échelle sur une plage stricte, généralement de zéro à un.
Voici le point clé. N'utilise pas la méthode astype de numpy pour convertir tes images uint8 en floats. Si tu prends un array uint8 et que tu appelles simplement astype float, numpy change uniquement le type de mémoire sous-jacent. Une valeur de pixel lumineuse de 255 devient simplement 255 point zéro. Ça ne remet pas les valeurs à l'échelle. Si tu passes cet array à une fonction scikit-image ou à un modèle PyTorch qui s'attend à une luminosité maximale à un point zéro, les maths explosent. Tes blancs sont soudainement traités comme s'ils étaient 255 fois plus lumineux que la valeur maximale possible.
À la place, tu dois utiliser les fonctions utilitaires intégrées de scikit-image. La plus importante s'appelle img_as_float. Cette fonction vérifie le data type en input et gère la mise à l'échelle mathématique automatiquement. Elle compresse en toute sécurité une plage uint8 de zéro à 255 vers une plage float précise de zéro à un point zéro.
Les data types ne sont que la moitié du combat. Tu dois aussi aligner les channels de couleur, surtout si tu captures de la vidéo. Si tu lis une frame avec OpenCV, il te renvoie un array numpy en uint8. Mais OpenCV a une particularité historique. Il stocke les channels de couleur dans l'ordre Bleu Vert Rouge, connu sous le nom de BGR. scikit-image et la plupart des modèles d'IA modernes s'attendent à du Rouge Vert Bleu, ou RGB. Si tu oublies d'inverser les channels, les pommes rouges ont l'air bleues et la peau humaine a l'air complètement alien.
Tu n'as pas besoin d'appeler une fonction de conversion de couleur OpenCV trop lourde pour corriger ça. Comme l'image est juste un array numpy, tu peux utiliser du slicing d'array basique. Tu slices l'array sur ses trois dimensions. Tu prends toutes les lignes, toutes les colonnes, et ensuite pour la dernière dimension qui représente les channels de couleur, tu spécifies un pas de moins un. Ça dit à numpy de parcourir les channels à l'envers, inversant le BGR en RGB instantanément en mémoire.
Passons en revue un pipeline d'ingestion complet pour un modèle de deep learning. D'abord, tu récupères une frame depuis un flux vidéo OpenCV, ce qui te donne un array BGR en uint8. Ensuite, tu inverses les channels de couleur en utilisant le slicing numpy pour le convertir en RGB. Puis, tu passes cet array dans img_as_float. L'array est maintenant une matrice à virgule flottante, parfaitement mise à l'échelle entre zéro et un. Enfin, tu convertis cet array numpy tout propre en un tensor PyTorch.
Un réseau de neurones ne peut pas te dire quand ses données en input sont mal mises à l'échelle, il apprend juste les mauvais patterns ou échoue silencieusement. Contrôler tes data types et l'ordre de tes channels dès l'étape d'ingestion garantit que ton pipeline repose sur des bases mathématiques solides.
C'est tout pour cet épisode. Merci d'avoir écouté, et continue de développer !
3
Contraste, exposition et robustesse de l'IA
3m 41s
Apprenez à utiliser l'ajustement du contraste et l'égalisation d'histogramme pour standardiser les jeux de données. Ces techniques sont cruciales pour rendre les modèles d'IA robustes face aux variations de conditions d'éclairage.
Salut, c'est Alex de DEV STORIES DOT EU. scikit-image : Le pipeline d'images IA, épisode 3 sur 5. Les réseaux de neurones sont géniaux pour trouver des patterns, mais ils vont joyeusement mémoriser l'éclairage spécifique d'une pièce au lieu de l'objet que tu veux qu'ils détectent. Pour corriger ça, on doit standardiser la variance dans nos datasets grâce au contraste, à l'exposition et à la robustesse de l'IA.
Prends l'exemple d'un dataset de radios médicales collectées dans une douzaine d'hôpitaux différents. Les scans viennent de machines différentes avec des calibrations qui varient énormément. Certaines images sont sombres et baveuses, alors que d'autres sont délavées et très claires. Si tu donnes ces données brutes à un réseau de neurones, il va probablement overfitter sur les conditions d'éclairage de scanners spécifiques au lieu d'apprendre à identifier la pathologie sous-jacente. Tu dois normaliser l'exposition avant que le training commence.
La première étape de cette standardisation, c'est souvent de supprimer les infos non pertinentes. Si seule la structure compte, la couleur est une distraction. Tu peux utiliser une fonction qui s'appelle rgb to gray pour convertir des images en couleur en arrays de niveaux de gris à un seul canal. Ça réduit la dimensionnalité de tes données et ça force le modèle à évaluer la luminance pure.
Une fois que tu travailles strictement avec la luminance, tu dois aligner la luminosité de base sur tout ton dataset. C'est là qu'intervient rescale intensity. Cette fonction fait un étirement linéaire sur les données de ton image. Elle prend le pixel le plus sombre et le mappe sur la valeur la plus basse possible, comme zéro, et elle mappe le pixel le plus clair sur la valeur la plus haute possible, comme deux cent cinquante-cinq. Chaque pixel entre les deux est mis à l'échelle linéairement.
Voici le truc important. Un simple étirement du minimum au maximum est fragile. Un seul pixel noir mort ou un artefact lumineux dû à une poussière sur le capteur va dicter toute l'échelle. L'étirement va compresser tes vraies données anatomiques dans une bande de gris étroite et inutile, juste pour accommoder cet outlier extrême.
Pour résoudre ça, tu utilises le percentile clipping. Au lieu d'étirer à partir du minimum et du maximum absolus, tu calcules le deuxième et le quatre-vingt-dix-huitième percentiles des valeurs des pixels de ton image. Tu passes ensuite ces percentiles dans la fonction rescale intensity comme ton input range. La fonction va couper les deux pour cent extrêmes de pixels clairs et sombres, en les mettant en blanc pur et en noir pur, et va étirer linéairement les quatre-vingt-seize pour cent de données restantes. Ça garantit que le gros de tes données structurelles utilise toute la dynamic range, en ignorant complètement les artefacts aléatoires.
Parfois, un étirement linéaire ne suffit pas. Tu peux avoir une radio où les données sont capturées, mais où tous les pixels sont regroupés autour de quelques nuances de gris spécifiques, ce qui rend l'image plate et masque les détails. Pour ça, tu utilises equalize hist, qui veut dire histogram equalization.
L'histogram equalization est un processus non linéaire. Au lieu de juste étirer les limites, ça analyse la fréquence de chaque valeur de pixel dans l'image. Ça répartit ensuite les valeurs d'intensité les plus fréquentes sur tout le spectre disponible. Si une grande partie de ta radio est coincée dans une bande étroite de gris foncés, l'histogram equalization va écarter ces gris, en leur attribuant de nouvelles valeurs qui vont du noir au blanc. Ça booste artificiellement le contraste local, révélant des textures et des contours subtils qui étaient avant cachés dans les zones baveuses du scan.
Standardiser ton dataset avec ces techniques garantit que ton modèle évalue la vraie forme et texture du sujet. Un pipeline robuste élimine la variance non pertinente de la calibration du hardware, forçant le réseau de neurones à apprendre le signal plutôt que le bruit. Merci d'avoir passé quelques minutes avec moi. À la prochaine, prends soin de toi.
4
Transformations géométriques pour l'augmentation de données
3m 47s
Découvrez comment redimensionner les images pour les adapter aux entrées des réseaux de neurones et appliquer des transformations affines. Essentiel pour construire des pipelines robustes d'augmentation de données.
Salut, ici Alex de DEV STORIES DOT EU. scikit-image : The AI Image Pipeline, épisode 4 sur 5. Un réseau de neurones convolutif peut reconnaître un chat à la perfection. Mais retourne ce chat, ou décale-le de trois pixels vers la gauche, et le modèle devient soudainement complètement aveugle. Tu corriges ça avec des transformations géométriques pour la data augmentation.
Avant d'augmenter quoi que ce soit, tu dois préparer la baseline. Les réseaux de neurones ont besoin d'input shapes fixes. Tu gères ça en utilisant la fonction resize dans scikit-image. Tu lui passes une image et tes dimensions d'output cibles, et elle étire ou rétrécit mathématiquement l'array de pixels pour l'adapter, en interpolant automatiquement les nouvelles valeurs des pixels. Mais le resize seul laisse ton modèle vulnérable à l'overfitting. Il va mémoriser exactement où les objets se trouvent dans la frame. Pour éviter ça, tu construis un pipeline de data augmentation qui applique des transformations aléatoires aux images de training à la volée.
Dans scikit-image, les transformations spatiales manipulent l'espace de coordonnées de l'image en utilisant le calcul matriciel. Déplacer ou faire pivoter une image revient à multiplier les coordonnées de ses pixels par une matrice de transformation. Voici le point clé. La translation, qui consiste à décaler une image sur l'axe x ou y, ne peut pas être calculée avec une multiplication matricielle deux par deux standard. La multiplication matricielle gère le scaling et la rotation, mais le décalage nécessite une addition.
Pour résoudre ça, scikit-image utilise les coordonnées homogènes. En ajoutant une troisième coordonnée fictive, la valeur un, à chaque point en deux dimensions, le système améliore les maths. Ça permet de calculer simultanément les translations, les rotations et le scaling sous la forme d'une seule multiplication matricielle trois par trois.
Tu n'as pas besoin d'écrire ces matrices trois par trois manuellement. scikit-image fournit des classes de transformation pour faire les maths à ta place. Pour notre pipeline anti-overfitting, tu utilises la classe Euclidean transform. Une transformation euclidienne préserve les distances et les angles, ce qui veut dire qu'elle ne gère que la rotation et la translation. Tu l'initialises en lui passant un angle de rotation et un vecteur de translation. Si tu avais besoin d'ajouter du shearing ou de changer le scale, tu passerais à une Affine transform. Si tu avais besoin de simuler un changement de perspective, tu utiliserais une Projective transform. Mais pour des rotations et des décalages aléatoires, Euclidean est exactement ce qu'il te faut.
Une fois ta matrice de transformation définie, tu dois l'appliquer à ton image. Tu fais ça en utilisant la fonction warp. Tu passes à la fonction warp ton image d'input et ton objet Euclidean transform.
C'est là que ça devient intéressant. La fonction warp ne calcule pas où les pixels d'input devraient aller dans la nouvelle image. Si tu pousses les pixels vers l'avant dans une nouvelle grille, les maths de rotation créent des coordonnées fractionnaires. Quand elles sont arrondies au pixel entier le plus proche, tu te retrouves avec des pixels manquants, ou des trous, dispersés sur ton image d'output. Au lieu de ça, warp fonctionne à l'envers. Elle prend l'inverse de ta matrice de transformation. Elle regarde chaque coordonnée de pixel vide dans l'image d'output cible, la mappe en arrière dans l'espace de l'image d'origine, et interpole la bonne valeur de couleur. Ce mapping inverse garantit un output plein, sans trous.
Pour ton pipeline d'augmentation, la logique est simple. Génère un angle aléatoire et un ensemble aléatoire de décalages. Passe-les à une Euclidean transform. Passe cette transform et ton image de training à la fonction warp. L'output va directement dans ton réseau de neurones. Les transformations géométriques ne font pas que créer plus de data de training ; elles forcent ton modèle à séparer l'objet qu'il doit reconnaître des coordonnées arbitraires qu'il se trouve à occuper.
C'est tout pour cet épisode. Merci d'avoir écouté, et continue à développer !
5
La segmentation classique pour amorcer l'IA
3m 16s
Découvrez comment utiliser la segmentation classique watershed pour générer automatiquement des masques d'entraînement parfaits au pixel près pour les modèles de deep learning, vous faisant ainsi gagner des heures d'étiquetage manuel.
Salut, c'est Alex de DEV STORIES DOT EU. scikit-image : Le pipeline d'images pour l'IA, épisode 5 sur 5. Les modèles de segmentation en deep learning sont incroyablement puissants, mais ils sont extrêmement gourmands. Ils exigent des milliers de masques dessinés à la main, pixel-perfect, avant de pouvoir apprendre quoi que ce soit. La segmentation classique pour bootstraper l'IA comble ce vide.
Tu entraînes un U-Net moderne pour détecter des cellules ou des pièces de monnaie qui se touchent. Tu as besoin de labels ground-truth. Dessiner ces masques à la main prend des semaines. Tu pourrais essayer de faire tourner un edge detector simple comme Canny pour automatiser le process. Canny est excellent pour trouver des transitions nettes, mais il échoue souvent à fermer les boucles. Il te donne des contours fragmentés, pas des régions pleines. Une IA entraînée sur des contours brisés te sortira des contours brisés en output.
La segmentation basée sur les régions résout ce problème. Plus précisément, l'algorithme Watershed. Il traite ton image comme un paysage topographique. Les valeurs de pixels élevées sont des montagnes, et les valeurs basses sont des vallées. Voici l'idée clé. Au lieu d'essayer de connecter des edges brisés, Watershed inonde l'image à partir de points de départ connus jusqu'à ce que l'eau se rejoigne sur les crêtes les plus hautes. Ça garantit des régions fermées et pleines.
D'abord, tu construis le terrain. Tu fais ça en générant une elevation map avec un filtre de Sobel. Le filtre de Sobel calcule les gradients spatiaux, ce qui fait ressortir les edges. Quand tu l'appliques à ton image, les bordures entre tes pièces qui se chevauchent deviennent les crêtes hautes de ta map. Les surfaces plates des pièces et le background deviennent les vallées.
Ensuite, tu places les markers. Tu dois dire à l'algorithme où l'eau doit commencer à monter. Si tu zappes ça, l'algorithme va inonder à partir de chaque petit minimum local et exploser ton image en des centaines de fragments inutiles. Tu crées un array de markers exactement de la même taille que ton image d'origine. Tu trouves le background définitif en sélectionnant les pixels en dessous d'un certain threshold d'intensité et tu leur assignes une valeur de un. Ensuite, tu trouves le foreground définitif, c'est-à-dire les centres pleins des pièces, en sélectionnant les pixels au-dessus d'un threshold d'intensité plus élevé. Tu leur assignes une valeur de deux.
Enfin, tu déclenches l'inondation. Tu passes ton elevation map et ton array de markers à la fonction watershed du module de segmentation de scikit-image. L'algorithme remplit les régions en partant des uns et des deux. À mesure que l'eau simulée monte, les régions s'étendent. Quand elles se rencontrent enfin sur les crêtes hautes de l'elevation map de Sobel, l'algorithme construit une boundary.
La fonction retourne un array d'entiers de régions fermées et parfaitement labellisées. Les objets qui se touchent sont séparés exactement à la boundary. Tu as maintenant un array de masques propre où chaque pièce est un objet plein distinct. Tu peux faire tourner ce pipeline sur tout ton dataset non labellisé pour générer des milliers de masques automatiquement. Tu feed ensuite ces masques directement dans ton U-Net comme training data ground-truth.
Bootstraper une IA ne demande pas de travail humain si tu sais comment combiner la logique de terrain du traitement d'image classique avec des architectures de modèles modernes. Je t'encourage à explorer la documentation officielle de scikit-image et à essayer de construire une elevation map hands-on, et si tu as une idée pour notre prochaine série, passe sur devstories.eu et dis-le-moi. C'est tout pour cet épisode. Merci d'avoir écouté, et keep building !
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Ce site n'utilise pas de cookies. Notre hébergeur peut enregistrer votre adresse IP à des fins d'analyse. En savoir plus.