Aiuto - Cerca - Utenti - Calendario - Salta a fondo pagina - Versione completa  
NikonClub.it Community > NIKON SCHOOL > Software
16ale16
Come richiesto da lucabeer in un 3D del Sushi Bar, vediamo come sia possibile ralizzare una procedura di watermarking col software Matlab. spero di essere chiaro.

Partiamo dall'algoritmo generale di watermarking. questa procedura mira ad inserire un marchio percettivamente trasparente in un'immagine; marchio che però deve essere riconoscibile da un apposito detector. La caratteristiche del marchio devono essere la trasparenza, come detto, ma anche la robustezza e l'identificabilità da parte del proprietario.
In matlab è possibile leggere le immagini, creando una matrice, anzi 3 matrici (se l'immagine è a colori, una per il rosso, una per blu, una per il verde). A questo punto, se l'immaigne è quantizzata ad 8 bit, avrai valori da 0 a 255 per ogni matrice che a sua volta sarà costituita, nel caso di una foto a 5Mpxls da 1944 righe e 2592 colonne.
L'istruzione per leggere un'immagine e convertirla in un file è imread, che sta nell' Image rocessing Toolbox.
Facciamo un esempio, tu vuoi leggere l'immagine 'moon.tif', che è un'immagine campione di Matlab. Allora nel prompt di Matlab devi scrivere:

>>a=imread('moon.tif');

in questo modo la variabile a è la tua immagine e nel Workspace ti apparirà proprio questa variabile, che sarà in formato uint8 (cioè intero non segnato ad 8 bit).
Prima di procedere è necessario convertire in formato double la variabile di a e l'operazione di cast in matlab la fai con la seguente sintasso:

>>a=double(a);

in questo modo la tua variabile a è pronta per essere marchiata.
16ale16
Ora dobbiamo passare alla realizzazione del marchio. Infatti il grande vantaggio di matlab è che saremo noi a creare il machio, quindi un qualisasi ladro di foto non avrà assolutamente idea di cosa avremo inserito nell'immagine.
Il nostro marchio può essere qualsiasi, una scritta, una foto, un rumore a distribuzione gaussiana.
Per facilità noi useremo proprio quest'ultimo. questo marchio si crea con le seguenti istruzioni:

>>rand('state',0.5);
>>M=rand(5,5);

Così abbiamo creato un marchio scegliendo un'apposita chiave, cioè 0.5 e i lnostro marchio ha dimensione 5*5 pixels. Ovviamente siamo libero di usare un'altra chiave o di scegliere un'altra dimensione. Ogni volta che useremo la stessa istruzione con la chiave 0.5 creeremo sempre la stessa matrice. Ecco il senso della chiave.
Il nostro marchio è il seguente:
[attachmentid=53030]

Atenzione perché se farete un marchio 5*5 non vedrete questa immagine, ma molto più piccola. Per darvi l'idea di quello che viene fuori ho deciso di plottare un marchio 355*355.

Adesso il marchio deve essere inserito nell'immagine
16ale16
Per mettere il marchio nell'immagine abbiamo tantissime scelte, quella che riporto è la più semplice.
qui entriamo nel dettaglio dei domini trasformati e spero di essere il più chiaro possibile. Infatti il watremarking può essere fatto direttamente sui numeri da 0 a 255 della matrice a, che costituisce la nostra immagine, oppure può essere fatta su una particolare trasformazione di questa matrice.
Tra le trasformazioni più usate troviamo la DFT (Discrete Fourier Transfor), la DCT(Discrete Cosene Transform), la WAVELET.
Tutte queste trasformate si distinguono per lacune caratteristiche e sono ovviamente tutte trasformate bidimensionali.
Noi vedremo il caso della trasformata DCT. Questa trasfomata avviene con una forumal che non ci interessa e crea una particolare matrice. Per avere un'idea la DCT è alla base dell'algoritmo di compressione JPEG.
Questa matrice ha numeri reali a precisione infinita la cui posizione è importante. In particoalre conta la diagonale principale, quella che va dall'elemento in alto a sinistra a quello in basso a destra. In alto a sinistra, l'elemento (1,1) è quello che ha i lmaggior contenuto informativo e man mano che si scende verso destra il contenuto informativo scende. In particolare in alto a sinistra troviamo le basse frequenze, in basso a destra le alte frequenze.
Il sistema visivo umano è molto sensibile alle basse frequenze, mentre meno alle alte frequenze, quindi se vogliamo inserire un marchio quindo dovremo cercare di fare il possibile per cercare di evitare le basse frequenze, perché così sarà più visibile per l'occhio, generando effetti di disturbo sulla foto.
Ecco allora che nel marchiare la nostra foto procederemo con le seguenti istruzioni:
per prima cosa binarizziamo il marchio, assegnandogli valori 1 o -1:

>>for i=1:legnth(M,1) (scorri tutte le righe del marchio)
for j=1:length(M,2) (scorri tutte le colonne del marchio)
if M(i,j)<0.5
Mbin(i,j)=-1;
else
Mbin(i,j)=1;
end
end
end

Con Mbin ovviamente indichiamo la versione binarizzata del marchio.

Ora procediamo con la DCT 2D e prima di fare questo sottraiamo il valore medio all'immagine, che per noi vi ricordo è la variabile a:

>>a=a-128;
>>A=dct2(a); (trasformazione DCT2D)

Attenzione perché Matlab è key-sensitive, quindi riconosce come diversi caratteri scritti in maiuscolo o minuscolo e generalmente le variabili trasformate si indicano con le maiuscole.

Ora il bello vero e proprio, cioè la marchiatura. Il marchio viene inserito con la scelta di un apposito coefficiente di peso, secondo la relazione:

watermarked=original+alfa*mark

si tratta come vedete di un coefficiente di peso del marchio e ovviamente varia tra 0 ed 1. Per noi alfa=0.8.
Scriveremo per marchiare la seguente istruzione:

>>A(10:14,10:14)=A(10:14,10:14)+0.8.*Mbin;

Nel prossimo messaggio vedremo perché si va da 10:14 nelle righe e nelle colonne
16ale16
Come detto precedentemente l'immagine trasformata DCT ha valore più interessante per contenuto informativo in alto a sinistra. moon.tif, la nostra immagine di prova, è un'immagine di dimensioni 537*358. Il marchio è di dimensioni 5*5 e con l'istruzione precedente abbiamo scelto di inserirlo dalla riga 10 alla 14 e dalla colonna 10 alla colonna 14. Come vedete non partiamo dall'elemento 1,1 che sarebbe quello con maggiore contenuto informativo perché é quello in alto a sinistra. Ci spositamo lungo la diagonale verso gli elementi a più alta frequenza.
In realtà si potrebbe pensare che non ci si sia spostati di così tanto e quindi i lnostro marchio, pesato per di più con un valore 0.8, possa produrre dei disturbi sull'immagine. In effetti questo in parte è vero, ma qui bisogna fare un'altra considerazione.
Infatto più il marchio viene inserito verso le basse frequenze, più è robusto, anche se, come detto, produce effetti visivi più evidenti. Ecco allora che sarà all'interpretazione del prgorammatore ed in base all'immagine scegliere (con varie prove) dove piazzare il marchio, valutrando il compromesso tra visibilità e robustezza.

Mi permetto di suggerire quanto segue: se non si ha un amrchio registrato e se ci si vuole difendere da furti di foto stile quello dei girasoli, non è necessario un marchio di eccessive dimensioni, inoltre non è necessaria un'eccessiva robustezza. Infatti nel caso di furto della foto da parte di Zorba il Greco, sarebbe bastata la presenza del marchio, senza riguardo alla sua robustezza ad eventuali attacchi massicci. Infatti la foto è stata presa e copiata così com'è!!!

L'immagine così ottenuta, cioè marchiata è infruibile, in quanto ricordiamo che ci siamo spostati in un dominio trasformato. Dobbiamo tronare indietro.
16ale16
Adesso per antitrasformare usiamo:

>> marked=idct2(A);

Aggiungiamo il valor medio tolto precedentemente:

>>marked=marked+128;

riconvertiamo in double:

>>marked=double(marked);

Ora possiamo vedere che cosa abbiamo combinato sull'immagine:

>>>figure, imshow(marked,[])

Come vedrete l'immagine non ha subito cambiamenti di rilievo.

Ora dobbiamo convertire l'immagine in un formato utilizzabile fuori matlab, ad esempio JPEG, scegliendo ovviamente anche il fattore di compressione. Ciò può essere fatto con le seguenti istruzioni:

>>imwrite(marked,'marked.jpg','Quality',80);

in questo modo nella cartella di lavoro di matlab viene creata un'immagine col nome marked, in formato JPG, compresso con fattore 80 su 100, quindi compressa poco. Se avessimo messo 40 invece di 80 avremmo copresso l'immagine del doppio, se invece mettiamo 100 il formato non è loseless.

Ora potete aprire l'immagine con un qualisasi visualizzatore di immagini e vrete ottenuto un'immagine protetta.
Ma non è finita qui...
16ale16
non è finita qui perché così abbiamo fatto solamente metà del lavoro, infatti noi per essere in grado di poter accusare qualcuno di furto dobbiamo coglierlo con le mani sporche di marmellata. Cioè dobbiamo prendere l'immagine e cercare il marchio che abbiamo inserito. Se effettivamente è presente potremo reclamarne la paternità.
Attenzione ad una cosa: per riconoscere il marchio dovete ricordarvi il modo con cui lo avete inserito, altrimenti non lo troverete più. Mi spiego. Noi abbiamo inesrito un marchio a distribuzione gaussiana (prima cosa da ricordare) con chiave 0.5 e dimensioni 5*5(seconda cosa da ricordare). Questo marchio è stato inserito con procedura DCT2D (terza cosa da ricordare) ed è stato inserito dal pixel 10,10 al pixel 14,14.

Il riconscimento del marchio avviene tramite l'operazione di correlazione. Questa operazione misura quanto due cose (entità software per noi) si assomigliano. Se il nostro valore di correlazione sarà sopra una certa soglia, potremo dire che effettivamente il marchio è presente e la foto è nostra.

Andiamo per gradi.
FASE DI DETECTION:
Leggo con l'istruzione imread l'immagine marchiata, che per noi era marked.jpg e la trasformo in formato double:

>>b=imread('marked.jpg');
>>b=double(cool.gif;

Ora, visto che siamo furbi e ci ricordiamo che abbiamo fatto l'embedding nel dominio DCT, trasformiamo in tale dominio la nostra immagine, per andare alla ricerca del nostro marchio. La ricerca infatti può essere fatta esclusivamente nel dominio in cui noi l'abbiamo inserito.

>>B=dct2(cool.gif;

Adesso dobbiamo calcolare la correlazione, cioè vedere quanto una precisa zona dell'immagine marchiata assomiglia al nostro marchio:

>>CORR=corr2(marked(10:14,10:14),Mbin)

attenzione a non mettere ora il ; perché ci interessa che venga restituito il risultato.
In particolare qui abbiamo:

CORR=0.1495

Il valore non è altissimo, ma comunque testimonia che c'è una certa somiglianza tra il nostro marchio e l'immagine. sinceramente non conosco le normative sul watermarking, sono più un tecnico che un burocrate, ma vi garantisco che esiste una soglia oltre la quale l'immagine è reclamabile come propria.
N.B.:: la correlazione va fatta nel dominio in cui abbiamo fatto l'embedding ed il marchio va cercato esattamente nei pixel in cui è stato inserito. Infatti noi facciamo la correlazione tra l'immagine marchiata tra la riga 10 e la 14 e tra la colonna 10 e la 14, dove abbiamo inserito il nostro marchio 5*5.
16ale16
scusate ma non ho fatto caso alle faccine, dove c'e' la faccina c'e' una b ed una parentesi tonda chiusa.... Ce se mettono pure gli smile dry.gif (a proposito!!)

Per chiudere, spero di essere stato chiaro il più possbile per rispondere a quanto era stato chiesto e mi scuso per inevitabili errori di battitura.

Vorrei che sia chiaro che quanto ho presentato è semplicemente una della 10000 procedure che possono essere fatte, ad esempio io in altri casi ho usato la trafromata wavelet.
Su Internet trovate comunque molti script che già fanno watermarking assieme alle procedure di detection. Generalmente sono procedure automatiche, basta che voi inseriate le immagini e fa tutto matlab.

Ciao e grazie per l'attenzione
16ale16
Scusate ma manca un pezzo. Incredibile ma vero!!!
Infatti l'esempio che vi ho riportato riguarda solo le immagini in scala di grigi!!!
Per le immagini a colori però la cosa non è complicata. Basta infatti selezionare le matrici del rosso o del blu e marchiare lì. Preferibilmente in quella del blu. Infatti l'occhio umano è molto sensibile alla matrice del verde, che ha per noi più dettagli.

Scusate ma era d'obbligo aggiungere!!!
robyt
Ciao Ale,
prima di tutto grazie per per le interessanti spiegazioni, forse si potrebbe anche spostare il 3D in "Tecniche".

Non mi sono mai preoccupato di proteggere le mie foto (e chi se le ruba biggrin.gif ) però qualche curiosità me l'hai fatta venire e ti pongo alcune domande.

1 ) - Quanto è importante tenere traccia del posizionamento del marchio visto che la foto potrebbe venire ritagliata ?

2 ) - Come mai il coefficiente di correlazione dell'esempio che hai fatto risulta basso pur non avendo (presumo) manipolato l'immagine ?

grazie ancora.
16ale16
QUOTE(robyt @ Jun 15 2006, 10:30 PM)
Ciao Ale,
prima di tutto grazie per per le interessanti spiegazioni, forse si potrebbe anche spostare il 3D in "Tecniche".

Non mi sono mai preoccupato di proteggere le mie foto (e chi se le ruba  biggrin.gif ) però qualche curiosità me l'hai fatta venire e ti pongo alcune domande.

1 ) - Quanto è importante tenere traccia del posizionamento del marchio visto che la foto potrebbe venire ritagliata ?

