May 13, 2021

Preparare un immagine per il riconoscimento e categorizzazione tramite Ai

Quanto sarebbe divertente collegare una videocamera ad un arduino, e registrare una partita a poker, a dama, a scacchi…

Si potrebbe creare un arbitro computerizzato, sfruttando anche il Text-To-Speech per segnalare verbalmente i bari, creare un ai che calcola la mossa migliore e ti segnala quando la hai scelta, o fa un suono triste quando sbagli grossolanamente.

Per fare tutto questo, oltre naturalmente a creare un programma magari python (il nostro linguaggio di prima scelta) per collegarsi alla webcam e raccogliere il feed video, c’è bisogno di fare data pre-processing.

Data pre-processing

Purtroppo perché un ai sia in grado di riconoscere il campo da gioco, le carte e tutto il resto, non è sufficiente analizzare il feed video puro, bisogna togliere tutto ciò che rappresenta dati inutili, o che potrebbero facilmente confondere il nostro algoritmo.

 “Garbage in, garbage out”

Con dati sporchi, ricchi di errori, si ottengono risultati sporchi e ricchi di errori

Ecco che entra in azione il data pre-processing, ovvero una procedura di filtraggio intenta proprio ad ottenere questi risultati.

Image filtering con python

Prendiamo come esempio un immagine ottenuta da un ipotetica telecamera posta sopra ad una scacchiera e i pezzi per la dama.

(Scacchiera venduta dal negozio spagnolo www.brindesvisao.com.br, link non sponsorizzato)

Supponiamo di dover far riconoscere all’ai le caselle e le dame di entrambi i giocatori, per farlo bisogna usare l’image recognition IR, però se guardate attentamente, ci sono tre diversi problemi che potrebbero confondere un ipotetico algoritmo:

le ombre che l’illuminazione traccia sul campo confondono in parte le caselle

le pedine sia bianche ma soprattutto rosse non sono esattamente dello stesso colore e sulla superfice presentano granulosità

la videocamera non visualizza le pedine tutte dalla stessa angolazione

Due dei problemi che potremmo avere sono risolvibili filtrando l’immagine, però le ombre purtroppo essendo scure e essendo spesso tracciate su caselle nere, rimarranno un problema, anche se in misura minore, che potremo però aggirare in un altro modo.

L’obbiettivo

Dobbiamo fondamentalmente rendere le superfici della dame perfettamente regolari, in questo modo potremmo riconoscerle semplicemente dando in pasto all’algoritmo di IR due cerchi, uno rosso e uno bianco, ed esso escluderà automaticamente le parti inclinate che ci davano fastidio.

Il codice

Partiamo dalle dipendenze di questo progetto:

from PIL import Image
import numpy as np
import time

Sia numpy e pil si possono installare lanciando pip3 install PIL e pip3 install numpy da terminale.

Per quanto riguarda time, non solo si tratta di una libreria già presente nell’installazione base di python3, ma è anche facoltativa, in quanto la useremo solamente per calcolare l’efficienza del nostro algoritmo.

Passiamo all’apertura della nostra foto:

image = Image.open("photo.jpg")
img_data = np.array(image)
h, w, t = img_data.shape

Ora la nostra immagine è salvata dentro image, i suoi dati in formato di array di numpy sono salvati dentro img_data, la altezza è h, la larghezza è w e il numero di componenti del singolo punto (3 con immagini RGB, 4 con immagini RGBA), sono salvati in t.

Possiamo fare un po’ di debug aggiungendo un print:

print(h, w, t)

Che ci restituirà in output:

>> 913 866, 3

Ottimo, quindi la nostra immagine è alta 913, larga 866 e non ha la trasparenza (si poteva già prevedere, considerando che si tratta di un jpg).

Ora prepariamo un nuovo array di numpy vuoto, pronto a raccogliere i pixel dell’immagine rielaborata.

new_img_data = np.zeros((h, w, t), dtype=np.uint8)

Quindi creiamo un iterazione in cui eseguiamo un ciclo per ogni pixel all’interno dell’immagine. Raccogliamo intanto la lista dei tre valori (R, G, B) che formano il pixel.

for x in range(w):
    for y in range(h):
        r_pixel = img_data[y][x][0]
        g_pixel = img_data[y][x][1]
        b_pixel = img_data[y][x][2]

Ora supponendo che non sia possibile posizionare perfettamente la videocamera, potrebbe essere necessario effettuare uno zoom sul soggetto, imponiamo dunque una regola che ci permetta di analizzare solo le zone interessanti.

if x in range(0, w) and y in range(0, h):

Per ora abbiamo inserito w e h come estremità del range per includere tutta l’immagine, se serve per esempio tagliare i bordi a sinistra e a destra di 200px basterebbe sostituire il primo range con range(200, w-200).

Siamo arrivati al filtro vero e proprio. Per la nostra immagine abbiamo trovato che per regolarizzare abbastanza i colori si può eseguire un’operazione di questo genere,

