Sfruttare l’intelligenza artificiale per una logistica più intelligente e una prospettiva basata sui dati sull’utilizzo dei container, massimizzando l’efficienza e il ROI
Una delle inefficienze più evidenti nella logistica è il problema dello spazio vuoto. I container, la linfa vitale del commercio globale, spesso viaggiano parzialmente pieni, sprecando spazio e risorse preziosi. Questa inefficienza si traduce in un aumento dei costi operativi e in danni alla sostenibilità del business e dell’ambiente.
Costi di trasporto più elevati
I vettori basano le loro tariffe sulla dimensione del container, non sulla quantità di carico che trasporta. Ciò significa che anche un contenitore parzialmente riempito costa quanto uno completamente imballato. Per dirla in prospettiva, AP Moller — Maersk, come riportato da Statista (2018–2023), hanno visto un aumento significativo delle tariffe di trasporto durante la pandemia di Covid-19. Pertanto, spedire container parzialmente pieni si riduce essenzialmente a pagare per lo spazio vuoto invece che per il carico prezioso, incidendo sul ritorno sull’investimento.
Aumento dell’impronta di carbonio lungo tutta la catena di fornitura
Suddividere lo stesso carico che potrebbe essere contenuto in un unico container significa raddoppiare i mezzi di trasporto.
Aumento dei danni alle merci da carico
Con più spazio, il carico non è così fitto. Ciò consente a scatole, pallet e merci di muoversi più liberamente durante il trasporto, in particolare a causa di vibrazioni e arresti improvvisi.
Per aiutare a identificarlo alla radice prima che il contenitore venga sigillato e spedito, a analizzatore del tasso di riempimento del contenitore che utilizza la visione artificiale e l’intelligenza artificiale (AI) per comprendere il tasso di riempimento di ogni strato di pallet caricato nel container. Il tasso di riempimento di un container è la percentuale di spazio disponibile occupato dal carico.
Utilizzando la visione artificiale con l’aiuto dell’intelligenza artificiale, il compito manuale di giudicare il tasso di riempimento di ciascuna immagine da parte di una persona potrebbe essere eliminato e l’attenzione potrebbe essere focalizzata sulla risoluzione del problema reale.
Codice Github AI della velocità di riempimento del contenitore
Esistono molti approcci a questa sfida. Si potrebbe usare a Rilevatore di colpo singolo (SSD) o Guardi solo una volta (YOLO) per rilevare i pallet e quindi calcolare il tasso di riempimento da lì. Arcgic spiega come funziona SSD in dettaglio nella sua pagina di documentazione Qui.
Tuttavia, l’idea era quella di testare il Meta Segmenta qualsiasi modello (SAM) per questo caso d’uso specifico. Nel blog Meta AI QuiMeta ha condiviso un parco giochi demo e una panoramica generale di ciò di cui è capace SAM. Questo metodo ovviamente non è specifico per un dominio rispetto all’addestramento di un modello per questo compito specifico, ma i modelli generalizzati hanno fatto molta strada e vale la pena testare la fattibilità di tale compito.
SAM è molto versatile e viene fornito con 2 metodi di rilevamento, uno è la generazione automatica della maschera in cui segmenterà tutto su un’immagine e l’altro è basato su prompt, in cui una coordinata sull’immagine guida la segmentazione. Meta ha condiviso un post molto dettagliato su come è stato costruito SAM Qui.
Generazione automatica della maschera SAM
# Initialize Segement Anything and pass in the image for auto mask generation
mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(input_layer_img)
Questo metodo funziona alla grande ed è facile da configurare con solo 2 righe di codice Python e tutto verrà segmentato nell’immagine senza alcuna istruzione.
Tuttavia, la sfida arriva quando si decide se la dimensione dispari dei pallet o degli oggetti estranei fa parte dello strato. Nell’immagine sopra, l’airbag, alcuni involucri di riempimento e il cartone sono segmentati, in modo da sembrare un pallet.
Occasionalmente, a causa di cinghie o involucri sciolti, questo viene segmentato separatamente, come mostrato sopra.
Segmentazione basata su prompt
La segmentazione basata su prompt richiede suggerimenti per guidare SAM nel sapere dove e come dovrebbe essere l’area di interesse. Testando il metodo di generazione automatica della maschera, il metodo di segmentazione basato su prompt è più praticabile per questo progetto.
Di seguito è riportato lo pseudocodice e lo snippet di codice del flusso di esecuzione del programma.
# Read the input image
input_layer_img: np.ndarray = cv2.imread(img_fp)# Downscale image for performance
input_layer_img = downscale(input_layer_img)
# First, find all the labels in the image
# The label position can help prompt SAM to generate segments better
label_points: list(list(int, int)) = pallet_label_detector(input_layer_img)
# Send the labels position to SAM and get a segment mask
segmented_mask: np.ndarray = prompt_segment(label_points, input_layer_img)
# Draw on the original image with values from the mask
segment_color = np.random.random(3) * 100
segmented_img = input_layer_img.copy()
segmented_img(segmented_mask) = segment_color
mask = cv2.inRange(segmented_img, segment_color - 10, segment_color + 10)
# Based on the segmented image, find the fill rate
fill_rate: float = fill_rate_calculation(label_points, mask, segmented_img)
In questo caso, le coordinate di ciascuna etichetta sul pallet possono essere passate a SAM per segmentarla. L’estrazione delle etichette può essere eseguita utilizzando tecniche di visione artificiale, come la definizione della regione di interesse, il filtraggio del colore e il contorno. Questo processo è specifico del dominio aziendale, ma in genere la maggior parte delle etichette sono vicine al bianco.
Il modo più accurato per rilevare le etichette è scansionarle Codice seriale del contenitore di spedizione (SSCC), tuttavia, la qualità dell’immagine non è sufficiente per rilevare i codici a barre.
lower_val = np.array((150, 150, 150), dtype=np.uint8)
upper_val = np.array((255, 255, 255), dtype=np.uint8)# preparing the mask to overlay
mask = cv2.inRange(layer_img, lower_val, upper_val)
# find contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)(0)
new_mask = np.ones(img.shape(:2), dtype="uint8") * 255
prompt_points = ()
for c in contours:
x, y, w, h = cv2.boundingRect(c)
# only select points in our region of interest
if is_outside_roi(layer_img, x, y):
continue
if w * h < 1000:
continue
cv2.rectangle(new_mask, (x, y), (x + w, y + h), (0, 0, 255), -1)
# We calculate the center of the label to be passed for prompting
prompt_points.append((int(x + (w / 2)), int(y + (h / 2))))
res_final = cv2.bitwise_and(layer_img, layer_img, mask=cv2.bitwise_not(new_mask))
cv2.imshow("Labels only", res_final)
Un filtro colore compreso tra 150 e 255 viene applicato all’immagine di input come mostrato nel codice Python sopra e le maschere vengono estratte dall’immagine di input.
Richiedere la posizione delle etichette SAM produrrà un risultato più incentrato sul dominio. Nonostante le etichette estratte non abbiano dimensioni esatte, una stima è sufficiente per consentire al prompt di segmentare quanto necessario.
# prompt_points contains the coordinates of the labels
# ( (x, y), (x, y)...)
input_point_nd = np.array(prompt_points, dtype=np.int32)# As all the prompt points are labels, we are giving them a category of 1
input_label = np.ones(len(prompt_points), dtype=np.int32)
predictor.set_image(segment_img)
masks, scores, _ = predictor.predict(
point_coords=input_point_nd,
point_labels=input_label,
multimask_output=False,
)
L’output segmentato è mostrato nell’immagine sopra. Per calcolare i confini del contenitore è stato utilizzato un metodo semplice, illustrato dal riquadro rosso. L’immagine viene successivamente convertita in bianco e nero per il calcolo del tasso di riempimento.
# Sum of white pixels
total_white = np.sum(fill_rate_used(tallest:ch, cx: cw) == 255)# Sum of black pixels
total_black = np.sum(fill_rate_used(tallest:ch, cx: cw) == 0)
# Percentage of white
fill_rate = round(total_white / (total_white + total_black), 2)
Il tasso di riempimento stimato corrisponderebbe allo spazio colorato occupato rispetto allo spazio non occupato, ovvero ai pixel neri nel confine del contenitore. Poche operazioni morfologiche possono essere applicate come la dilatazione per riempire gli spazi tra le scatole.
Con gli attuali casi di test a disposizione basati su un ambiente personale, i risultati sono vicini alla realtà. Ciò riduce significativamente il carico di lavoro manuale derivante dall’analisi del tasso di riempimento di ciascun contenitore ed è in atto un giudizio più coerente sulla percentuale del tasso di riempimento. I pallet di forma strana vengono presi in considerazione quando l’etichetta verrà rilevata e le segmentazioni indesiderate vengono ridotte grazie alla richiesta delle coordinate delle etichette.
Con questo risultato per ogni strato caricato in un container, le aziende sono ora in grado di analizzare la causa dei carichi parziali e decidere se esiste una lacuna nel processo operativo o di pianificazione. Dal punto di vista operativo, la decisione di sigillare un container prima della spedizione potrebbe utilizzare come fattore anche l’indicatore del tasso di riempimento.
Monitorando i risultati nel tempo, è possibile creare una tendenza visibile per visualizzare eventuali miglioramenti nel processo di caricamento.
Strato di pallet
Una delle limitazioni sarebbe che i pallet dietro vengono occasionalmente segmentati con i pallet davanti se i colori corrispondono troppo. Ciò provoca un calcolo errato del tasso di riempimento poiché in realtà il compartimento è considerato vuoto. Per superare tali limitazioni, l’utilizzo della segmentazione basata su prompt potrebbe non essere l’ideale, ma una combinazione di generazione automatica di maschere e rilevamento di etichette.
Corpo estraneo
Un’altra sfida arriva con la segmentazione degli airbag. In alcuni casi, gli airbag si sono mimetizzati con i pallet, provocando il raggruppamento della segmentazione.
Un’opzione per superare tale limitazione è disegnare una scatola ove possibile, rimuovendo le segmentazioni di forma strana. Tuttavia, questo comporta ancora un’altra sfida per i pallet dalla forma strana, si pensi a un pallet di sedie non pieghevoli.
Con l’uso della visione artificiale, i team e i colleghi di un’azienda possono prendere decisioni basate sui dati senza il fastidio di analizzare manualmente le singole immagini.
Ci sono molti modi in cui questo progetto può essere esteso. Alcuni di essi includono:
- Caricamento di camion e anche di piccoli furgoni (consegna dell’ultimo miglio)
- Stima in tempo reale/analisi del carico di fine spedizione da video
- Tradurre il tasso di riempimento in valore monetario e potenziale perdita di metri cubi (m3).
- Calcolo della probabilità di danni alle merci del carico in base alla soglia del tasso di riempimento
Il fattore più importante per garantire un buon output è avere un’immagine o un flusso di input coerente e standardizzato. Ciò migliorerà notevolmente la stima dell’altezza del contenitore e il rilevamento del posizionamento del pallet. Il modo ottimale sarebbe rilevare i codici a barre SSCC e utilizzare la posizione del codice a barre per avviare la segmentazione, tuttavia, ciò comporterebbe il costo di fotocamere più costose.
Ognuno è libero di adattare il codice del progetto container-fill-rate-ai Githubriguardo a Licenza Meta SAM Apache. Questo progetto non è perfetto e c’è sempre molto spazio per miglioramenti.
L’estensione di questo progetto per la propria attività/caso d’uso potrebbe richiedere la comprensione del codice e la modifica dei parametri nel file Python. Ancora più importante, la conoscenza del processo aziendale è essenziale prima di passare al codice. Questo ti aiuterà a capire come adattare il codice all’azienda.
Per saperne di più su questo progetto, non esitate a contattare:
Sito web: https://jonathanlawhh.com/
E-mail: jon_law98@hotmail.com
Fonte: towardsdatascience.com