2 ) - Come mai il coefficiente di correlazione dell'esempio che hai fatto risulta basso pur non avendo (presumo) manipolato l'immagine ?

grazie ancora.
*



Le domande sono più che lecite.
Rispondo prima alla seconda. L'esempio che ho riportato risponde al 3D ladri di foto nel sushi bar in cui è stata presa una foto da un Greco che l'ha pubblicata su un forum ellenico spacciandola per propria. In quel caso qualsiasi ritaglio o elaborazione avrebbe rovinato la foto stessa, alternadone il contenuto. Quindi nel caso specifico basta un marchio presente, visto che tanto se qualcuno non passa per matlab, con un suo intervento rovinerebbe la foto o quanto meno la modificherebbe. Anche se questi passasse per matlab, non sapendo la tecnica di embedding, potrebbe fare poco.

Per la prima domanda esiste un tizio mezzo svizzero mezzo russo, dal congome assolutamente improponibile, ma tipo volochinovskji, che ha implementato un algoritmo di watermarking resitente a molti degli attacchi possibili tra cui il crop o la torsione.
ripeto però che nel caso specifico un attacco geometrico di rotazione non ha senso, perché se io rubo una foto a qualcuno e la pubblico a testa in giù, beh, non ho fatto una furbata...
questo metodo proprosto è "didattico', nel senso che propongo una panoramica, ma se hai conoscenze di un po' di analisi di segnali puoi usare la Wavelet 2D lavorando sulle matrici LH o HL. I risultati sono migliori!!