r = (255, 0)[r_pixel < 100]
g = (255, 0)[g_pixel < 100]
b = (255, 0)[b_pixel < 100]
new_img_data[y][x] = [r, g, b]

In sostanza salviamo 255 ovvero intensità massima per ogni colore, solo se il colore stesso parte da un intensità non troppo elevata.

Il programma completo, con l’aggiunta del caso in cui siamo fuori dal range interessante e la produzione effettiva dell’immagine risulta così.

from PIL import Image
import numpy as np
import time

image = Image.open("photo.jpg")
img_data = np.array(image)
h, w, t = img_data.shape

print(h, w, t)

new_img_data = np.zeros((h, w, t), dtype=np.uint8)

for x in range(w):
    for y in range(h):
        r_pixel = img_data[y][x][0]
        g_pixel = img_data[y][x][1]
        b_pixel = img_data[y][x][2]
        if x in range(0, w) and y in range(0, h):
            r = (255, 0)[r_pixel < 100]
            g = (255, 0)[g_pixel < 100]
            b = (255, 0)[b_pixel < 100]
            new_img_data[y][x] = [r, g, b]
        else:   #siamo fuori dal range
            new_img_data[y][x] = [255, 255, 255] # pixel bianco

print("Process time: " + str(time.process_time()) + "s")

new_img = Image.fromarray(new_img_data, 'RGB')
new_img.show()                # visualizza l'immagine a video
new_img.save("new_photo.jpg") #salva la nuova immagine

Che produce questo risultato:

Perfetto, adesso come preventivato con dei semplici cerchi rossi e bianchi possiamo riconoscere tutte le pedine.

E la scacchiera? La scacchiera in realtà non serve, una volta riconosciuta la pedina nella relativa posizione, basta controllare in che range di pixel rientra, per capire in che casella risiede.

Ancora non soddisfatti? Si può ottenere un immagine con ancora meno disturbo effettivamente, togliere completamente ombre e scacchiera, e tenere solo le pedine, quello che davvero ci interessa.

Per farlo è sufficiente modificare il filtro:

r = (255, 0)[r_pixel > 207]
g = (255, 0)[g_pixel > 207]
b = (255, 0)[b_pixel > 207]

Per ottenere il seguente risultato.

Ora è impossibile che l’algoritmo si confonda. Direste mai che questa foto è stata scattata ad una scacchiera di dama?

Avete notato un trend? Meno l’immagine è riconoscibile dall’umano, più è riconoscibile dalla macchina. Questo perché noi siamo in grado di dare molteplici significati con relativamente alta precisione, mentre una macchina non è in grado (ancora) di analizzare più di un dettaglio su un immagine senza applicare nessun filtro. Se si vogliono analizzare le ombre bisogna togliere tutto il resto, se si vuole capire quanti tasselli ha un puzzle bisogna togliere i colori, e così via. Dopo molti filtri e diverse analisi si ottiene il risultato che un umano in genere ricava con un solo sguardo.

Leonardo Bonadimani – Whatar – Filosoft

www.twitch.tv/whatartv

Related Posts

AI Coding Agents Are Becoming Part of Everyday Development

AI coding agents are quickly becoming a normal part of software development. According to JetBrains’ 2026 Developer Ecosystem Survey, around 90% of professional developers used AI coding agents at work at least once a week between May and July 2026. The survey included more than 15,000 professional developers worldwide. Unlike traditional code assistants, AI agents […]

August 25, 2026

Artificial Intelligence and Health: From Diagnosis to Drug Discovery

https://www.sifweb.org/sif-magazine/articolo/intelligenza-artificiale-e-salute-dalla-diagnosi-alla-scoperta-di-nuovi-farmaci-2025-03-27 Artificial Intelligence (AI) is a technology that allows computers to process huge amounts of data, recognize patterns, and make highly accurate predictions. Through advanced models such as machine learning and deep learning, AI systems can learn from data and continuously improve their performance. In medicine, this innovation is transforming the way diseases are diagnosed, […]

May 22, 2026

AI as cognitive support for developers

A recent study by GitHub Next explores how artificial intelligence is reshaping modern software development workflows. The interviews revealed a clear distinction between repetitive, standardized tasks — such as boilerplate code generation, simple refactoring, or test generation — and high cognitive-load activities, including complex debugging, architectural design, contextual system analysis, and the evaluation of technical […]

May 13, 2026

Top ten stubborn gems in the upgrade from ruby 2 to 3

Updating gems is the fulcrum of the upgrade process of a legacy Rails codebase. Other than rails itself, a few gems stand out for their stubbornness in limiting the normal functionality of the application. Establishing the difficulty of maintaining the gem features it’s an heuristic process that involves looking up the gem on https://rubygems.org/ and […]

September 19, 2025

Bill Gates nel suo blog sull’AI

Developing AI and AGI has been the great dream of the computing industry. For decades, the question was when computers would be better than humans at something other than making calculations. Now, with the arrival of machine learning and large amounts of computing power, sophisticated AIs are a reality and they will get better very […]

March 22, 2023