Acquisire ed elaborare immagini
Seconda 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”)
Distribuzioni
• Dato che Linux è composto da tantissimi piccoli blocchi
programmati indipendentemente
– Alcune importanti organizzazioni si occupano di “mettere
assieme” i blocchi
– Per rendere più semplice ed immediata l’installazione
– Per favorire gli utenti non esperti
– Per assicurarsi che il sistema complessivo funzioni bene
– Per tener traccia di tutti gli ultimi aggiornamenti sulla
sicurezza
• Le più famose:
– Mandriva, Ubuntu, Fedora, SuSE, Knoppix, Debian, Gentoo,
Slackware…
– Elenco completo: http://www.linux.org/dist/list.html
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 “user name” 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!!!)
Il terminale
• E’ il modo più diretto per interagire con tutte le funzioni del sistema
operativo
• È dotato di un prompt che risponde ai comandi dell’utente
• Il prompt è gestito dalla shell
che aiuta l’utente a
– Velocizzare le operazioni
noiose
– Ricordare tutti i comandi
utilizzati
– Effettuare alcune operazioni
automaticamente
– Gestire l’interazione con i
programmi
Il comando sudo
• Entrare come amministratore (root) è pericoloso:
– Si possono cancellare, distruggere files e configurazioni
– Si può resettare la macchina senza autorizzazioni
• Soluzione: è meglio usare l’utente root solo quando è
necessario!!!
– Solo alcuni comandi richiedono di essere amministratore
– Basta scrivere prima del comando desiderato, il comando
sudo e inserire la password:
– Esempio:
• enzo@www-server:~$ sudo ifconfig
• [sudo] password for enzo: ****
• ………
– NB: la password non appare a terminale!!!
Impostare gli indirizzi di rete
• Un Computer (Host IP), per connettersi alla
rete, ha bisogno di:
– Un Indirizzo IP e una netmask
– Un indirizzo per il default gateway
– Un indirizzo del server DNS
• Tale indirizzo serve per tradurre i nomi degli host con gli
indirizzi IP
• La scheda di rete viene individuata con la sigla
eth0
Impostare gli indirizzi di rete (2)
• Indirizzo IP e netmask:
– sudo ifconfig eth0 192.168.x.x netmask 255.255.x.x
• Default gateway:
– sudo route del default (cancella una route esistente)
– sudo route add default gw 192.168.x.x
• Server DNS:
– sudo echo nameserver 151.99.x.x > /etc/resolv.conf
I pacchetti software
• Tutte le distribuzioni sono composte da pacchetti software:
Kernel
Glibc
(librerie)
XORG
(amb. Grafico)
netfilter
(firewall)
Bash
(shell)
libjpeg
(x le immagini!)
CUPS
(stampanti)
OpenOffice
(Word, Excel,…)
• Spesso l’istallazione di alcuni pacchetti rende indispensabile
l’installazione di altri pacchetti, struttura gerarchica!!!
Installare il software da Internet:
APT-GET INSTALL
• Scarica da Internet e installa automaticamente uno o
più pacchetti software andando a cercare
automaticamente le dipendenze
• Esempio: installazione editor GEDIT
– sudo apt-get install gedit
• Funziona solo sulle distribuzioni Debian-Ubuntu
– Mandriva: urpmi
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
Editing di un file con GEDIT
• E’ un editor che ha funzioni specifiche per
programmare.
• Si avvia da terminale con il comando gedit &
HTTP e l’autorizzazione
• La telecamera è accessibile da QUALUNQUE computer
connesso alla rete.
• Tuttavia solo chi è autorizzato può prelevare le immagini!
• Com’è il meccanismo di autorizzazione?
– La telecamera chiede nome utente e password
• root, guaita
– Firefox o Internet explorer macinano nome utente e password e
ottengono il digest
• cm9vdDpmcmFuY2VzY2E=
– Il digest viene inserito nella richiesta HTTP e la
telecamera è in grado di verificare se è giusto!
• Non è facile trovare “a caso” il digest giusto, quindi il
meccanismo è abbastanza sicuro. MAH…
Scambio di richieste risposte tra PC
(client) e telecamera (server)
• Richiesta:
GET /mjpg/image.jpg HTTP/1.1
Host: 192.168.121.12
User-Agent: Mozilla/5.0 (Windows; U;
Windows NT 5.1; it; rv:1.9.0.3)
Gecko/2008092417 Firefox/3.0.3
Accept:
image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: it-it,it;q=0.8,enus;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer:
http://192.168.121.12/view/view.shtml
?imagePath=/mjpg/video.mjpg&size=1
Authorization: Basic
cm9vdDpmcmFuY2VzY2E=
Nome del file richiesto e vers. HTTP
Indirizzo IP del server
Informazioni sull’applicazione
richiedente il servizio
Password di autorizzazione
DIGEST!!!!!!
Scambio di richieste risposte tra PC
(client) e telecamera (server)
• Risposta:
Il server risponde che la richiesta è
corretta!
HTTP/1.0 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Connection: close
Content-Type: multipart/x-mixed-replace; boundary=--myboundary
--myboundary
Content-Type: image/jpeg
Content-Length: 29423
......JFIF..
Ci informa che il contenuto richiesto è
una immagine JPEG ed è lunga 29423
bytes!!!!
Il JPEG inizia a essere trasmesso!!!!
Possiamo vedere il digest?
• Con il programma gratuito wireshark, si può vedere quali informazioni
vengono ricevute e quali vengono spedite dal nostro PC (tra cui il digest!):
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:
4 righe
– La dimensione è il numero di pixel orizzontali x il
numero di pixel verticali:
– 640x480
5 colonne
– 800x600
– 102x768
– Ecc.
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))
ESEMPIO: Configurare la telecamera in
diretta
• 1 coppia alla volta
• 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
Creare una immagine di pochi pixel
Impostare un colore
Colorare un pixel con quel colore, gli
altri in nero
Salvare l’immagine in uno dei formati
RASTER
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?
La programmazione nel linguaggio C
• Rende semplice interagire con la rete ed
elaborare le immagini
• Produce dei programmi estremamente veloci
• Non è indicato per creare programmi con
finestre e pulsanti
Cosa serve per poter programmare in
C
• Il compilatore GCC
• Le librerie di sistema (per aprire i files,
connettersi alla rete, interagire con l’utente, ecc.)
• Alcune librerie aggiuntive per leggere/scrivere
files jpeg
• Altre librerie contenenti funzioni già preparate
per eseguire i programmi che ci interessano
Linguaggio C: il sistema operativo
• Funzionalità offerte dal sistema operativo
– Interfacciamento con l’utente (terminale ecc)
– Rete
– File system
– Ecc.
Il compilatore C di linux: GCC!
• Il suo funzionamento è semplicissimo:
– gcc nomefile.c
• Produce un file eseguibile denominato a.out
– Si esegue con il comando ./a.out
• Importante!!! Saper leggere i messaggi di
errore di gcc!!!
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!
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!
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
#define imgX 640
#define imgY 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()
int main(int argc, const char ** 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!
Un semplice programma in linguaggio
C
Nome file: prova.c
#include <stdio.h>
int main(int argc, const char ** argv){
printf(“Ciao, come va?”);
return 0;
}
Copiare, salvare, compilare ed
eseguire l’esempio
• Copiare l’esempio con l’editor GEDIT
• Salvare il file .c
• Compilare con il comando gcc prova.c
• Eseguire con il comando ./a.out
Modificare l’esempio per scrivere il
proprio nome e cognome
• Cosa devo cambiare per fare scrivere il mio nome e
cognome?
• L’istruzione PRINTF serve per:
– Interagire con l’utente
– Comunicare all’utente qualcosa o il risultato
• NOTA: In questo momento noi siamo
contemporaneamente programmatori e utenti!
– Programmatori quando scriviamo il programma,
– Utenti quando eseguiamo il programma e ne verifichiamo
gli output interagendo con esso.
Scrivere nome, cognome ed età
Nome file: eta.c
#include <stdio.h>
int main(int argc, const char ** argv){
int annoNascita = 1982;
int eta = 2008 – 1982;
printf(“Luca Capisani, età %i”, eta);
return 0;
}
Scrivere nome, cognome ed età (2)
Nome file: eta.c
#include <stdio.h>
int main(int argc, const char ** argv){
int annoNascita = 1982;
int eta = 2008 – 1982;
printf(“Luca Capisani, nato nel %i età %i”,annoNascita, eta);
return 0;
}
Salvare tutte le informazioni su un file:
fprintf()!
#include <stdio.h>
int main(int argc, const char ** argv){
FILE *fptr = fopen(“f.txt","w");
int annoNascita = 1982;
int eta = 2008 – 1982;
fprintf(fptr,“Luca Capisani, età %i”, eta);
fclose(fptr);
return 0;
}
• Per controllare che il file è corretto: cat f.txt dopo aver
eseguito il programma
Blocchi fondamentali 2: le strutture di
controllo
• Nell’esercizio di prima, ogni istruzione viene eseguita nell’ordine indicato.
• A volte è necessario eseguire istruzioni solo se si verificano certe
condizioni
– Se piove
• Prendo l’ombrello
– Altrimenti
• Esco in bicicletta!
• A volte è necessario cambiare l’ordine delle istruzioni o ripetere
l’esecuzione di alcuni blocchi
– Per fare una torta
•
•
•
•
•
Aggiungere farina
Aggiungere olio
Aggiungere zucchero
Mescolare il tutto
Se non si amalgama, ricominciare dall’inizio
Istruzione condizionale IF THEN ELSE
•
Esempio: mi dice se sono maggiorenne
#include <stdio.h>
int main(int argc, const char ** argv){
int annoNascita = 1982;
int eta = 2008 – 1982;
printf(“Luca Capisani, età %i \n”, eta);
if (eta >= 18){
printf(“Sei maggiorenne! \n”);
} else {
printf(“Sei minorenne! \n”);
}
return 0;
}
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>
int main(int argc, const char ** 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
#include
#include
#include
<sys/socket.h>
<arpa/inet.h>
<stdlib.h>
<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
#include
#include
#include
#include
#include
#include
<stdio.h>
<sys/socket.h>
<arpa/inet.h>
<stdlib.h>
<netdb.h>
<string.h>
<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
#include
#include
#include
#include
#include
#include
<stdio.h>
<sys/socket.h>
<arpa/inet.h>
<stdlib.h>
<netdb.h>
<string.h>
<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
???
SI!
CHIUSURA
CONNESSIONE
FINE
NO!
Dove va a finire la risposta?
• Nel nostro caso la risposta della telecamera va
persa!
• Tuttavia vedremo la prossima volta come 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.
Scarica

Acquisire ed elaborare immagini