Ciao
16ale16
QUOTE(robyt @ Jun 15 2006, 10:30 PM)
Ciao Ale,
prima di tutto grazie per per le interessanti spiegazioni, forse si potrebbe anche spostare il 3D in "Tecniche".

Non mi sono mai preoccupato di proteggere le mie foto (e chi se le ruba  biggrin.gif ) però qualche curiosità me l'hai fatta venire e ti pongo alcune domande.

1 ) - Quanto è importante tenere traccia del posizionamento del marchio visto che la foto potrebbe venire ritagliata ?

2 ) - Come mai il coefficiente di correlazione dell'esempio che hai fatto risulta basso pur non avendo (presumo) manipolato l'immagine ?

grazie ancora.
*



Un'atra cosa. Se il marchio lo inserisci in una zona centrale dell'immagine, il taglio diventa un attacco inutile, perché dovresti 'tassellare' l'immaigne. La cosa importante è che la gente non se lo aspetta che ci sia il marchio. Nel caso del furto di girasoli, il proprietario (di cui non ricordo il nick) avrebbe potuto scaricare la foto dal forum greco, lanciare l'algoritmo di detection (cioè fare la correlazione) e vedere se il valore che ottenuto era uguale a quello ottenuto da lui in fase di embedding. Anche per questo alla fine non ci importa più di tanto l'altissimo valore di correlazione. diciamo che le nostre immagini non devono proteggere copyright di una grande industria. Ci basta tutelarle in qualche modo.

