Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart
Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart
Mentre Ubisoft vorrebbe chiedere agli utenti, all'occorrenza, di distruggere perfino le copie fisiche dei propri giochi, il movimento Stop Killing Games si sta battendo per preservare quella che l'Unione Europea ha già riconosciuto come una forma d'arte. Abbiamo avuto modo di parlare con Daniel Ondruska, portavoce dell'Iniziativa Europa volta a preservare la conservazione dei videogiochi
Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione
Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione
Abbiamo provato il nuovo Galaxy S25 Edge, uno smartphone unico per il suo spessore di soli 5,8 mm e un peso super piuma. Parliamo di un device che ha pro e contro, ma sicuramente si differenzia dalla massa per la sua portabilità, ma non senza qualche compromesso. Ecco la nostra prova completa.
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto
Pensato per il professionista sempre in movimento, HP Elitebook Ultra G1i 14 abbina una piattaforma Intel Core Ultra 7 ad una costruzione robusta, riuscendo a mantenere un peso contenuto e una facile trasportabilità. Ottime prestazioni per gli ambiti di produttività personale con un'autonomia lontano dalla presa di corrente che permette di lavorare per tutta la giornata
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 21-02-2010, 22:30   #1
omniaforever
Senior Member
 
Iscritto dal: Apr 2009
Messaggi: 1926
segmentazione immagine

ragazzuoli, ho un'altra domanda per voi..

sostanzialmente ho una immagine che possiamo trattare benissimo come matrice di valori..l'immagine ha solo 2 colori: il nero ed un altro colore (quindi concettualmente può essere trattata come una immagine in bianco e nero)

vorrei suddividerla in tanti immagini in base a varie regioni...cioè se l'immagine ha gli oggetti rossi(e sfondo nero) e tutti gli oggetti sono TOTALMENTE SEPARATI (ossia non hanno nemmeno un pixel in comune, se ce l'hanno sarà trattato come lo stesso oggetto), ogni oggetto deve essere riportata su una immagine a parte (con solo quell'oggetto rosso e il resto nero)..anche se c'è un pixel rosso isolato teoricamente dovrà costituire una nuova immagine (in quel caso poi io applico un filtro)..

che procedimento algoritmico grezzo basato su matrice potrei usare? se avete una soluzione usando le librerie opencv sarebbe meglio, ma anche in modo grezzo va bene lo stesso(non ho esigenze di computazione veloce, ma semplicemente che l'algoritmo funzioni)

grazie
__________________
Come installare la rom cucinata V11-7 fixed di Hyperx:
http://www.hwupgrade.it/forum/showpo...ostcount=21774
omniaforever è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 00:43   #2
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12815
Interessante, ci si potrebbe fare un contest , vediamo qualcosa che mi viene di primo acchitto...

Supponiamo tu abbia X oggetti Rossi:

[ R N N R ]
[ N R N N ]
[ N R N N ]

Affinchè un elemento da solo costituisca un immagine non deve avere vicino (a distanza 1) un elemento del colore opposto.

Credo ci sia bisogno di 2 liste, una globale G per tenere traccia degli R visti e una locale L per poter costruire l'immagine.

Coordinate 0,0 (aggiungo in G ed L) -> leggo R:

R N
N R

Tra i vicini c'è un R, lo seguo -> posizione (1,2) (aggiungo in G ed L)

Controllo i vicini di quell'R:
R N N
N R N
N R N

Correzione: vanno calcolati ricorsivamente tutti i vicini ->
abbozzo funzione:


Codice:
vicini(x, y, Set):
passo base:
non ho vicini R oppure (x,y) già in Set, esco
passo ricorsivo:
per ogni vicino R (x1, y1):
Set.addAll(vicini(x1, y1, Set))
Poiché il vicino 0,0 è nella lista G seguo R in (2,2):

Vicini:

N R N
N R N

Non ho altre posizioni da aggiungere alla lista L (e G).

In base alla lista L creo una nuova immagine:
R in (0,0) (1,2) (2,2)

Svuoto la lista L e a questo punto passo ad analizzare (0,1), se trovo vicini R nelle posizioni che ho visto prima (grazie a G li tengo) li scarto e vado avanti...

Trovi un R in (3,1) che è nuovo, lo aggiungi ad L, controlli i vicini, non ha nessun R, quindi crei una nuova immagine.

E via così credo che ce la potresti fare.

Data la tarda ora non assicuro che l'algoritmo sia infallibile, anzi .

Sicuramente si può migliorare l'efficienza se tieni traccia di più informazioni, ora però vado a letto .

Edit: oh ora che ci sto pensando, va sciolta la questione di quale R scegliere nel caso alla prima mossa ti ritrovassi con due R vicini, tipo:

[R R N R]
[N R N N]
[N R N N ]

Nel primo caso bisognerebbe seguire 0,1 e non 1,2, quindi un ipotesi è quella di seguire il vicino di riga.

Tuttavia proviamo un'altra situazione:

[N R R N]
[R R N N]
[N N N N]

In questo caso è evidente una cosa:

Bisogna avere una lista di tutti i vicini R e visitarli tutti.

R in 0,1 -> vicini rossi (0,3) (1,2) (0,1)

Che a loro volta potrebbero avere altri vicini.

Ricordati che quelli che visiti li metti in L così da:
a) controllare quali hai già visitato
b) consentirti di creare alla fine l'immagine

