Pagina 1 di 1

#3 [14/05/2015] Minicontest programmazione - Img processing

Inviato: 07/05/2015, 22:48
da Tizzio
<< Contest precedente

Sporadicamente vi proporrò un problema e dovrete implementarlo in uno/più script

Sarà accessibile a tutti, anche chi è agli inizi con la programmazione (e vi invito ad approfittarne e partecipare) in generale, ma che potrebbe far riflettere su un problema o vederlo da un altro punto di vista anche chi programma da anni, dato che dopo si discuterà il codice della gente che ha consegnato

Regolamento
Postate lo script dentro al tag code, ad esempio

Codice: Seleziona tutto

if(argument0 == argument1)
    return 1;
return 0;
(entro la data di scadenza scritta nel titolo del topic)

o un progetto gmk/gmz

Cosa si vince?
Un sacco di conoscenza

CONTEST DI QUESTA SETTIMANA
Estrattore di contorni:
Elaborare una surface caricata con una foto qualunque (per le prove utilizzare quella fornita) in maniera da enfatizzare I contorni delle figure

Immagine fornita: http://www.hack4fun.org/h4f/sites/defau ... p/lena.bmp

esempi di risultati che dovete ottenere: (l'importante è che si distinguano bene i contorni)
http://i.gyazo.com/656575bf977cd6c259bb47bf07095844.png
http://researchvalue.net/valorisation/a ... /Fig.5.png
PS: Si possono utilizzare anche più script dipendenti tra loro e/o fornire un progetto di esempio

<< Contest precedente

Re: #3 [14/05/2015] Minicontest programmazione - Img process

Inviato: 08/05/2015, 0:06
da cp94
Solo in GML?
edit:
Immagine
E' lento sfatto, ma è realizzato in 5 minuti e sicuramente migliorabile.
https://mega.co.nz/#!nJASmLKa!R9OWWOFGv ... oK488PTnyI

Per gli sfaticati il codice è il seguente. La sintassi merdosa è data dal fatto che uso GM8.
Ah, non avevo voglia di far caricare lo sprite esternamente, così dovete metterlo voi a (0,0) :lol:

CREATE

Codice: Seleziona tutto

spr = sprite0_lena; //nome sprite
s_xx = sprite_get_width(spr);
s_yy = sprite_get_height(spr);
dsc = ds_grid_create(s_xx,s_yy);
dsf = ds_grid_create(s_xx,s_yy);
spessore = 1;

show_message("processing");
for (i=0; i<s_xx; i+=1)
    for (j=0; j<s_yy; j+=1)
    {
        var t;
        ds_grid_add(dsc,i,j,draw_getpixel(i,j));
        ds_grid_add(dsf,i,j,c_white);
        var dgo; dgo = ds_grid_get(dsc,i,j);
        for (t=0; t<spessore*4; t+=1)
        {
            var px; px = i+cos(t*90)*(floor(t/spessore)+1);
            var py; py = j+sin(t*90)*(floor(t/spessore)+1);
            if (px<0 || py<0 || px>s_xx || py>s_yy) continue;
            var dgval; dgval = ds_grid_get(dsc,px,py);
            if (abs(dgval-dgo)>1544366) ds_grid_set(dsf,px,py,c_black);
        }
    }
DRAW

Codice: Seleziona tutto

var i,j;
for (i=0; i<s_xx; i+=1)
    for (j=0; j<s_yy; j+=1) 
    {
        var dv; dv = ds_grid_get(dsf,i,j);
        draw_set_color(dv);
        draw_point(s_xx+10+i,j);
    }

Re: #3 [14/05/2015] Minicontest programmazione - Img process

Inviato: 08/05/2015, 17:43
da Cash
Questo è un problema interessante, ho iniziato a scrivere un po' di codice ma è molto brutto(seriamente) quindi non lo posto. Per ora la mia idea è:
-Prendo tutti i colori di tutti i pixel e li metto in una ds_grid, per ora uso surface_getpixel ma dopo mi guardo buffer_get_surface
-Approssimo tutti i valori della ds_grid, nel senso che se ci sono pixel che hanno colori diversi ma molto simili allora li rendo uguali.
-Con un loop passo per tutti i valori della grid e appena trovo un cambio di valore disegno un pixel bianco alla posizione corrispondente
So che i passi 2 e 3 si potrebbero unire e si potrebbe disegnare subito i pixel bianchi ma mi incuriosiva vedere l'immagine con tutti i colori distorti. Inoltre questo metodo è molto lento, ho scalato l'immagine a 128x128 e per prendere tutti i colori dei pixel ci mette 20 secondi circa(probabilmente a causa del getpixel)

Re: #3 [14/05/2015] Minicontest programmazione - Img process

Inviato: 08/05/2015, 18:06
da cp94
Cash ha scritto:Questo è un problema interessante, ho iniziato a scrivere un po' di codice ma è molto brutto(seriamente) quindi non lo posto. Per ora la mia idea è:
-Prendo tutti i colori di tutti i pixel e li metto in una ds_grid, per ora uso surface_getpixel ma dopo mi guardo buffer_get_surface
-Approssimo tutti i valori della ds_grid, nel senso che se ci sono pixel che hanno colori diversi ma molto simili allora li rendo uguali.
-Con un loop passo per tutti i valori della grid e appena trovo un cambio di valore disegno un pixel bianco alla posizione corrispondente
So che i passi 2 e 3 si potrebbero unire e si potrebbe disegnare subito i pixel bianchi ma mi incuriosiva vedere l'immagine con tutti i colori distorti. Inoltre questo metodo è molto lento, ho scalato l'immagine a 128x128 e per prendere tutti i colori dei pixel ci mette 20 secondi circa(probabilmente a causa del getpixel)
E' esattamente ciò che ho postato.

Re: #3 [14/05/2015] Minicontest programmazione - Img process

Inviato: 21/05/2015, 21:34
da Breston
Che topic interessante, un peccato che si sia cimentata una sola persona.
Cash ha scritto: -Approssimo tutti i valori della ds_grid, nel senso che se ci sono pixel che hanno colori diversi ma molto simili allora li rendo uguali.
Questo è esattamente quello che si tende a fare in ambito scientifico, anche se non in maniera così radicale: hai descritto un filtraggio passa alto.
Tale filtraggio enfatizza le variazioni forti (frequenze alte) e demolisce quelle deboli (frequenze basse), anche se non rende esattamente i pixel uguali, sicuramente li rende più simili.
Sotto alcune condizioni questo filtro opera esattamente come l'operatore di derivazione.
Per cominciare, i bordi si estraggono sulla versione in bianco e nero dell'immagine, cioè su un'immagine ad un solo canale ottenuto così: Y = 0.299 R + 0.587 G + 0.114 B.
I coefficienti non hanno un significato preciso, limitatevi a notare che la loro somma è 1. La loro motivazione risiede negli studi che hanno mostrato che l'occhio umano è sensibile solo a quei tre colori (rosso, verde e blu), e, in particolare, è molto più sensibile al verde rispetto a rosso e blu.
Sia [latex]f(x,y) \in [0,255][/latex] l'immagine in scala di grigio ottenuta convertendo l'immagine originale in luminanza.
Quella che si applica è una versione approssimata della derivazione, anche molto semplice:
[latex]\frac{\partial f}{\partial x}(x,y) \approx -f(x-1,y)+f(x+1,y)[/latex]
[latex]\frac{\partial f}{\partial y}(x,y) \approx -f(x,y-1)+f(x,y+1)[/latex]
Si può quindi calcolare il modulo del gradiente e considerare come contorni i pixel in cui tale modulo sia superiore ad una certa soglia prefissata:
[latex]\sqrt{\frac{\partial f}{\partial x}^2+\frac{\partial f}{\partial y}^2} > V_{th}[/latex]
L'algoritmo può essere migliorato raffinando l'approssimazione della derivata oppure cambiandola con una combinazione più robusta al rumore (vedi filtro di canny).
Un altro modo per migliorare le prestazioni è di filtrare prima l'immagine con un passa basso o similari (filtro gaussiano) per togliere il rumore.

Re: #3 [14/05/2015] Minicontest programmazione - Img process

Inviato: 21/05/2015, 22:52
da civic71
Che topic interessante
Concordo e complimenti per la vostre capacità nel risolvere il minicontest :D