v0.26 — Ediția 2026. Un curs de 5 episoade despre utilizarea scikit-image v0.26 (Ediția 2026) ca motor principal pentru preprocesarea imaginilor și data augmentation în pipeline-urile moderne de AI și deep learning.
Descoperă cum scikit-image reprezintă imaginile ca ndarrays în NumPy. Află de ce acest design îl face motorul perfect de preprocesare pentru framework-uri de deep learning precum PyTorch și TensorFlow.
4m 13s
2
Vorbim aceeași limbă: Dtypes și OpenCV
Stăpânește tipurile de date ale imaginilor pentru a preveni cele mai frecvente bug-uri silențioase din computer vision. Învață cum să integrezi perfect scikit-image cu OpenCV și inputurile rețelelor neuronale.
4m 35s
3
Contrast, expunere și robustețea AI-ului
Învață cum să folosești ajustarea contrastului și egalizarea histogramei pentru a standardiza dataset-urile. Aceste tehnici sunt cruciale pentru a face modelele de AI robuste la condiții de iluminare variabile.
3m 58s
4
Transformări geometrice pentru data augmentation
Explorează cum să redimensionezi imaginile pentru a se potrivi cu inputurile rețelelor neuronale și cum să aplici transformări affine. Esențial pentru construirea unor pipeline-uri robuste de data augmentation.
4m 19s
5
Segmentare clasică pentru bootstrapping în AI
Descoperă cum să folosești segmentarea clasică watershed pentru a genera automat măști de antrenament perfecte la nivel de pixel pentru modelele de deep learning, economisind ore de etichetare manuală.
3m 37s
Episoade
1
Pipeline-ul de imagini pentru AI: NumPy la bază
4m 13s
Descoperă cum scikit-image reprezintă imaginile ca ndarrays în NumPy. Află de ce acest design îl face motorul perfect de preprocesare pentru framework-uri de deep learning precum PyTorch și TensorFlow.
Salut, sunt Alex de la DEV STORIES DOT EU. scikit-image: The AI Image Pipeline, episodul 1 din 5. Înainte ca un model de deep learning să poată recunoaște o față, acesta trebuie să digere o grilă de numere. Dacă introduci acea grilă în ordinea greșită, modelul tău nu învață nimic, iar procesarea încetinește considerabil. The AI Image Pipeline: NumPy at the Core este soluția pentru a structura corect acea grilă.
Când încarci o imagine folosind scikit-image, nu primești un obiect imagine proprietar. Primești un array N-dimensional standard, cunoscut sub numele de ndarray. O imagine este pur și simplu o matrice de pixeli. Pentru că este un simplu array NumPy, poți folosi orice operație standard pentru a face slice, mask sau pentru a manipula direct datele imaginii.
Aici este ideea esențială. Modul în care scikit-image indexează aceste array-uri îi pune în dificultate pe mulți developeri. În geometria standard, folosești coordonatele x și y, unde x este pe orizontală și y este pe verticală. scikit-image abandonează asta în favoarea notației de matrice. Primul index este rândul, care corespunde poziției verticale. Al doilea index este coloana, care corespunde poziției orizontale. Dacă ai o imagine color, al treilea index este canalul de culoare. O imagine color bidimensională standard este de fapt un array tridimensional ordonat ca rând, coloană, canal.
Să presupunem că pregătești un batch de imagini color pentru a le introduce într-o rețea neuronală convoluțională. Rețeaua ta se așteaptă la un anumit shape. Dacă imaginea ta are 256 de pixeli înălțime și 256 de pixeli lățime cu canale de roșu, verde și albastru, acel shape pentru o singură imagine este 256, 256, 3. Dar un batch cu aceste imagini adaugă o a patra dimensiune la început, reprezentând numărul de imagini.
Când aplici funcții scikit-image pe aceste date, funcția trebuie să știe care dimensiune conține valorile de culoare, ca să nu le proceseze drept date spațiale. Acest lucru este gestionat de argumentul channel axis. Setând argumentul channel axis la minus unu, îi spui funcției că acele canale de culoare se află mereu în ultima dimensiune a array-ului. Asta asigură că funcția țintește datele de culoare corecte, indiferent dacă îi pasezi o singură imagine sau un batch mare cu dimensiuni spațiale suplimentare.
Asta ne aduce la memorie. Asta este partea care contează pentru viteza de procesare. Array-urile NumPy sunt stocate în blocuri contigue de memorie, folosind by default o ordine de tip C. Asta înseamnă că ultima dimensiune din acel shape al array-ului se schimbă cel mai rapid în memoria fizică. Pentru array-ul nostru standard de imagine format din rând, coloană, canal, canalele individuale de culoare pentru un singur pixel stau unul lângă altul în memoria RAM hardware.
Dacă scrii cod custom pentru a face loop peste acești pixeli, trebuie să respecți acest memory layout. Regula este absolută: cea mai din dreapta dimensiune a array-ului tău ar trebui procesată în cel mai interior loop. Iterezi peste rânduri în acel outer loop, apoi peste coloane, apoi peste canale la interior. Dacă inversezi asta și faci loop peste rânduri la interior, forțezi CPU-ul să sară înainte și înapoi peste adrese de memorie fragmentate. Asta distruge cache locality și face codul tău să ruleze semnificativ mai lent.
Cel mai important lucru de reținut este că scikit-image nu folosește coordonate orizontale și verticale; folosește o indexare strictă de matrice cu rând, coloană și canal, iar potrivirea acelor loop-uri cu acea ordine exactă din memorie este ceea ce îți menține data pipeline-ul rapid.
Dacă vrei să ajuți acest podcast să continue, poți susține emisiunea căutând DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mulțumesc că m-ai ascultat și continuă să construiești!
2
Vorbim aceeași limbă: Dtypes și OpenCV
4m 35s
Stăpânește tipurile de date ale imaginilor pentru a preveni cele mai frecvente bug-uri silențioase din computer vision. Învață cum să integrezi perfect scikit-image cu OpenCV și inputurile rețelelor neuronale.
Salut, sunt Alex de la DEV STORIES DOT EU. scikit-image: Pipeline-ul de imagini AI, episodul 2 din 5. Cel mai frecvent silent bug din AI-ul de computer vision nu este în arhitectura rețelei neuronale. Este un mismatch de data type. Introduci o imagine într-un model, codul rulează fără erori, dar output-urile sunt complet garbage. Acest lucru se întâmplă când librăriile tale nu se pun deloc de acord asupra modului în care un pixel ar trebui reprezentat numeric. Astăzi vom repara asta discutând despre Vorbind același limbaj: Dtypes și OpenCV.
În scikit-image, imaginile sunt stocate ca numpy arrays standard. Dar numerele din interiorul acestor arrays se comportă diferit în funcție de data type-ul lor exact. Formatul default de la camere web și fișiere de imagine standard este unsigned integer pe opt biți, cunoscut ca uint8. Aceste valori variază de la zero la 255, unde zero este negrul absolut, iar 255 este intensitatea maximă.
Totuși, funcțiile științifice de procesare a imaginilor și framework-urile de deep learning preferă aproape întotdeauna numerele floating-point. În scikit-image, o imagine de tip float se așteaptă ca intensitățile pixelilor să fie scalate pe un range strict, de obicei de la zero la unu.
Iată ideea cheie. Nu folosi metoda astype din numpy pentru a-ți converti imaginile uint8 în floats. Dacă iei un array uint8 și apelezi pur și simplu astype float, numpy schimbă doar tipul de memorie din spate. O valoare a unui pixel luminos de 255 devine pur și simplu 255 punct zero. Nu rescalează valorile. Dacă pasezi acel array într-o funcție scikit-image sau într-un model PyTorch care se așteaptă ca luminozitatea maximă să fie unu punct zero, matematica explodează. Nuanțele tale de alb sunt tratate brusc ca și cum ar fi de 255 de ori mai luminoase decât valoarea maximă posibilă.
În schimb, trebuie să folosești funcțiile utilitare built-in din scikit-image. Cea mai importantă se numește img_as_float. Această funcție verifică data type-ul de input și gestionează automat rescalarea matematică. Ea comprimă în siguranță un range uint8 de la zero la 255, până la un range float precis de la zero la unu punct zero.
Data type-urile reprezintă doar jumătate din bătălie. De asemenea, trebuie să aliniezi canalele de culoare, mai ales dacă faci captură video. Dacă citești un frame folosind OpenCV, acesta îți dă un numpy array uint8. Dar OpenCV are o ciudățenie istorică. Stochează canalele de culoare în ordinea Blue Green Red, cunoscută sub numele de BGR. scikit-image și majoritatea modelelor moderne de AI se așteaptă la Red Green Blue, sau RGB. Dacă uiți să faci swap la canale, merele roșii arată albastru, iar pielea umană arată complet extraterestru.
Nu ai nevoie să apelezi o funcție greoaie de conversie a culorilor din OpenCV pentru a repara asta. Pentru că imaginea este doar un numpy array, poți folosi array slicing de bază. Faci slicing pe array pe cele trei dimensiuni ale sale. Iei toate rândurile, toate coloanele, iar apoi, pentru dimensiunea finală care reprezintă canalele de culoare, specifici un step de minus unu. Asta îi spune lui numpy să parcurgă înapoi canalele, inversând instantaneu BGR în RGB în memorie.
Hai să parcurgem un pipeline complet de ingestie pentru un model de deep learning. Mai întâi, iei un frame dintr-un video stream OpenCV, care îți dă un array BGR uint8. Apoi, inversezi canalele de culoare folosind numpy slicing pentru a-l converti în RGB. După aceea, pasezi acel array în img_as_float. Array-ul este acum o matrice floating-point, scalată perfect între zero și unu. În cele din urmă, convertești acest numpy array curat într-un tensor PyTorch.
O rețea neuronală nu îți poate spune când datele sale de input sunt scalate incorect, ci doar învață pattern-urile greșite sau eșuează silențios. Controlul data type-urilor și al ordinii canalelor chiar la pasul de ingestie asigură că pipeline-ul tău se bazează pe o fundație matematică solidă.
Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
3
Contrast, expunere și robustețea AI-ului
3m 58s
Învață cum să folosești ajustarea contrastului și egalizarea histogramei pentru a standardiza dataset-urile. Aceste tehnici sunt cruciale pentru a face modelele de AI robuste la condiții de iluminare variabile.
Salut, sunt Alex de la DEV STORIES DOT EU. scikit-image: The AI Image Pipeline, episodul 3 din 5. Rețelele neuronale sunt excelente la găsirea tiparelor, dar vor memora foarte ușor iluminarea specifică a unei camere în loc de obiectul pe care vrei să îl detecteze. Pentru a repara asta, trebuie să standardizăm varianța din dataset-urile noastre prin Contrast, Expunere și Robustețe AI.
Gândește-te la un dataset de radiografii medicale colectate de la o duzină de spitale diferite. Scanările provin de la aparate diferite, cu calibrări extrem de variate. Unele imagini sunt întunecate și tulburi, în timp ce altele sunt șterse și prea luminoase. Dacă introduci aceste date brute într-o rețea neuronală, probabil va face overfit pe condițiile de iluminare ale anumitor scannere, în loc să învețe să identifice patologia de bază. Trebuie să normalizezi expunerea înainte să înceapă training-ul.
Primul pas în această standardizare este adesea eliminarea informațiilor irelevante. Dacă structura este tot ce contează, culoarea doar îți distrage atenția. Poți folosi o funcție numită rgb to gray pentru a converti imaginile color în array-uri grayscale cu un singur canal. Asta reduce dimensionalitatea datelor tale și forțează modelul să evalueze luminanța pură.
Odată ce lucrezi strict cu luminanța, trebuie să aliniezi luminozitatea de bază în tot dataset-ul tău. Aici intervine rescale intensity. Această funcție aplică un stretch liniar pe datele imaginii tale. Ia cel mai întunecat pixel și îl mapează la cea mai mică valoare posibilă, cum ar fi zero, și mapează cel mai luminos pixel la cea mai mare valoare posibilă, cum ar fi două sute cincizeci și cinci. Fiecare pixel intermediar este scalat liniar.
Iată ideea cheie. Un simplu stretch de la minim la maxim este fragil. Un singur pixel negru mort sau un artefact luminos de la un fir de praf de pe senzor va dicta întreaga scală. Acest stretch va comprima datele tale anatomice reale într-o bandă îngustă și inutilă de griuri doar pentru a acomoda acel outlier extrem.
Pentru a rezolva asta, folosești percentile clipping. În loc să faci stretch de la minimul și maximul absolut, calculezi percentilele doi și nouăzeci și opt ale valorilor pixelilor din imaginea ta. Apoi pasezi aceste percentile în funcția rescale intensity ca input range. Funcția va tăia cele două procente extreme de pixeli luminoși și întunecați, setându-i la alb pur și negru pur, și va face un stretch liniar pe restul de nouăzeci și șase la sută din date. Asta garantează că cea mai mare parte a datelor tale structurale folosește întregul dynamic range, ignorând complet artefactele aleatoare.
Uneori, un stretch liniar nu este suficient. S-ar putea să ai o radiografie în care datele sunt capturate, dar toți pixelii sunt grupați în jurul câtorva nuanțe specifice de gri, făcând imaginea să pară plată și ascunzând detaliile. Pentru asta, folosești equalize hist, care vine de la histogram equalization.
Histogram equalization este un proces non-liniar. În loc să facă stretch doar pe limite, analizează frecvența fiecărei valori a pixelilor din imagine. Apoi, distribuie cele mai frecvente valori de intensitate pe întregul spectru disponibil. Dacă o mare parte a radiografiei tale este blocată într-o bandă îngustă de griuri închise, histogram equalization va separa acele griuri, atribuindu-le valori noi care se întind de la negru la alb. Asta amplifică artificial contrastul local, dezvăluind texturi subtile și contururi care înainte erau ascunse în zonele tulburi ale scanării.
Standardizarea dataset-ului tău cu aceste tehnici te asigură că modelul evaluează forma și textura reală a subiectului. Un pipeline robust elimină varianța irelevantă a calibrării hardware, forțând rețeaua neuronală să învețe semnalul, nu zgomotul. Mulțumesc că ai petrecut câteva minute cu mine. Până data viitoare, numai bine.
4
Transformări geometrice pentru data augmentation
4m 19s
Explorează cum să redimensionezi imaginile pentru a se potrivi cu inputurile rețelelor neuronale și cum să aplici transformări affine. Esențial pentru construirea unor pipeline-uri robuste de data augmentation.
Salut, sunt Alex de la DEV STORIES DOT EU. scikit-image: Pipeline-ul de imagini AI, episodul 4 din 5. O rețea neuronală convoluțională ar putea recunoaște perfect o pisică. Dar dacă întorci pisica cu susul în jos sau o muți cu trei pixeli la stânga, modelul devine brusc complet orb. Rezolvi asta cu Transformări Geometrice pentru Data Augmentation.
Înainte să facem orice augmentare, trebuie să pregătim baseline-ul. Rețelele neuronale necesită input shapes fixe. Gestionezi asta folosind funcția resize din scikit-image. Îi pasezi o imagine și dimensiunile de output dorite, iar ea întinde sau micșorează matematic array-ul de pixeli pentru a se potrivi, interpolând automat noile valori ale pixelilor. Dar doar redimensionarea lasă modelul vulnerabil la overfitting. Acesta va memora exact unde se află obiectele în cadru. Pentru a preveni asta, construiești un pipeline de Data Augmentation care aplică transformări aleatorii imaginilor de training, din mers.
În scikit-image, transformările spațiale manipulează spațiul de coordonate al imaginii folosind matematica matricelor. Mutarea sau rotirea unei imagini înseamnă înmulțirea coordonatelor pixelilor acesteia cu o matrice de transformare. Aici e ideea principală. Translația, adică deplasarea unei imagini pe axa x sau y, nu poate fi calculată folosind înmulțirea standard de matrice doi pe doi. Înmulțirea matricelor gestionează scalarea și rotația, dar deplasarea necesită adunare.
Pentru a rezolva asta, scikit-image utilizează coordonate omogene. Prin adăugarea unei a treia coordonate dummy, un unu, la fiecare punct bidimensional, sistemul face un upgrade la matematică. Asta permite ca translațiile, rotațiile și scalarea să fie calculate simultan printr-o singură înmulțire de matrice trei pe trei.
Nu trebuie să scrii manual aceste matrice trei pe trei. scikit-image oferă clase de transformare care fac calculele pentru tine. Pentru pipeline-ul nostru anti-overfitting, folosești clasa de transformare Euclidean. O transformare Euclidean păstrează distanțele și unghiurile, ceea ce înseamnă că gestionează doar rotația și translația. O inițializezi pasând un unghi de rotație și un vector de translație. Dacă ai avea nevoie să adaugi shearing sau să modifici scala, ai trece la o transformare Affine. Dacă ai avea nevoie să simulezi o schimbare de perspectivă, ai folosi o transformare Projective. Dar pentru rotiri și deplasări aleatorii, Euclidean este exact ce ai nevoie.
Odată ce matricea de transformare este definită, trebuie să o aplici pe imaginea ta. Faci asta folosind funcția warp. Pasezi funcției warp imaginea ta de input și obiectul tău de transformare Euclidean.
Aici devine interesant. Funcția warp nu calculează unde ar trebui să ajungă pixelii de input în noua imagine. Dacă împingi pixelii înainte într-un nou grid, matematica rotației creează coordonate fracționare. Când acestea se rotunjesc la cel mai apropiat pixel întreg, ajungi să ai pixeli lipsă, sau găuri, împrăștiați pe toată imaginea de output. În schimb, warp funcționează invers. Ia inversa matricei tale de transformare. Se uită la fiecare coordonată de pixel gol din imaginea de output dorită, o mapează înapoi în spațiul original al imaginii și interpolează valoarea corectă a culorii. Această mapare inversă garantează un output solid, fără găuri.
Pentru pipeline-ul tău de augmentare, logica e simplă. Generezi un unghi aleatoriu și un set aleatoriu de deplasări. Le pasezi unei transformări Euclidean. Pasezi acea transformare și imaginea ta de training în funcția warp. Output-ul merge direct în rețeaua ta neuronală. Transformările geometrice nu creează doar mai multe date de training; ele forțează modelul tău să separe obiectul pe care trebuie să-l recunoască de coordonatele arbitrare pe care se întâmplă să le ocupe.
Asta e tot pentru acest episod. Mersi că ai ascultat și continuă să construiești!
5
Segmentare clasică pentru bootstrapping în AI
3m 37s
Descoperă cum să folosești segmentarea clasică watershed pentru a genera automat măști de antrenament perfecte la nivel de pixel pentru modelele de deep learning, economisind ore de etichetare manuală.
Salut, sunt Alex de la DEV STORIES DOT EU. scikit-image: The AI Image Pipeline, episodul 5 din 5. Modelele de segmentation din deep learning sunt incredibil de puternice, dar sunt incredibil de înfometate. Au nevoie de mii de măști pixel-perfect, desenate de oameni, înainte să poată învăța ceva. Classical segmentation pentru a face bootstrap la AI acoperă acest gol.
Antrenezi un U-Net modern ca să detectezi celule sau monede care se ating între ele. Ai nevoie de ground-truth labels. Să desenezi manual aceste măști durează săptămâni. Ai putea încerca să rulezi un edge detector simplu, cum ar fi Canny, ca să automatizezi procesul. Canny este excelent la găsirea tranzițiilor bruște, dar de multe ori nu reușește să închidă buclele. Îți dă contururi fragmentate, nu regiuni solide. Un AI antrenat pe broken outlines va da ca output broken outlines.
Region-based segmentation rezolvă asta. Mai exact, algoritmul Watershed. El tratează imaginea ta ca pe un peisaj topografic. Valorile mari ale pixelilor sunt munți, iar valorile mici sunt văi. Aici e ideea de bază. În loc să încerce să conecteze broken edges, Watershed inundă imaginea din starting points cunoscute până când apa se întâlnește la cele mai înalte creste. Asta garantează regiuni închise și solide.
Mai întâi, construiești terenul. Faci asta generând un elevation map folosind un filtru Sobel. Filtrul Sobel calculează gradienții spațiali, scoțând în evidență marginile. Când îl aplici pe imaginea ta, granițele dintre monedele care se suprapun devin crestele înalte din map-ul tău. Suprafețele plate ale monedelor și background-ul devin văile.
Apoi, plasezi markerele. Trebuie să-i spui algoritmului de unde ar trebui să înceapă să crească apa. Dacă dai skip la asta, algoritmul va inunda de la fiecare local minimum minuscul și îți va sparge imaginea în sute de fragmente inutile. Creezi un marker array de exact aceeași dimensiune ca imaginea ta originală. Găsești definite background-ul selectând pixelii sub un anumit intensity threshold și le atribui valoarea unu. Apoi, găsești definite foreground-ul, adică centrele solide ale monedelor, selectând pixelii peste un intensity threshold mai mare. Acelora le atribui valoarea doi.
La final, declanșezi inundația. Dai pass la elevation map și la marker array către funcția watershed din modulul de segmentation din scikit-image. Algoritmul umple regiunile pornind de la valorile de unu și doi. Pe măsură ce apa simulată crește, regiunile se extind. Când în sfârșit se întâlnesc la crestele înalte din elevation map-ul Sobel, algoritmul construiește un boundary.
Funcția returnează un integer array de regiuni închise, perfect etichetate. Obiectele care se ating sunt separate exact la boundary. Acum ai un mask array curat, unde fiecare monedă este un obiect solid distinct. Poți rula acest pipeline pe tot dataset-ul tău unlabelled ca să generezi automat mii de măști. Apoi, dai feed la acele măști direct în U-Net-ul tău ca ground-truth training data.
Să faci bootstrap la un AI nu necesită muncă umană dacă știi cum să combini logica de teren din image processing-ul clasic cu arhitecturile moderne de modele. Te încurajez să explorezi documentația oficială scikit-image și să încerci să construiești un elevation map hands-on, iar dacă ai o idee pentru următoarea noastră serie, intră pe devstories.eu și spune-mi. Asta e tot pentru acest episod. Mulțumesc că m-ai ascultat și continuă să construiești!
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Acest site nu folosește cookie-uri. Furnizorul nostru de hosting ar putea înregistra adresa ta IP în scopuri de analiză. Află mai multe.