Credo che questa cosa si possa migliorare, ma ora non ci sto con la testa .

Ultima modifica di WarDuck : 22-02-2010 alle 11:48.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 01:57   #3
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2774
Io però invece di tenere in G i nodi visitati ci terrei tutti i nodi e li toglierei mano a mano che li visito. Penso che renda le cose più facili.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 10:47   #4
omniaforever
Senior Member
 
Iscritto dal: Apr 2009
Messaggi: 1926
mmmm non lo so, non mi convince..cioè i problema è quando un pixel rosso comunica con più di un pixel rosso..io sceglierò una strada, ma poi il pixel che non ho scelto?e la sua strada?cioè mi sa che mi ritroverò tante immagine al posto di una reale..anche se lo hai spiegato dopo, ma non ho capito molto..uno schizzo in pseudo codice?
__________________
Come installare la rom cucinata V11-7 fixed di Hyperx:
http://www.hwupgrade.it/forum/showpo...ostcount=21774

Ultima modifica di omniaforever : 22-02-2010 alle 10:56.
omniaforever è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 11:37   #5
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12815
Quote:
Originariamente inviato da wingman87 Guarda i messaggi
Io però invece di tenere in G i nodi visitati ci terrei tutti i nodi e li toglierei mano a mano che li visito. Penso che renda le cose più facili.
Non vorrei sbagliarmi ma intuitivamente dal punto di vista computazionale dovrebbe essere la stessa cosa.

Quote:
Originariamente inviato da omniaforever Guarda i messaggi
mmmm non lo so, non mi convince..cioè i problema è quando un pixel rosso comunica con più di un pixel rosso..io sceglierò una strada, ma poi il pixel che non ho scelto?e la sua strada?cioè mi sa che mi ritroverò tante immagine al posto di una reale..anche se lo hai spiegato dopo, ma non ho capito molto..uno schizzo in pseudo codice?
Si esatto non devi seguirne qualcuno in particolare ma li devi vedere tutti.

Purtroppo nei prossimi giorni ho qualcosa come 3 esami e non posso perderci troppo tempo, sforzati un pochino, fatti venire in mente qualcosa anche a te, lo spunto credo di averlo dato.

Cmq è molto interessante come cosa .
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 11:55   #6
omniaforever
Senior Member
 
Iscritto dal: Apr 2009
Messaggi: 1926
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Non vorrei sbagliarmi ma intuitivamente dal punto di vista computazionale dovrebbe essere la stessa cosa.



Si esatto non devi seguirne qualcuno in particolare ma li devi vedere tutti.

Purtroppo nei prossimi giorni ho qualcosa come 3 esami e non posso perderci troppo tempo, sforzati un pochino, fatti venire in mente qualcosa anche a te, lo spunto credo di averlo dato.

Cmq è molto interessante come cosa .
grazie..vediamo cosa riesco a fare
__________________
Come installare la rom cucinata V11-7 fixed di Hyperx:
http://www.hwupgrade.it/forum/showpo...ostcount=21774
omniaforever è offline   Rispondi citando il messaggio o parte di esso
Old 22-02-2010, 12:59   #7
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2774
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Non vorrei sbagliarmi ma intuitivamente dal punto di vista computazionale dovrebbe essere la stessa cosa.
Forse sì, però dal punto di vista implementativo mi sembra più semplice. Comunque non sono sicuro che sia la stessa cosa dal punto di vista computazionale. Bisognerebbe scrivere l'algoritmo per poter confrontare e anch'io oggi non ho tempo per scriverlo (e ieri notte ero stanco).
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2010, 14:24   #8
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12815
Come procede?

