490 likes | 634 Views
Acquisire ed elaborare immagini - Terza parte. Luca Capisani. Il Sistema Operativo Linux. E’ composto da tantissimi blocchi, i quali sono sviluppati da gruppi indipendenti di programmatori volontari E’ facilmente programmabile per interfacciarsi con la rete
E N D
Acquisire ed elaborare immagini -Terza parte Luca Capisani
Il Sistema Operativo Linux • E’ composto da tantissimi blocchi, i quali sono sviluppati da gruppi indipendenti di programmatori volontari • E’ facilmente programmabile per interfacciarsi con la rete • La configurazione della rete è semplice • Ci sono tanti strumenti che aiutano in caso di problemi • Offre gratuitamente tanti tool per la programmazione: • Compilatore C, C++, Java … • Editor • Librerie per fare qualunque cosa • Interagire con l’utente • Accedere alla rete • Convertire le immagini • Leggere e Memorizzare i dati sul disco
Linux: componenti fondamentali • Distribuzioni (Chi mette assieme le componenti fondamentali) • Kernel (il cuore del sistema operativo) • File system (gestisce i files di sistema e utenti) • Utenti e amministratore (Ciascuno ha le proprie regole!) • Interfaccia grafica (NON è parte fondamentale!) • Terminale (è il modo più diretto per accedere al sistema) • Sistema di rete (Offre tutti gli strumenti indispensabili e oltre!) • I pacchetti software (sono sempre accessori rispetto al “piccolo kernel”)
File system • E’ l’insieme di tutti i programmi e dello spazio di memoria che servono per • Memorizzare i files • Evitare perdita di dati • Ritrovare velocemente i dati • Lo spazio di memoria di Linux è tipicamente organizzato in 3 partizioni • root, “/”, mantiene l’albero principale delle directory • /home, mantiene i files dell’utente • swap, mantiene i files temporanei
Gli utenti e l’amministratore • In linux, ogni programma • Può essere creato solo da alcuni utenti • Può essere installato solo dall’amministratore o da chi ne ha il permesso • Può essere eseguito solo da chi ne ha il permesso • In linux, ogni file • Può essere letto solo da chi ne ha il permesso • Può essere scritto/cancellato solo da chi ne ha il permesso • Può essere eseguito (se è un programma) solo da chi ne ha il permesso • In linux, ogni risorsa (rete, periferiche, audio,video, …) • Può essere utilizzata solo da chi ne ha il permesso • L’amministratore (root) ha sempre tutti i permessi e può decidere i permessi degli altri
Gli utenti e l’amministratore (2) • Ogni utente: • Ha una “username” denominata login • Ha una password • Ogni utente può: • Cambiare la propria password • Cambiare i permessi dei propri files, dei propri programmi e delle proprie risorse • Gli utenti non possono: • Vedere alcuna password • Utilizzare programmi, files, risorse assegnate ad altri • L’amministratore (root) può: • Modificare le password di chiunque (non le può vedere) • Utilizzare e modificare qualunque programma, files o risorsa (rischio!!!)
Visualizzazione di un file con CAT • E’ il modo più veloce per visualizzare un file da terminale • Comando: cat /home/lab/pippo • Visualizza il file pippo nella cartella /home/lab
Visualizzazione di un file esadecimale con HEXDUMP • E’ il modo più veloce per visualizzare un file in esadecimale • Comando: hexdump /home/lab/pippo • Visualizza il file pippo nella cartella /home/lab
Rappresentazione delle immagini • Ciascuna immagine è rappresentata nel computer per mezzo di numeri (01000101110101101…) • L’area viene suddivisa in tanti piccoli quadrati colorati • Ci sono metodi efficienti per la memorizzazione • Vediamone i dettagli!
Come viene rappresentata una immagine? ZOOM! • Una immagine è una sequenza di tantissimi puntini colorati detti pixel(PICture ELement)
Dimensioni dell’immagine • Una immagine è una grande matrice di pixel: • La dimensione è il numero di pixel orizzontali x il numero di pixel verticali: • 640x480 • 800x600 • 1024x768 • Ecc. 5 colonne 4 righe
Colorazione pixel RGB! • Ogni pixel ha un colore unico! • Il colore del pixel è determinato in base a tre componenti fondamentali: • Rosso – R: 0-255 • Verde – G: 0-255 • Blu – B: 0-255 • In questo modo si possono ottenere più di 16 milioni di colori diversi (per ciascun pixel dell’immagine)! • 256*256*256= 16777216
Formati di immagine: cosa sono? • Considerando il numero di pixels e il numero di colori di ciascun pixel, una immagine occupa tantissimo spazio. • Una immagine si può memorizzare interamente così com’è • Formato RASTER: occupa molto spazio! • Esempio BMP • Oppure si può memorizzare in modo da ridurre lo spazio occupato: • Formato lossy. Esempio: JPG
I numeri esadecimali • Sono rappresentazioni particolari dei numeri binari. • Ogni numero è una cifra da 0 a F che corrisponde ai numeri da 0 a 15
Rappresentazione RGB esadecimale • Esempio: il pixel • È un mix dei colori: • Rosso: 224/255 Verde: 36/255 Blu: 36/255 • Si rappresenta su tre bytes RGB. • Una rappresentazione semplice si ha in hex • E02424 (E0 (224), 24 (36), 24(36))
Librerie di sistema: aiuto alla programmazione • Ci sono compiti che non dobbiamo risolvere noi programmatori: • Come si invia un dato sulla rete? • Come si scrive un carattere sul video? • Come si scrive un file? • Risposta? • Non ci interessa! • Ci sono librerie già fatte per fare queste operazioni, basta saperle usare!
Librerie di sistema: aiuto alla programmazione • Esempi: • #include <stdio.h>: contiene tutto ciò che ci serve per gestire la stampa di caratteri a video! • #include <sys/socket.h>, • #include <arpa/inet.h>, • #include <netdb.h>: contengono tutto ciò che ci serve per usare la rete! • #include <string.h>: contiene tutto ciò che ci serve per usare le stringhe! • Notare le parentesi < e >
Librerie utente: permettono di scrivere il codice una volta per tutte! • Esempio: Connettersi alla telecamera e richiedere una immagine è un problema ricorrente • E’ meglio avere un pezzo di codice che lo fa, senza doverci preoccupare ogni volta del problema! • Si includono con la sintassi • #include “libreria.h” • Notare le virgolette!!!
Blocchi fondamentali di un programma C • Sezione INCLUDE: • Serve per includere le librerie e altri files .c • #include <stdlib.h> • Con le parentesi < e > si includono le librerie di sistema • #include “mialib.h” • Con le virgolette si includono le librerie dell’utente (nella stessa cartella dei programmi) • Inlcudere un file significa mettere il file indicato al posto della parola include!!! • È come scrivere il codice al posto dell’include
Blocchi fondamentali di un programma C (2) • Sezione DEFINE: • Serve per definire le costanti • #defineimgX 640 • #defineimgY 480 • Hanno lo stesso effetto di sostituire il numero al nome della costante prima di compilare il codice! • Sezione del codice: • Metodi del programma • Sono le parti del programma • Metodo main() • Contiene quella parte di programma che viene chiamata non appena il programma parte • Al suo interno chiama le altre parti (metodi) del codice
Blocchi fondamentali: metodo main() intmain(intargc, constchar ** argv){ //Questo è un commento leggiDati(); calcolaQualcosa(); scriviLaRisposta(); return 0; //Non ci sono errori } E’ la prima porzione di codice che il processore elabora quando si esegue il programma!
Blocchi fondamentali: PRINTF() • La funzione printf()serve per visualizzare qualcosa all’utente • Comunicare una informazione all’utente. Esempio: • printf(“Ciao, come va?”); • Visualizza a video: • Ciao, come va?
Blocchi fondamentali: PRINTF() e i numeri • printf() può essere usata per stampare delle stringhe che contengono un MIX tra lettere e numeri: • ESEMPIO: int numero = 3; // Dichiarazione di un numero printf(“Il numero è %d”, numero) Il simbolo %d indica a printf che in quella posizione ci deve essere sostituito il numero!
ESEMPIO: Configurare la telecamera in diretta • 1 coppia alla volta http://172.16.205.50 • Accedere alla telecamera con la userid e la password di default • Impostare un indirizzo IP e una netmask ammissibile per la rete • Verificare e cambiare le impostazioni immagine/video • Controllare che le modifiche abbiano effetto • Non cambiare le password
Esempio: GIMP e le immagini esadecimali • Aprire GIMP con il comando gimp & da terminale • Creare una immagine nuova 1x1 pixel • Immettere un pixel di un certo colore RGB • Salvare l’immagine in uno dei seguenti formati: • PBM PGM XPM PPM BMP • Verificare con hexdump che cosa è stato scritto su disco • Ripetere l’esercizio con una immagine 3x3
Esempio: GIMP e le immagini esadecimali • Salvare in PPM ASCII • Visualizzare il file con CAT • Modificare l’immagine con GEDIT • Visualizzare le modifiche con GIMP • Modificare il colore del pixel centrale con un altro colore (bianco) • Provare a fare rosso/blu il pixel centrale • Provare a fare una scacchiera
Fare alcune prove confrontando i vari formati RASTER • Cosa cambia tra i vari formati raster? • Cosa cambia tra una immagine di 1 pixel e una di 9? • Cosa si vede salvando l’immagine come jpg?
Salvare tutte le informazioni su un file: fprintf()! #include <stdio.h> intmain(intargc, constchar ** argv){ FILE *fptr = fopen(“f.txt","w"); intannoNascita = 1982; inteta = 2008 – 1982; fprintf(fptr,“Luca Capisani, età %i”, eta); fclose(fptr); return 0; } • Per controllare che il file è corretto: catf.txtdopo aver eseguito il programma
Cicli FOR • Esempio: comunicare all’utente il conteggio da 1 a 10!!! • Procedura: • Scrivere 1; • Calcolare 1 + 1 = 2 • Scrivere 2; • Calcolare 2 + 1 = 3 • Scrivere 3; • Calcolare 3 + 1 = 4 • … • Le istruzioni si ripetono! • Come possiamo scrivere la stessa cosa più rapidamente???
Cicli FOR • Esempio: comunicare all’utente il conteggio da 1 a 10!!! • Non voglio ripetere le istruzioni uguali! • Procedura: • Imposto a = 0; • Inizio di un ciclo • a = a + 1 • Scrivo (a) • Mi fermo solo quando ho raggiunto il limite • Le istruzioni non si ripetono più! • Come possiamo scrivere la stessa cosa nel linguaggio C???
Esempio: Uso dei cicli #include <stdio.h> intmain(intargc, constchar ** argv){ int i; for (i = 0; i<10; ){ i = i+1; printf("i = %d\n" ,i); } return 0; }
Uso delle librerie di rete • Richiede di • Includere le librerie di rete • #include <sys/socket.h> • #include <arpa/inet.h> • #include <stdlib.h> • #include <netdb.h> • Configurare le impostazioni desiderate per la connesione • Creare la connessione • Utilizzarla per inviare/ricevere dati • Chiudere la connessione
Configurare la rete… struct sockaddr_in *remote; int tmpres; char *ip; char *get; char buf[BUFSIZ+1]; char *host; char *page; host = "192.168.121.12"; page = PAGE; sock = create_tcp_socket(); ip = get_ip(host); remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *)); remote->sin_family = AF_INET; tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr))); if( tmpres < 0) { perror("Can't set remote->sin_addr.s_addr"); exit(8); }else if(tmpres == 0){ fprintf(stderr, "%s is not a valid IP address\n", ip); exit(7); } remote->sin_port = htons(PORT); if(connect(sock, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){ perror("Could not connect"); exit(4); }
Un semplice programma per richiedere una immagine alla camera #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <netdb.h> #include <string.h> #include <unistd.h> #include "netHTTP.h" #include "mylib.h" int PORT=80; char* HOST = "192.168.121.12"; //char* PAGE = "/mjpg/video.mjpg"; char* PAGE = "/jpg/image.jpg"; int pktCount=0; void dataRec(void *data, unsigned long int l){ pktCount++; printf("Ricevuto pkt %d len %d\n", pktCount, l); } int main(int argc, char **argv) { tcpConnect(); sendHTTPRequest(); memset(buf,0,sizeof(buf)); while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0){ dataRec(buf,tmpres); } closeSock(); return 0; }
Librerie!! • Di sistema #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <netdb.h> #include <string.h> #include <unistd.h> • Utente #include "netHTTP.h" #include "mylib.h"
Parametri!! • Configurazione! int PORT=80; char* HOST = "192.168.121.12"; Voglio ricevere il filmato? //char* PAGE = "/mjpg/video.mjpg"; Voglio vedere solo “una foto”? char* PAGE = "/jpg/image.jpg";
Richiesta HTTP di una immagine • Connessione TCP alla telecamera • Avviene usando • l’indirizzo IP 192.168.x.x • e la Porta 80 • tcpConnect(); • Richiesta HTTP di tipo GET alla telecamera • Specifica il file che mi interessa e che cosa sono in grado di fare (le mie caratteristiche) • sendHTTPRequest();
Arriva l’immagine!!! • Preparo lo spazio di memoria memset(buf,0,sizeof(buf)); • Attendo ciasun “pacchetto” dalla rete e lo memorizzo while((tmpres=recv(sock,buf,BUFSIZ,0))> 0){ dataRec(buf,tmpres); }
Diagramma di flusso di connessione e richiesta INIZIO CONNESSIONE TCP RICHIESTA HTTP TRASFERIMENTO DI UN PACCHETTO FINE DATI??? NO! SI! CHIUSURA CONNESSIONE FINE
Dove va a finire la risposta? • Nel nostro caso la risposta della telecamera va persa! • Tuttavia si può memorizzare su un file • Alla fine possiamo visualizzare la foto con un comune programma da disegno!
Esercizio • Fate un programma che: • Si connetta alla telecamera; • Richieda l’invio di una immagine; • Legga l’immagine inviata dalla telecamera; • Sommando tutte le lunghezze dei pacchetti ricevuti dalla telecamera, vi dica quanto era lunga l’immagine.
I Buffers • Sono degli spazi di memoria di una certa dimensione • charbuf[1500]; • E’ un’area di memoria denominata bufe di lunghezza 1500 caratteri ASCII • Può contenere qualsiasi tipo di dato! • Una o più stringhe: “Ciao, come va?” • Uno o più numeri rappresentati in cifre decimali o in binario • Una immagine • Il buffer è caratterizzato da un indirizzo di memoria rappresentato dal suo nome: buf
Richiedere una immagine alla camera e memorizzarla su file senza buffer #include … #define PORT 80 #define HOST "192.168.121.12“ char* PAGE = "/jpg/image.jpg"; int pktCount=0; int main(int argc, char **argv) { FILE *outfile = fopen("frame.jpg","w"); tcpConnect(); sendHTTPRequest(); memset(buf,0,sizeof(buf));
Richiedere una immagine alla camera e memorizzarla su file senza buffer while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0){ fwrite(buf, 1, tmpres, outfile); } closeSock(); fclose(outfile); return 0; }
Richiedere una immagine alla camera e memorizzarla su file con i buffer …