Diagnosi di polmonite con OpenCV

Articolo in lingua originale di Sandy M

Foto di National Cancer Institute su Unsplash

La polmonite è una grave malattia respiratoria causata da un’infezione che, soprattutto nei gruppi a rischio, può avere complicazioni pericolose per la vita. È fondamentale diagnosticare e trattare la polmonite il prima possibile per massimizzare le possibilità di recupero del paziente. Il processo di diagnosi non è semplice e richiede alcuni strumenti di laboratorio medico e competenze mediche avanzate, ma possiamo utilizzare il deep learning e la computer vision per costruire uno strumento facile e veloce che aiuterà i medici a individuare la polmonite.

Le applicazioni per l’analisi di immagini e video, come i risultati delle radiografie, possono essere create utilizzando la libreria software open-source di computer vision e machine learning nota come OpenCV (Open Source Computer Vision). OpenCV è una libreria open-source per la computer vision, il machine learning e l’elaborazione delle immagini. In questa lezione scopriremo come utilizzare OpenCV per identificare la polmonite nelle immagini radiografiche del torace.

Installare OpenCV

L’installazione di OpenCV è la fase iniziale. Esistono vari metodi per installare OpenCV a seconda del sistema operativo. Ecco alcune scelte molto popolari:

Windows: sul sito principale di OpenCV utilizzare i percorsi pre-costruiti

Linux: OpenCV può essere installato utilizzando il manager dei pacchetti incluso nel proprio Linux distro.

Serve eseguire il seguente codice nel terminale, ad esempio in Ubuntu:

Install libopencv-dev with sudo apt-get

MacOS: OpenCV può essere installato utilizzando Homebrew, il codice sottostante va inserito nel terminale

Brew install opencv

Una volta che OpenCV è caricato, si può utilizzare il seguente codice Python per verificare che funzioni correttamente

import cv2

print(cv2.__version__)

Dovreste vedere il numero di versione stampato nel terminale se OpenCV è stato correttamente installato.

Scaricare il dataset

Il dataset che verrà utilizzato per addestrare un algoritmo per identificare la polmonite può essere ora scaricato. In questo caso, utilizzeremo un dataset di immagini di radiografie al torace di pazienti affetti da polmonite preso da Kaggle. Nel dataset ci sono 5856 immagini totali di radiografie al torace, divise in due categorie: polmonite e soggetti sani.

Per ottenere il dataset, è necessario iscriversi a Kaggle creando un account e aderire ai termini e condizioni del dataset. Una volta che l’avete fatto, digitate il seguente comando nel terminale per ottenere il dataset:

kaggle datasets download -d paultimothymooney/chest-xray-pneumonia

Un file ZIP contenente le informazioni verrà scaricato. create una sottocartella sul vostro computer locale in cui estrarre la ZIP.

Preparare i dati

I dati devono quindi essere preparati per l’addestramento del nostro modello di riconoscimento della polmonite. Per creare più campioni di training a partire da quelli attuali, utilizzeremo un metodo chiamato data augmentation. Questo metodo serve ad aumentare le prestazioni del modello e ad aiutarlo a costruirsi più velocemente. Per creare versioni diverse della stessa immagine, l’aumento dei dati comporta l’applicazione di trasformazioni casuali alle immagini, come la rotazione, il ridimensionamento e il capovolgimento.

Per preparare i dati creeremo due cartelle: una per le immagini di addestramento e una per le immagini di validazione. L’80% delle immagini sarà utilizzato per l’addestramento e il 20% per la validazione.

Ecco il codice per preparare i dati:

import os
import shutil
import random

# Define the paths
input_dir = 'path/to/input/dir'
train_dir = 'path/to/train/dir'
val_dir = 'path/to/val/dir'

# Create the directories
os.makedirs(train_dir, exist_ok=True)
os.makedirs(val_dir, exist_ok=True)

# Get the list of images
image_paths = []
for root, dirs, files in os.walk(input_dir):
for file in files:
if file.endswith('.jpeg'):
image_paths.append(os.path.join(root, file))

# Shuffle the images
random.shuffle(image_paths)

# Split

split_idx = int(0.8 * len(image_paths))
train_image_paths = image_paths[:split_idx]
val_image_paths = image_paths[split_idx:]

Ora copiate le immagini nelle cartelle. Cambiate “path/to/input/dir” con il percorso della cartella in cui sono state estratte le informazioni in questo codice. I percorsi delle cartelle in cui si desidera conservare le immagini di addestramento e di validazione devono essere sostituiti da “path/to/train/dir” e “path/to/val/dir”.

Addestrare il modello