Ma ripeto che esistono infitini schemi di embedding, che possono essere scaricati free da Internet, basta cerca "watermarking matlab" con Google.

Ciao
robyt
..... grazie.gif
oesse
ma matlab non serve a fare calcoli con le matrici e si programma in fortran e pascal??

.oesse.
teo
QUOTE(oesse @ Jun 16 2006, 12:15 AM)
ma matlab non serve a fare calcoli con le matrici e si programma in fortran e pascal??

.oesse.
*



matlab serve per fare i miracoli!!!
sintassi semplicissima e immediata. Una bomba, soprattutto per i progetti pacco di alcuni corsi wink.gif
Fedro
ottimo spunto! grazie per la condivisione di questo metodo di marchiatura.

visto che l'avevi aperto al bar, l'ho riposizionata nella sua sezione naturale: software.


grazie ancora!
Lucabeer
QUOTE(oesse @ Jun 16 2006, 12:15 AM)
ma matlab non serve a fare calcoli con le matrici e si programma in fortran e pascal??

.oesse.
*



Di base fa calcoli con le matrici, questo è vero, ma usa un linguaggio suo (che poi sia simile a pascal, fortran e altri è altrettanto vero).

Il fatto che sia specializzato in trattare matrici di dati lo rende però flessibilissimo per praticamente QUALUNQUE necessità matematica (da un po' di versioni fa pure calcolo simbolico, anche se con un'interfaccia non proprio user friendly). Sono presenti molti add-on pronti che spaziano praticamente in qualsiasi campo.