Ho avuto tempo di fare un implementazione e sembra funzionare abbastanza bene.

Questa è la parte centrale:

Codice:
public static ArrayList<Point> contigui(int x, int y, HashSet<Point> viewed) {
        ArrayList<Point> vicini = new ArrayList();

        boolean quit = true;
        
        for (int i=-1; i<=1; i++) {
            int a = x+i; // coordinata X1 del vicino
            if (a>=0 && a<mat.length) {

                for (int j=-1; j<=1; j++) {

                    int b = y+j; // cordinata Y1 del vicino

                    if (b>=0 && b<mat[0].length && mat[a][b]==1) {

                        Point v = new Point(a, b);

                        if (!viewed.contains(v)) {
                            vicini.add(v);
                            if (viewed.add(v)) {
                                quit = false;
                            }
                        }
                    }
                }
            }
        }

        if (!quit) {
            for (int k=0; k<vicini.size(); k++) {
                Point p = vicini.get(k);
                vicini.addAll(contigui(p.x, p.y, viewed));
            }
        }

        return vicini;
    }
Tramite questa funzione sostanzialmente trovo tutti gli 1 contigui alla posizione X,Y.

In pratica:
  • mi trovo tutti i vicini di (X,Y)
  • per ognuno di essi, chiamiamoli (Xv, Yv) mi calcolo la funzione contigui(Xv, Yv).

La ricorsione termina quando non aggiungo più nuovi vicini.

Una piccola nota su come genero i vicini del generico punto P(X,Y):

a) Definiamo vicino V di coordinate (A,B) l'elemento da cui P dista 1.
b) Definiamo Delta la varazione di una singola coordinata (es. X+1, delta X = 1).

Ora appare abbastanza evidente che i possibili Delta sulle coordinate saranno [-1, 1].

Per cui con quei due cicli for mi genero tutti i delta calcolandomi le coordinate del vicino V(A,B):

A=X+I
B=Y+J

con I,J nell'intervallo [-1, 1].

Notare che includo anche lo 0 per poter fissare una data riga o una data colonna ed includere tutti i possibili elementi vicini.

Ovviamente le coordinate generate con questo sistema devono essere valide (devono ricadere all'interno della matrice), per questo noterete un po' di if atti a fare i dovuti controlli.

Alla lista aggiungo solo quelli marcati con un 1, ovvero del colore che mi interessa.

Poi il gioco prosegue facilmente chiamando la funzione contigua(X,Y) su ogni elemento della matrice, appena ho un altro po' di tempo vedo se c'è qualche trucco per ottimizzare il tutto (penso ci si possa ragionare su).

Ultima modifica di WarDuck : 23-02-2010 alle 14:28.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2010, 18:28   #9
omniaforever
Senior Member
 
Iscritto dal: Apr 2009
Messaggi: 1926
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Come procede?

Ho avuto tempo di fare un implementazione e sembra funzionare abbastanza bene.

Questa è la parte centrale:

Codice:
public static ArrayList<Point> contigui(int x, int y, HashSet<Point> viewed) {
        ArrayList<Point> vicini = new ArrayList();

        boolean quit = true;
        
        for (int i=-1; i<=1; i++) {
            int a = x+i; // coordinata X1 del vicino
            if (a>=0 && a<mat.length) {

                for (int j=-1; j<=1; j++) {

                    int b = y+j; // cordinata Y1 del vicino

                    if (b>=0 && b<mat[0].length && mat[a][b]==1) {

                        Point v = new Point(a, b);

                        if (!viewed.contains(v)) {
                            vicini.add(v);
                            if (viewed.add(v)) {
                                quit = false;
                            }
                        }
                    }
                }
            }
        }

        if (!quit) {
            for (int k=0; k<vicini.size(); k++) {
                Point p = vicini.get(k);
                vicini.addAll(contigui(p.x, p.y, viewed));
            }
        }

        return vicini;
    }
Tramite questa funzione sostanzialmente trovo tutti gli 1 contigui alla posizione X,Y.

In pratica:
  • mi trovo tutti i vicini di (X,Y)
  • per ognuno di essi, chiamiamoli (Xv, Yv) mi calcolo la funzione contigui(Xv, Yv).

La ricorsione termina quando non aggiungo più nuovi vicini.

Una piccola nota su come genero i vicini del generico punto P(X,Y):

a) Definiamo vicino V di coordinate (A,B) l'elemento da cui P dista 1.
b) Definiamo Delta la varazione di una singola coordinata (es. X+1, delta X = 1).