Attraverso le immagini di training create nello step precedente, possiamo ora addestrare il modello di identificazione della polmonite. Il nocciolo del nostro modello sarà una rete neurale convoluzionale (CNN) pre-addestrata, ovvero la VGG16. L’architettura di questa CNN molto famosa è diventata lo stato dell’arte di numerosi task di riconoscimento delle immagini dopo essere stata addestrata su un notevole set di immagini.

Ecco il codice per addestrare il modello:

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Define the input shape of the images
input_shape = (224, 224, 3)

# Load the VGG16 model
base_model = VGG16(weights='imagenet', include_top=False, input_shape=input_shape)

# Add a global average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)

# Add a fully connected layer
x = Dense(128, activation='relu')(x)

# Add the output layer
output = Dense(1, activation='sigmoid')(x)

# Define the model
model = Model(inputs=base_model.input, outputs=output)

# Freeze the layers of the VGG16 model
for layer in base_model.layers:
layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Define the data generators for training and validation
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=10,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
zoom_range=0.1,
horizontal_flip=True,
fill_mode='nearest')

val_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(train_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary')

val_generator = val_datagen.flow_from_directory(val_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary')

# Train the model
model.fit(train_generator,
steps_per_epoch=len(train_generator),
epochs=10,
validation_data=val_generator,
validation_steps=len(val_generator))

Innanzitutto, abbiamo caricato i pesi già addestrati con il dataset di ImageNet. Abbiamo incluso anche un output layer con una funzione di attivazione sigmoide, un layer completamente connesso con 128 neuroni e un GAP (global average pooling) layer. I layer del modello della VGG16 vengono congelati e l’algoritmo Adam insieme alla binary cross-entropy vengono utilizzati per costruire il modello. Successivamente, vengono specificati generatori di dati per i set di training e validation che aumentino i dati e riscalino i pixel nel range [0, 1].

Utilizzando l’approccio fit e i generatori di dati per il training e il validation, addestriamo il modello per 10 epoche.

Valutazione del modello

Per determinare la generalizzazione del modello a nuovi dati dopo l’addestramento, dobbiamo valutare le sue prestazioni su un set di test. Per valutare il modello, utilizzeremo la collezione di test del dataset. Inoltre, mostreremo alcune illustrazioni di immagini classificate correttamente e non correttamente.

Utilizzate il codice seguente per valutare il modello e visualizzare alcune istanze.

import numpy as np
import matplotlib.pyplot as plt

# Define the path to the test directory
test_dir = 'path/to/input/dir/chest_xray/test'

# Define the data generator for test
test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(test_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary',
shuffle=False)

# Evaluate the model on the test set
loss, accuracy = model.evaluate(test_generator, steps=len(test_generator))
print(f'Test accuracy: {accuracy:.2f}')

# Get the predictions and true labels
predictions = model.predict(test_generator, steps=len(test_generator))
predictions = np.squeeze(predictions)
true_labels = test_generator.labels

# Get the image filenames
filenames = test_generator.filenames

# Find the indices of the correctly and incorrectly classified images
correct_indices = np.where((predictions >= 0.5) == true_labels)[0]
incorrect_indices = np.where((predictions >= 0.5) != true_labels)[0]

# Plot some correctly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(correct_indices[:9]):
plt.subplot(3, 3, i+1)
img = plt.imread(os.path.join(test_dir, filenames[idx]))
plt.imshow(img, cmap='gray')
plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
plt.axis('off')

# Plot some incorrectly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(incorrect_indices[:9]):
plt.subplot(3, 3, i+1)
img = plt.imread(os.path.join(test_dir, filenames[idx]))
plt.imshow(img, cmap='gray')
plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
plt.axis('off')

plt.show()

In questo codice, abbiamo creato un generatore di dati di test e di valutazione per valutare il modello. Otteniamo anche le previsioni e le label vere per il set di test e troviamo gli indici delle immagini classificate correttamente e di quelle classificate in modo errato. Quindi, utilizzando Matplotlib, riportiamo alcuni casi di immagini classificate correttamente e scorrettamente.

 

Conclusione

In questo tutorial abbiamo costruito un modello di individuazione della polmonite utilizzando OpenCV e TensorFlow. Abbiamo letto, elaborato e visualizzato le immagini utilizzando OpenCV e abbiamo addestrato e testato il modello utilizzando TensorFlow. Il modello è riuscito a classificare la maggior parte delle immagini del set di test con un alto grado di precisione.

La Computer Vision può essere una grande risorsa per la diagnostica medica. Pur non sostituendo gli operatori sanitari qualificati, possono ridurre i tempi di diagnosi e migliorare l’accuratezza diagnostica. Qui è possibile vedere altri casi d’uso medico del CV in azione.

Share:

Contenuti
Torna in alto