LUPittore: software che impara da solo a dipingere come un umano, prima versione, verrà accelerato l'apprendimento
Abstract
# LUPittore[cite: 2] ## Description[cite: 2] LUPittore is an autonomous, standalone Python desktop application for Windows 10 and Windows 11 combining raster canvas manipulation, multilayer digital compositing, procedural brush engines, and autonomous stroke-based rendering (SBR)[cite: 2]. The software is implemented exclusively in Python 3.10+ and relies on PySide6 for the desktop interface, NumPy and Numba for raster operations, Pillow and OpenCV-compatible image processing, and ONNX Runtime with the DirectML execution provider for optional hardware-accelerated inference[cite: 2]. It requires no C++, MSVC, KDE, or external third-party digital painting suite installation[cite: 2]. LUPittore provides a practical Paint-style workflow: new documents, image import, PNG export, freehand brush, eraser, eyedropper, flood fill, tablet pressure, color selection, multilayer compositing, layer opacity, and bounded undo/redo history[cite: 2]. The autonomous rendering agent executes within a dedicated Qt worker thread isolated from the main interface[cite: 2]. For each iteration it evaluates an ensemble of inferential, inductive, abductive, deductive, and intervention-based Do-Calculus signals at the same time[cite: 2]. Candidate actions are fused into a bounded cubic Bézier stroke[cite: 2]. When `models/stroke_policy.onnx` is available, ONNX Runtime attempts DirectML first and falls back to CPU execution[cite: 2]. The included policy generator creates a compact, valid ONNX starter model; it is an initialization model and is not presented as pre-trained[cite: 2]. ## Dual-Layer Graph Persistence 1. **System Ontological Hypergraph (`sbr_hypergraph.ndjson`)**: A machine-readable, Linked Data schema conforming to W3C PROV-O and schema.org that formally specifies all computational entities, action spaces, execution pipelines, and loss formulations attributed to Luigi Usai (ORCID: https://orcid.org/0009-0003-3001-717X)[cite: 1].2. **Episodic Learning Memory (`ipergrafo.ndjsonld`)**: An append-only transactional log where all autonomous observations are stored as independent JSON-LD records in NDJSON format[cite: 2]. The episodic graph records reference targets, stroke parameters, reasoning confidences, loss observations, 30-stroke reference comparisons, adaptive brush parameters, step counters, and ensemble weights[cite: 2]. At application startup the graph is loaded into memory, restoring the learned state and allowing a new session to continue from the previous stroke count, weights, and brush parameters[cite: 2]. The composite raster canvas remains in volatile system memory (RAM) until manually exported via PNG, whereas episodic records are persisted with flush and fsync[cite: 2]. Corrupted individual records are skipped during recovery so that the remaining learning history remains usable[cite: 2]. Every 30 strokes the current composite is compared with the initial reference using MAE, MSE, PSNR, and normalized similarity[cite: 2]. The painter adapts brush width, stroke length, opacity, pressure, and color mixing from these measurements[cite: 2]. A discovery checkpoint is persisted at least every 30 seconds and again when the session finishes[cite: 2]. The curriculum periodically alternates 60 exploratory strokes and 60 reference-guided strokes[cite: 2]. Exploration visibly tests 1 px, 2 px, 3 px, and 4 px brush tips, multiple colors, and line, circle, triangle, rectangle, and arc primitives[cite: 2]. Geometry type and path are persisted as linked-data action fields[cite: 2]. ## Scientific scope[cite: 2] The five reasoning labels describe computational strategies used to select and weight painting actions[cite: 2]. The current Do-Calculus component performs a counterfactual intervention heuristic based on predicted color error[cite: 2]. It is not a general causal identification engine and does not claim causal conclusions without an explicit causal graph and suitable observational/interventional data[cite: 2]. ## Reproducibility[cite: 2] The source distribution includes the application modules, the ONNX policy generator, the NDJSON-LD persistence layer, and the complete technical specification in `specifiche.md`[cite: 2]. Local virtual environments (`.venv`) and bytecode caches (`__pycache__`) are excluded. Install dependencies and run with:[cite: 2] ```powershellpython -m venv .venv.\.venv\Scripts\activatepython -m pip install -r requirements.txtpython generate_policy.pypython main.py``` ## Author[cite: 2] Luigi Usai[cite: 2] ORCID: https://orcid.org/0009-0003-3001-717X[cite: 2] ## Keywords[cite: 2] Python, PySide6, digital painting, autonomous painting, stroke-based rendering, Bézier strokes, reinforcement learning, ONNX, DirectML, NDJSON-LD, linked data, causal reasoning, Do-Calculus, computer graphics, Windows[cite: 2]. # LUPittore - Specifiche tecniche[cite: 3] ## Obiettivo[cite: 3] LUPittore e un'applicazione desktop standalone per Windows 10/11, scritta in Python 3.10+, per pittura raster multilivello e generazione autonoma di stroke[cite: 3]. Non richiede C++, MSVC o KDE[cite: 3]. ## Dipendenze[cite: 3] Le dipendenze sono in `requirements.txt`: PySide6, NumPy, Numba, Pillow, OpenCV, ONNX e ONNX Runtime DirectML[cite: 3]. L'ambiente virtuale (`.venv`) e la cache di bytecode (`__pycache__`) sono rigorosamente esclusi dal repository di distribuzione. ## Avvio[cite: 3] ```powershellpython -m venv .venv.\.venv\Scripts\activatepython -m pip install -r requirements.txtpython generate_policy.pypython main.py``` `generate_policy.py` crea `models/stroke_policy.onnx`, una policy starter compatibile con ONNX Runtime e DirectML[cite: 3]. Il modello e un'inizializzazione eseguibile, non un modello pre-addestrato[cite: 3]. ## Architettura[cite: 3] * `main.py`: bootstrap QApplication[cite: 3].* `main_window.py`: QMainWindow, menu, toolbar, canvas, livelli e dialog About[cite: 3].* `canvas_engine.py`: layer stack, buffer RGBA contigui float32, compositing source-over, undo/redo bounded[cite: 3].* `brush_engine.py`: Bézier cubica, campionamento adattivo, stamp circolare soft-edge, pressione, contagocce e flood fill[cite: 3].* `ai_worker.py`: QThread, acquisizione target, inferenza ONNX/DirectML, ensemble cognitivo concorrente e loop autonomo[cite: 3].* `learning_graph.py`: memoria append-only NDJSON-LD e ripristino dello stato[cite: 3].* `generate_policy.py`: esportazione del modello ONNX starter[cite: 3].* `sbr_hypergraph.ndjson`: specifica ontologica del sistema in standard Linked Data (W3C PROV-O) attribuita a Luigi Usai[cite: 1]. ## Canvas e livelli[cite: 3] Ogni layer e `Layer(name, pixels, opacity, visible)`, con `pixels.shape == (height, width, 4)` e dtype `float32`[cite: 3]. Il compositing applica Porter-Duff Source Over:[cite: 3] `A_out = A_top + A_base * (1 - A_top)`[cite: 3] `C_out = (C_top*A_top + C_base*A_base*(1-A_top)) / A_out`[cite: 3] Sono supportati aggiunta, rimozione, selezione, opacita, visibilita, riordinamento tramite API engine e cronologia limitata a 50 snapshot[cite: 3]. I dati della tela risiedono nella memoria volatile (RAM) fino al salvataggio manuale PNG. ## Pennello[cite: 3] La traiettoria parametrica e:[cite: 3] `B(u)=(1-u)^3 P0 + 3(1-u)^2 u P1 + 3(1-u)u^2 P2 + u^3 P3`[cite: 3] Il campionamento usa la lunghezza della polilinea dei punti di controllo e una tolleranza proporzionale alla dimensione del pennello[cite: 3]. Gli stamp sono RGBA soft-edge con pressione e opacita[cite: 3]. Mouse e tavoletta Qt (`QTabletEvent`) usano la stessa pipeline[cite: 3]. ## Strumenti Paint[cite: 3] La UI espone Nuovo, Apri, Salva PNG, Pennello, Gomma, Contagocce, Riempimento, Colore, livelli, Undo e Redo[cite: 3]. Il viewport mantiene il canvas proporzionato; l'immagine aperta viene convertita a RGBA e ridimensionata alla dimensione del documento[cite: 3]. ## Menu[cite: 3] * `File`: nuovo, salvataggio PNG, apertura riferimento, uscita[cite: 3].* `Modifica`: Undo e Redo[cite: 3].* `Visualizza`: visibilita del dock livelli[cite: 3].* `Aiuto`: About LUPittore[cite: 3].* `Apprendi`: avvio, pausa/ripresa, arresto e selezione del contesto cognitivo[cite: 3]. About: Autore Luigi Usai[cite: 3]. ORCID cliccabile: https://orcid.org/0009-0003-3001-717X[cite: 3]. ## Ciclo autonomo[cite: 3] `AutonomousPainterWorker` e un `QThread`; non modifica direttamente la UI[cite: 3]. Emette `stroke_ready`, ricevuto dal thread Qt principale[cite: 3]. Il ciclo:[cite: 3] 1. carica il target RGB;[cite: 3]2. copia il canvas corrente;[cite: 3]3. ridimensiona il target al canvas;[cite: 3]4. calcola cinque candidati in parallelo;[cite: 3]5. fonde coordinate con confidenze e pesi persistenti;[cite: 3]6. emette uno stroke Bézier;[cite: 3]7. registra l'osservazione nell'ipergrafo;[cite: 3]8. aggiorna i pesi dell'ensemble e continua dal contatore salvato[cite: 3]. Il worker salva un `sbr:DiscoveryCheckpoint` almeno ogni 30 secondi e sempre alla fine della sessione[cite: 3]. Il checkpoint contiene parametri del pennello, pesi delle strategie e metriche dell'ultimo confronto[cite: 3]. Il curriculum ricomincia periodicamente ogni 120 stroke: i primi 60 sono esplorativi e provano in modo visibile punte da 1, 2, 3 e 4 px, cinque colori e linee, cerchi, triangoli, rettangoli e archi; i successivi 60 sono dedicati alla correzione guidata dal riferimento[cite: 3]. Il contatore e globale e viene ripristinato dall'ipergrafo, senza doppio incremento[cite: 3]. ## Ragionamento simultaneo[cite: 3] Le strategie sono sempre valutate nella stessa iterazione:[cite: 3] * Inferenza: errore pixel oppure output della policy ONNX[cite: 3].* Induzione: errore pesato dalla statistica cromatica globale[cite: 3].* Abduzione: errore pesato dalla forza dell'ipotesi, stimata dalla varianza cromatica[cite: 3].* Deduzione: errore pesato da una regola di confidenza cromatica[cite: 3].* Do-Calculus: stima controfattuale dell'errore dopo un intervento sul colore medio[cite: 3]. La fusione e:[cite: 3] `p = sum_i (w_i*c_i*p_i) / s