Ora appare abbastanza evidente che i possibili Delta sulle coordinate saranno [-1, 1].

Per cui con quei due cicli for mi genero tutti i delta calcolandomi le coordinate del vicino V(A,B):

A=X+I
B=Y+J

con I,J nell'intervallo [-1, 1].

Notare che includo anche lo 0 per poter fissare una data riga o una data colonna ed includere tutti i possibili elementi vicini.

Ovviamente le coordinate generate con questo sistema devono essere valide (devono ricadere all'interno della matrice), per questo noterete un po' di if atti a fare i dovuti controlli.

Alla lista aggiungo solo quelli marcati con un 1, ovvero del colore che mi interessa.

Poi il gioco prosegue facilmente chiamando la funzione contigua(X,Y) su ogni elemento della matrice, appena ho un altro po' di tempo vedo se c'è qualche trucco per ottimizzare il tutto (penso ci si possa ragionare su).
grazie tantissime..in realtà mi sto muovendo utilizzando le opencv che dovrebbero avere funzioni abbastanza specifiche per queste operazioni, ma ovviamente entro questo weekend testerò la tua soluzione e se computazionalmente parlando siamo messi meglio rispetto all'uso delle opencv userò la tua soluzione manuale..in questi giorni dò un'occhiata meglio per capire meglio..in ogni caso ti ringrazio infinitamente della tua cortesia

non ho capito alcune cose:

1-quando poi ciclo tutta l'immagine col coppio ciclo for in quanto matrice e richiamo contigua(X,Y, viewed), in quel viewed che metto?

2-dato che ad esempio partendo dal pixel (0,0) e richiamando la continua(x,y), mi troverò la lista di pixel concatenati a partire da (0,0)..poi mi quando nel ciclo parto da (0,1) ma se ad esempio (0,1) è contiguo a (0,0) mi ritroverò la stessa lista di pixel concatenati di prima...in sostanza dovrei evitare anche i doppioni

cioè parto da questa immagine:
http://img411.imageshack.us/img411/8113/aa4e.jpg

e dovrò ottenere questa
http://img175.imageshack.us/img175/1261/aa2ix.jpg

e questa
http://img685.imageshack.us/img685/5679/aa3s.jpg
__________________
Come installare la rom cucinata V11-7 fixed di Hyperx:
http://www.hwupgrade.it/forum/showpo...ostcount=21774

Ultima modifica di omniaforever : 23-02-2010 alle 18:46.
omniaforever è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2010, 21:27   #10
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12815
viewed è un insieme esterno che rimane durante tutta la scansione della matrice, per cui i dati raccolti da una passata vengono utilizzati anche per la successiva.

viewed contiene sostanzialmente tutte le posizioni in cui sono presenti 1.

Nel main faccio questo:

Codice:
ArrayList<ArrayList<Point>> images = new ArrayList();

        HashSet<Point> viewed = new HashSet();
         
        for (int i=0; i<mat.length; i++) {
            for (int j=0; j<mat[0].length; j++) {

                ArrayList<Point> image = contigui(i, j, viewed);

                if (!image.isEmpty())
                    images.add(image);
            }
        }
L'immagine ovviamente è un insieme di punti.

Come vedi fuori dal ciclo dichiaro sia l'insieme delle immagini generate sia viewed.

Nel caso non lo sapessi, ma penso di si, in Java quando passi un oggetto viene passato il riferimento (quindi viewed può essere visto come una variabile globale).

Avrei in effetti anche potuto dichiararlo come attributo statico di classe, evitandomi il passaggio per riferimento.

Per altro l'utilizzo di un HashSet già di per se non permette duplicati (qual ora tenti di inserire un elemento già nell'insieme lui semplicemente lo ignora) .
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 24-02-2010, 11:29   #11
omniaforever
Senior Member
 
Iscritto dal: Apr 2009
Messaggi: 1926
è uguale usare List? oppure posso usare ArrayList ma devo togliere la specializzazione a <Point>..fa lo stesso? dato che arraylist<point> in c# mi dà errore