E' il mio programma base per identificazione di sistemi, progettazione di controlli automatici (regolatori pressione turbocompressori, mixing gas EGR, controllo lambda gas di scarico, ecc.).

Un grazie a 16ale16 per il tutorial: le soluzioni fai da te sono sempre le più divertenti, anche quando esistono tool appositi già pronti per essere scaricati da Internet!
16ale16
QUOTE(Lucabeer @ Jun 16 2006, 07:37 AM)

Un grazie a 16ale16 per il tutorial: le soluzioni fai da te sono sempre le più divertenti, anche quando esistono tool appositi già pronti per essere scaricati da Internet!
*



Scusate ma la notte porta consiglio e ieri sera avevo un sonno incredibile. Rileggendo ho visto che c'è un'imprecisione in quello che ho scritto. Provvedo a spiegare:

il coefficiente di peso della marchiatura, che abbiamo chiamato alfa, non è detto che abbia come valore massimo 1. Anzi, si può effettuare una marchiatura con alfa qualsiasi, tenendo ovviamente conto che maggiore sarà il valore di alfa, maggiore sarà l'effetto percettivo del marchio.
Se usate la trasformata wavelet addirittura potete spingervi anche ad alfa=4 nella matrice HH, visto che questa racchiude tutte le alte freuqneze, che sono poco significative per l'occhio umano.

Ciao
PAS
Interessante.
Utilizzo spesso Mathlab e Simulink per implementare simulazioni ma non avevo mai pensato ad utilizzarli per il watermarking
Grazie
Ipisilon
QUOTE
FASE DI DETECTION:
Leggo con l'istruzione imread l'immagine marchiata, che per noi era marked.jpg e la trasformo in formato double:

>>b=imread('marked.jpg');
>>b=double(cool.gif;

Ora, visto che siamo furbi e ci ricordiamo che abbiamo fatto l'embedding nel dominio DCT, trasformiamo in tale dominio la nostra immagine, per andare alla ricerca del nostro marchio. La ricerca infatti può essere fatta esclusivamente nel dominio in cui noi l'abbiamo inserito.

>>B=dct2(cool.gif;

Adesso dobbiamo calcolare la correlazione, cioè vedere quanto una precisa zona dell'immagine marchiata assomiglia al nostro marchio:

>>CORR=corr2(marked(10:14,10:14),Mbin)

attenzione a non mettere ora il ; perché ci interessa che venga restituito il risultato.
In particolare qui abbiamo:

CORR=0.1495

Il valore non è altissimo, ma comunque testimonia che c'è una certa somiglianza tra il nostro marchio e l'immagine. sinceramente non conosco le normative sul watermarking, sono più un tecnico che un burocrate, ma vi garantisco che esiste una soglia oltre la quale l'immagine è reclamabile come propria.
N.B.:: la correlazione va fatta nel dominio in cui abbiamo fatto l'embedding ed il marchio va cercato esattamente nei pixel in cui è stato inserito. Infatti noi facciamo la correlazione tra l'immagine marchiata tra la riga 10 e la 14 e tra la colonna 10 e la 14, dove abbiamo inserito il nostro marchio 5*5.


Ciao Alessandro,
molto interessante il tuo articolo sul watermarking.
Grazie davvero tante per i preziosi consigli!!!

Non capisco però:

1) perchè togli e aggiungi il valor medio all'immagine prima di calcolare la dct2;

2) perché per la fase di DETECTION fai il confronto tra l'immagine
marked(10:14,10:14) e il marchio Mbin? unsure.gif

Non dovresti invece:
- caricare l'immagine da validare (da validare se marchiata o no);
- chiedere all'utente quale marchio vuoi ricercare (nel nostro caso magari inserirlo direttamente nel codice come hai fatto tu, senza funzioni di input);
- estrarre lo spettro dall'immagine da validare e vedere se in quest'ultimo, alla posizione che sappiamo, noi troviamo il marchio;
In questo caso, se il marchio è presente corr2 ci darà 1.

Perché invece tu confronti direttamente l'immagine marchiata con Mbin?
Che senso ha? unsure.gif

3) Quando salvi l'immagine salvi una immagine double non dovresti prima riconvertirla col comando uint8 ?

Grazie infinite per lo stimolo che mi hai dato leggendo i tuoi post. grazie.gif

Filippo



Salta a inizio pagina | Per vedere la versione completa del forum Clicca qui.