quindi tu dici che quando fai
for (int i=0; i<mat.length; i++) {
for (int j=0; j<mat[0].length; j++) {

ArrayList<Point> image = contigui(i, j, viewed);


if (!image.isEmpty())
images.add(image);
}
}
significa che se il pixel (x,y) è stato già concatenato ad un pixel che è stato esaminato in precedenza, contigui() nella lista relativa ai contigui di (x,y) non mi restituirà nessun pixel giusto?

andando a fare il ciclo for (int i = -1; i <= 1; i++)
non darà errore in esecuzione quando siamo nei pixel di bordo dell'immagine?
__________________
Come installare la rom cucinata V11-7 fixed di Hyperx:
http://www.hwupgrade.it/forum/showpo...ostcount=21774

Ultima modifica di omniaforever : 24-02-2010 alle 12:10.
omniaforever è offline   Rispondi citando il messaggio o parte di esso
Old 24-02-2010, 22:03   #12
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12815
Quote:
Originariamente inviato da omniaforever Guarda i messaggi
è uguale usare List? oppure posso usare ArrayList ma devo togliere la specializzazione a <Point>..fa lo stesso? dato che arraylist<point> in c# mi dà errore
Si puoi usare anche una semplice List, tuttavia ogni volta devi riscansionarla per assicurarti che l'elemento non sia già presente, perdendo di efficienza.

Cmq la classe HashSet è presente anche in C#.

Point è una classe Java per gestire le coordinate dei punti 2D, ho usato quella per evitare di rifarmi la classe, cmq la puoi fare tranquillamente anche tu, anzi se usi C# puoi fare direttamente una struttura (più leggera) con i campi int x, int y.

Quote:
Originariamente inviato da omniaforever Guarda i messaggi
quindi tu dici che quando fai
Codice:
for (int i=0; i<mat.length; i++) {
            for (int j=0; j<mat[0].length; j++) {

                ArrayList<Point> image = contigui(i, j, viewed);


                if (!image.isEmpty())
                    images.add(image);
            }
        }
significa che se il pixel (x,y) è stato già concatenato ad un pixel che è stato esaminato in precedenza, contigui() nella lista relativa ai contigui di (x,y) non mi restituirà nessun pixel giusto?
Lui scansiona tutti i vicini alla ricerca di R (valore 1), tuttavia se l'R è già stato visto evita di controllare i suoi vicini.

Questo aspetto credo che potrebbe essere migliorato in qualche modo, domani gli darò un'occhiata.

Quote:
Originariamente inviato da omniaforever Guarda i messaggi
andando a fare il ciclo for (int i = -1; i <= 1; i++)
non darà errore in esecuzione quando siamo nei pixel di bordo dell'immagine?
Premetto che non ho scritto molto elegantemente il codice , cmq la risposta è NO poiché effettuo il controllo più avanti con gli altri if per valutare se le coordinate a e b siano valide, ti riporto l'esempio:

Codice:
for (int i=-1; i<=1; i++) {
            int a = x+i; // coordinata X1 del vicino
            if (a>=0 && a<mat.length) {
               ...
WarDuck è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart Intervista a Stop Killing Games: distruggere vid...
Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione Samsung Galaxy S25 Edge: il top di gamma ultraso...
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto HP Elitebook Ultra G1i 14 è il notebook c...
Microsoft Surface Pro 12 è il 2 in 1 più compatto e silenzioso Microsoft Surface Pro 12 è il 2 in 1 pi&u...
Recensione REDMAGIC Astra Gaming Tablet: che spettacolo di tablet! Recensione REDMAGIC Astra Gaming Tablet: che spe...
La Cina pronta a sfidare NVIDIA? Le GPU ...
Samsung, mega accordo da 16,5 miliardi p...
Le 18 offerte Amazon del weekend, senza ...
Galaxy S25 Ultra 512GB sotto i 1.000€ su...
Vi piace l'iPhone nero? Su Amazon sono s...
MacBook Air M4 16GB/256GB e 16GB/512GB s...
4 portatili per risparmiare tanto ed ess...
San Marino multa TikTok: non controllano...
Dreame e Roborock in saldo su Amazon: ro...
Pazzesco su Amazon: crollano i prezzi de...
La Corea del Sud vorrebbe costruire una ...
Rilasciati i primi risultati delle anali...
Robot umanoidi low cost? Unitree ci prov...
Non solo Rocket Lab, anche Avio potrebbe...
Chips Act UE: 41,5 milioni di euro a Eph...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 06:22.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v