UNIVERSITA’ DEGLI STUDI DI GENOVA

 

FACOLTA’ DI INGEGNERIA

 

 

Corso di Laurea in Ingegneria

Elettronica

 

TESI DI LAUREA

 

 

 

STUDIO E REALIZZAZIONE DI TECNICHE PER IL RICONOSCIMENTO VOCALE



Relatore :        Chiar.mo Prof.  Francesco Curatelli

Studente :        Lorenzo Banderali

 

 

  Anno accademico: 2002 – 2003


 


 

Indice

 

Indice                                                                                                                                               2
Indice delle tabelle e delle figure                                                                                                   3

Abstract                                                                                                                                           5
Prefazione                                                                                                                                       7

Capitolo 1 : Funzionamento di un sistema di riconoscimento vocale                                           8

1.1 Teorema del campionamento                                                                                                       8

1.2 Acquisizione del segnale                                                                                                              9

1.3 Metodi di analisi del segnale                                                                                                         11

1.4 Passi della tecnica PLP                                                                                                                12

1.5 Memoria associativa                                                                                                                    15

1.6 Dinamic time warping                                                                                                                  17

1.7 Algoritmo di programmazione dinamica                                                                                        19

Capitolo 2 :Teoria ed algoritmi                                                                                                      20
2.1 Algoritmo Lloyd                                                                                                                          21
2.2 Algoritmo K-Means                                                                                                                    22

2.3 AlgoritmoVoronoi                                                                                                            22

Capitolo 3 : Ottimizzazione                                                                                                             26
Capitolo 4 : I programmi                                                                                                                29
4.1 Soluzioni principali e funzioni del programma                                                                                31
4.2 Programmi accessori                                                                                                                   34
Capitolo 5 : I risultati                                                                                                                     35
5.1 Risultati ottenuti tramite l’uso di Spear                                                                                          47
Capitolo 6 : Conclusioni                                                                                                                 63
Capitolo 7 : Appendice                                                                                                                   64
Bibliografia                                                                                                                                     110

 

 


Indice delle Tabelle e delle Figure

Capitolo 1 : Funzionamento di un sistema di riconoscimento vocale

Figura 1a: campionamento del segnale di ingresso                                                                               8
Figura 1b: Sistema a due sorgenti per la limitazione del rumore                                                10
Figura 1c: Passi della tecnica PLP                                                                                                      14
Figura 1d: rappresentazione dello spazio di train e di test                                                                    16
Figura 1e: Percorso di normalizzazione.                                                                                              18

Capitolo 2 : Teoria ed algoritmi

Figura 2.1a: spostamento dei vettori di riferimento                                                                               21

Figura 2.2b: celle di Voronoi                                                                                                              22

Figura 2.2c: ordinare tutti i punti in secondo x ascendente                                                                   22

Figura 2.2d: Dai primi due semi si genera il più semplice diagramma di Voronoi                                   24

Figura 2.2e: Generazione ed inserimento di una nuova linea bisettrice derivante
dalla considerazione del terzo punto e del primo                                                                                 24

Figura 2.2f: individuazione delle intersezioni tra le rette e creazione di una
nuova retta bisettrice dell’angolo formato dalle prime due rette                                                25

Figura 2.2g: termine dell’algoritmo                                                                                                     25

 

Capitolo 3 : Ottimizzazione
Figura 3 a: Insieme di partenza                                                                                               26

Figura 3 b: I punti neri sono stati disattivati                                                                                         26

Figura 3 c: Punti rimasti                                                                                                                      27

 

Capitolo 5 : I risultati

Figura 5 a: Lloyd  fatrid =  50 modo XàV                                                                                        35

Figura 5 b: k-means  fatrid =  50 modo XàV                                                                        36

Figura 5 c: k-means  fatrid =  10 modo XàV                                                                        37

Figura 5 d: k-means  fatrid =  10 modo XàVàV*                                                                           38

Figura 5 e: k-means  fatrid =  10 modo XàX*àV                                                                           39

Figura 5 f: Voronoi di k-means  fatrid =  10 modo  XàV                                                                  40

Figura 5 g: k-means  fatrid =  100 modo  XàV                                                                                 41

Figura 5 h: k-means  fatrid =  100 modo XàVàV*                                                             42

Figura 5 i: k-means  fatrid =  100 modo XàX*àV                                                              43

Figura 5 l: Voronoi  di k-means fatrid =  100 modo XàV                                                                 44

Figura 5 m: Voronoi  di k-means fatrid =  100 modo XàVàV*                                                       45

Figura 5 n: Voronoi  di k-means fatrid =  100 modo XàX*àV                                                        46

Tabella 5.1: Riconoscimento di file interni con la sessione 1 di anco e le
sue riduzioni con Lloyd modo X à V                                                                                    48

Grafico 5.1: Riconoscimento di file interni con la sessione 1 di anco e le
sue riduzioni con Lloyd modo X à V                                                                                    48

Tabella 5.2: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à V à V*                                                                         49

Grafico 5.2: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à V à V*                                                                         49

Tabella 5.3: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à X* à V                                                                         50

Grafico 5.3: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à X* à V                                                                         50

Tabella 5.4: Riconoscimento di file interni con tutte le sessioni di anco e
le sue riduzioni con Lloyd  modo X à V                                                                                           51

Grafico 5.4: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd  modo X à V                                                                                           51
Tabella 5.5: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à V à V*                                                                                  52

Grafico 5.5: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à V à V*                                                                                  52

Tabella 5.6: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à X* à V                                                                                  53

Grafico 5.6: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à X* à V                                                                                  53

Tabella 5.7: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-Means modo X à V                                                                                          54

Tabella 5.8: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-means modo X à V à V*                                                                                54

Tabella 5.9: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-Means modo X à X* à V                                                                               55

Tabella 5.10: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à V                                                                        55

Tabella 5.11: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à V à V*                                                             56

Tabella 5.12: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à X* à V                                                             56

Tabella 5.13: Riconoscimento di file interni con la sessione 1 di anco e le
sue riduzioni con Lloyd modo X à V                                                                                    57

Tabella 5.14: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à V à V*                                                                         57

Tabella 5.15: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con Lloyd modo X à X* à V                                                                         58

Tabella 5.16: Riconoscimento di file interni con tutte le sessioni di anco e
le sue riduzioni con Lloyd  modo X à V                                                                                           58

Tabella 5.17: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à V à V*                                                                                  59

Tabella 5.18: Riconoscimento di file interni con tutte le sessioni di anco e

le sue riduzioni con Lloyd modo X à X* à V                                                                                  59

Tabella 5.19: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-Means modo X à V                                                                                          60

Tabella 5.20: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-means modo X à V à V*                                                                                60

Tabella 5.21: Riconoscimento di file interni con la sessione 1 di anco e le

sue riduzioni con K-Means modo X à X* à V                                                                               61

Tabella 5.22: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à V                                                                        61

Tabella 5.23: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à V à V*                                                             62

Tabella 5.24: Riconoscimento di file interni con tutte le sessioni di anco

e le sue riduzioni con K-Means modo X à X* à V                                                             62

 

 

 

 

Studio e realizzazione di tecniche per il riconoscimento vocale

 

 

 

Abstract

 

The goal of our work has been that to improve the performance of an already existing vocal recognition system (Spear), based on the paradigm of associative memories. In particular, it has been afforded the task to decrease the overall computational time of the vocal recognition program by properly decreasing the number of vectors actually used by the associative memory to recognize speech utterances.

The method adopted is based on vector quantization by using some well-known tecniques for reducing the number of points.  In particular, the number of items belonging to the training set file are properly reduced through the application of either Lloyd or K-means algorithms.

Several tests have been performed for what concerns the percentage of  recognition of single-digit speech utterances provided by a  Italian segmented speech database, both for reduced and non-reduced training sets. The results have shown that training set redution yields acceptable decreasing in recognition percentages.

 

 

 

 

 

 

 

 

 

 


Ai miei cari , e a tutti

coloro che contribuiscono

all’informazione gratuita

tramite internet

Grazie

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Prefazione

Questa tesi si è svolta presso il Laboratorio di microelettronica  del Dipartimento di Ingegneria Elettronica (D.I.B.E.) dell’Università degli Studi di Genova.

Il riconoscimento vocale, grazie all’incremento delle prestazioni e all’abbattimento dei costi dei sistemi hardware e software che lo implementano, ha trovato largo uso in molte applicazioni. Ad esempio il riconoscimento vocale è stato inserito con successo nei telefoni cellulari per facilitare l’interazione tra l’utente ed i dispositivi, nelle stazioni  telefoniche con funzione di  centralino, ma anche in ambito medico per la refertazione automatica, ecc…  così permettendo un notevole risparmio di risorse umane.   In questa tesi, in particolare, si è affrontato il problema dello studio e della realizzazione di tecniche per il riconoscimento vocale attraverso l’ uso di  algoritmi come Lloyd e K-means  implementati da un programma scritto in visual C++ allo scopo di visualizzare graficamente dati contenuti nel file di ingresso e di elaborarli.

Lo scopo principale del programma è stato quello di ridurre il numero di dati presenti nel file di entrata  perdendo la minor informazione possibile; tale operazione permette di ridurre i tempi di esecuzione del programma di riconoscimento vocale “Spear”  con degrado accettabile nella precisione del riconoscimento vocale.

Le attività connesse alla tesi si sono svolte in detto laboratorio, con l’ausilio di materiale di studio fornito dal Relatore Accademico e mediante l’utilizzo di Internet .

 

 

 

 

 


Capitolo 1 : Funzionamento di un sistema di riconoscimento vocale

 

In accordo con la teoria dell’informazione, il parlato può essere rappresentato in termini del contenuto o dell’informazione che trasmette. Una visione alternativa permette di rappresentare il parlato in termini di segnale che trasporta l’informazione, ovvero l’onda sonora.

La voce umana è un segnale tempo-continuo che è possibile rappresentare come una funzione x(t) della variabile continua t .

Per comodità il segnale tempo-continuo viene convertito in una sequenza numerica x(n) dove i singoli valori della sequenza numerica sono detti campioni e sono equispaziati di una quantità Tc detta periodo di campionamento.



Figura 1a: campionamento del segnale di ingresso


L’uscita del sistema di campionamento ad un ingresso  puo’ essere descritta come:
 con


1.1
Teorema del campionamento

La condizione per cui la sequenza di campioni  sia una rappresentazione univoca del segnale analogico   è data dal teorema di campionamento: se un segnale  ha una trasformata di Fourier , limitata in banda, e tale che  per  allora  può essere univocamente ricostruito dalla sequenza  con  se  dove è la frequenza di Nyquist.

Se la condizione di Nyquist viene rispettata il segnale è ricostruibile tramite la formula di interpolazione:
 

1.2
Acquisizione del segnale

 

Fino ad ora si è visto come è possibile passare dal segnale tempo-continuo ad un segnale tempo-discreto per mezzo del campionamento, ma a monte di questa operazione, per ottenere una rappresentazione più robusta del parlato, possono essere applicati vari metodi, che hanno il compito di ridurre il rumore le distorsioni dovute ai canali di comunicazione, come le linee telefoniche o i microfoni, o alle distorsioni fisiologiche del parlato.

Successivamente, filtraggi ottenute con varie tecniche, possono migliorare ulteriormente la qualità del segnale acquisito.

Si procede all’analisi del parlato trasformando il segnale digitale in una sequenza spettrale; inoltre per ottenere una buona analisi sono stati sviluppati modelli matematici dell’udito, che tendono a riprodurre gli organi unmani oppure le caratteristiche acustiche dell’udito.

Per convertire un segnale dalla rappresentazione analogica a quella digitale sono necessari un certo numero di passi: innanzitutto il segnale deve essere acquisito da un microfono o da un array di microfoni , campionato e codificato in una rappresentazione digitale.

In base alla tecnica utilizzata per acquisire il segnale, il rumore ed il riverbero incidono in maniera differente sugli stadi successividell’analisi, per cui la fase di acquisizione non può essere sottovalutata se si vuole ottenere un buon risultato nel riconoscimento. Ad esempio, per limitare il rumore ambientale, vengono utilizzati tipi speciali di microfoni detti “close-talking” che sono microfoni da utilizzare molto vicino alle labbra.

Se il rumore ambientale è particolarmente elevato vengono utilizzati più microfoni , il cui segnale verrà elaborato da speciali algoritmi di riduzione del rumore che hanno bisogno di più di una sorgente di ingresso.

 



Figura 1b: Sistema a due sorgenti per la limitazione del rumore


1.3 Metodi di analisi del segnale


Per analizzare il segnale vocale sono stati studiati vari modelli per avvicinarsi al sistema uditivo umano.
Un modello per simulare l’udito può essere sviluppato in due maniere:
 - secondo un approccio strutturale o fisiologico

- secondo un approccio funzionale

Con il primo approccio ci si aspetta una modellazione di tutti i fonemi osservati, con il secondo sono modellati solo gli aspetti più importanti.

Viene spesso preferito il secondo approccio, perché l’obiettivo è quello di inserire il modello per l’udito in un front-end per il riconoscimento del parlato, inoltre non si è ancora in grado di descrivere tutti i meccanismi dell’udito.

Tra i modelli maggiormante utilizzati troviamo il modello LP (linear prediction) ed il modello PLP (perceptually – based linear prediction) che è una delle più importanti tecniche di analisi del parlato poiché permette di stimare con accuratezza i parametri del parlato in modo veloce.
Il modello PLP è un approccio relativamente nuovo basato su una funzione a soli poli ed una tecnica di autocorrelazione. Il modello prevede l’introduzione della “critical-band” delo spettro di potenza del parlato, della preenfasi “equal-loudness” e per la compressione “cubic-root intensity loudness”.
In seguito viene applicato un modello a soli poli del quint’ordine che ha anche il vantaggio di enfatizzare i picchi spettrali.

Nell’analisi viene utilizzato il modello autoregressivo a soli poli , , dello “short-term power spectrum”  stimato attraverso il modello LP. Se l’ordine del modello è scelto appropriatamente ,  approssima bene le aree di alta concentrazione di energia di  e smorza i dettagli meno rilevanti dello spettro. Tali aree spesso corrispondono alle frequenze di risonanza del tratto vocale (formanti).

 


1.4 Passi della tecnica PLP

-         Analisi Spettrale.

Il parlato viene segmentato utilizzando la finestratura di “Hamming”  dove N è la lunghezza della finestra (tipicamente 20 ms).
La trasformata di Fourier discreta (DFT) permette poi di passare nel dominio delle frequenze (per ottimizzare i tempi di calcolo normalmente viene utilizzata la Fast Fourier Transform FFT). Per una frequenza di campionamento pari a 10 kHz, occorrono 256 punti della FFT per trasformare i 200 campioni che costruiscono la finestra (56 valori sono nulli). A questo punto è possibile calcolare lo short-term power spectrum:

 
dove è il valore della FFT alla frequenza .

 

-         Risoluzione Spettrale della banda critica.

Lo spettro   viene trasformato dal dominio delle frequenze al dominio delle frequenze di Bark per mezzo della relazione:

 
dove  è la frequenza angolare in rad/s. Il risultato della trasformazione viene poi convoluito con lo spettro di potenza di una banda critica simulata. Nella tecnica PLP, la curva della banda critica è data dalla funzione:




La convoluzione discreta di  con  produce i campioni dello spettro di potenza della banda critica:


La convoluzione della banda critica con la funzione riduce in modo significativo la risoluzione spettrale di rispetto all’originale . In questo metodo è campionata con intervalli di l-Bark, il valore esatto dell’ampiezza di tali intervalli viene scelto in modo che sia un numero intero di campioni spettrali a coprire l’intera banda di analisi. Tipicamente vengono utilizzati 18 campioni spettrali di  per coprire l’intera banda di analisi di Bark che va da 0 a 16.9 (0-5 Hz) in 0.994 Bark-steps.

 

-         Equal-loudness preemphasis.

La funzione campionata   viene preenfatizzata con la curva equal-loudness simulata dalla relazione:


La funzione  è un’approssimazione del fatto che l’udito umano ha una diversa sensibilità a differenti frequenze e simula proprio questa sensibilità ad un livello di circa 40dB. La particolare approssimazione adottata è la seguente:


Questa è la funzione di trasferimento di un filtro con asintoti a 12 dB/oct tra 0 e 400 Hz, 0 dB/oct  tra 400 e 1200 Hz, 6 dB/oct tra 1200 e 3100 Hz, e 0 dB/oct tra 3100 Hz e la frequenza di Nyquist. Per limitare i livelli del suono, questa approssimazione è buona oltre i 5000 Hz.
Per applicazioni che richiedono frequenze di nyquist elevate, viene aggiunto un termine all’equazione che rappresenta un ulteriore decremento della sensibilità dell’udito per frequenze oltre i 5000 Hz (circa –18 dB/oct), avremo quindi:



-         Intesdity-loudness power law.

L’ultima operazione da compiere, prima di applicare il modello a soli poli, è quella di effettuare la compressione dell’ampiezza secondo la seguente relazione:

Questa operazione è un’approssimazione della power law of hearing e simula la relzione non lineare tra l’itensità del suono e il loudness percepito. Questa operazione riduce anche la variazione dell’ampiezza dello spettro della banda critica, cosicché il modello a soli poli possa essere realizzato per mezzo di un modello di ordine relativamente basso.

Figura 1c: Passi della tecnica PLP

 

-         Modello Autoregressivo.

Nell’ultima operazione dell’analisi PLP, è approssimata con lo spettro di un modello a soli poli, a questo punto si applica la trasformata discreta inversa (IDFT) per ottenere la funzione di autocorrelazione duali di . La scelta della IDFT invece che della IFFT è migliore in quanto servono solo pochi valori di autocorrelazione. I primi M+1 valori vengono usati per risolvere le equazioni di Yule-Walker per trovare i coefficienti autoregressivi del modello a soli poli M-esimo ordine.

Tali coefficienti possono essere poi trasformati in altri tipi di parametri.

 


1.5 Memoria associativa

La memoria associativa è utilizzata per analizzare e classificare i parametri del parlato, estratti tramite la tecnica PLP ed associarli ad un set predefinito di caratteristiche, che rendono possibile il riconoscimento della forma d’onda.

Tra tutte le tecniche la memoria associativa è stata ,in un primo momento, quella che ha riflettuto nel migliore dei modi l’intenzione di emulare la natura associativa del cervello umano. Per questa ragione tali memorie sono state largamente studiatre negli anni ’80, ma presto ,con l’avanzare della ricerca, sono state sostituite con altri modelli. Comunque in molti campi di applicazione queste memorie mostrano ancora molti vantaggi rispetto ad altri metodi. Tali vantaggi sono messi in luce dalle applicazioni che necessitano di una rapplresentazione vettoriale dei dati, e da quelle dove sia necessario che i tempi di addestramento siano molto ridotti; inoltre tali memorie non commettono alcun errore se vengono testate con patterns utilizza ti in fase di addestramento.
Il metodo classico usa il contribuuto di tutti i patterns addestrati, Un test patten è definito da:

dove  rappresenta l’informazine della fase associata ad ogni variabile del test di pattern, mentre  rappresenta il livello pesato di confidenza.

per ottenere una risposta associata al test di pattern, occore un’operazione di decodifica effettuata con la matrice . Questa operazione consiste nel moltiplicare ogni variabile  con il suo corrispondente neurone nella memoria.

La risposta è data da


dove c è il coefficiente di normalizzazione e rappresenta il contributo di  per ogni test pattern ed è dato da

Ogni risposta generata è rappresentata dalla somma di vettori complessi in relazione al contributo di ogni variabile di ogni simbolo addestratodei confronti del test pattern presentato. Tale risposta è data da

che può essere scritta come


L’espressione precedente mostra una sequenza di contributi dati dagli elementi di ogni train pattern ad una specifica risposta r. Questa espressione può essere riscritta nella forma compatta così:

dove  e  sono i contributi alla risposta dati rispettivamente dal modulo pesato e dalla fase di ogni pattern addestrato, confrontato con lo stimolo di test. Così la coppia train-test più vicina costituisce l’attrattore dominante ed influenza la risposta più degli altri patterns. In altre parole, più l’orientazione del train pattern coincide con lo stimolo di test, più influenza ha nell’orientazione della risposta finale.

Ogni singolo contributo può essere scritto nella forma:


Evidenziando separatamente, dall’equazione precedente, modulo e fase, si ottiene:


Il metodo classico di decodifica viene riassunto nella seguente figura:

Figura 1d: rappresentazione dello spazio di train e di test

La figura di sinistra rappresenta la configurazione del train test, mentre quella a destra indica il modo in cui viene associato in risposta per ogni coppia di train test, e come la somma normalizzata di questa risposta dà l’associazione finale.

La risposta nel dominio reale viene calcolata utilizzando la funzione inversa della sigmoide:
 
 
1.6 Dinamic time warping


Il problema dell’Automatic Speech Recognition (ASR) può essere schematizzato come la decodifica delle informazioni contenute in un segnale vocale, e la loro trascrizione in un insieme di caratteri.
A seconda delle condizioni di lavoro la complessità del problema varia notevolmente: i principali fattori da tenere in considerazione sono:

- il numero dei parlatori

- tipo di parlato (parole isolate, parlato continuo, parlato spontaneo)

- dimensione del vocabolario

- complessità del linguaggio

- condizioni ambientali e qualità del segnale vocale


Un sistema di riconoscimento del parlato opera in due fasi:

- una fase di training, durante la quale il sistema acquisisce i pattern di riferimento rappresentativi dei suoni associati alle varie parole costituenti il vocabolario.
- una fase di riconoscimento, durante la quale un pattern di ingresso sconosciuto viene identificato basandosi sull’insieme dei riferimenti. Il processo è costituito essenzialmente da tre passi:

  1. classificazione dei pattern: viene calcolata una qualche misura di somiglianza tra l’ingresso
    e ogni pattern di riferimento. A questo scopo è necessario definire una qualche misura di vicinanza tra i vettori di caratteristiche e trovare metodi per allineare due speech patters che possono avere lunghezze diverse
  2. decisione: passo finale nel quale al pattern riconosciuto viene associato il più vicino pattern di riconoscimento. La decisione si basa su regole che tengano conto del risultato delle misure di somiglianza.  

Un pattern corrisponde ad una parola ed è composto da una sequenza di vettori acustici. La maggior difficoltà nell’applicazione all’ASR delle tecniche di pattern recognition deriva dal fatto che occorre comparare sequenze di vettori di lunghezze diverse, in quanto diverse occorrenze della stessa parola, anche pronunciate dallo stesso parlatore, differiscono tra di loro in durata e rate. Siccome queste distorsioni sono in generale non lineari, è necessario progettare efficienti metodi per effettuare una comparazione affidabile.

Siano X e Y due speech pattern isolati, ad esempio due parole, composte da una sequenza di vettori  e  rispettivamente la distorsione tra X ed Y, che indicheremo con d(i,j).
Il non-linear time warping dei pattern X ed Y può essere rappresentato come un percorso  nel piano (i,j) definito dalle due sequenze di vettori X ed Y.
La distorsione tra X ed Y lungo il percorso P è data dalla formula:

 
dove  è un opportuno coefficiente ed  un fattore di normalizzazione.
Lo scopo è trovare il percorso che minimizzi  tra tutti i possibili percorsi  in modo da avere una distorsione.


Questo problema di minimizzazione può essere risolto usando tecniche che si ispirano direttamente alla programmazione dinamica.



 Figura 1e: Percorso di normalizzazione.

 

 


1.7 Algoritmo di programmazione dinamica


La programmazione dinamica è stata largamente usata per risolvere i problemi di ottimizzazione;
per tenere conto degli aspetti fisici del problema e per limitare il numero di percorsi (warping path) è stato necessario imporre i seguenti vincoli:

- utterance endpoints: gli endpoints sono i  limiti temporali entro i quali deve prendere posto la normalizzazione. Si vuole che il percorso sia tale che  P( 1 ) = ( 1 , 1 )    e   P( K ) = ( I , J ) .
- monotonocità: questo vincolo si riferisce all’ordine temporale fissato dei vettori successivi in uno speech pattern. Per mantenere questo ordine è necessario imporre una condizione di monotonicità che implica che il percorso P( K ) non può avere una pendenza negativa.
-  continuità locale: si vuole minimizzare la perdita di informazione locale necessaria per l’identificazione di un utterance. Tale vincolo può essere convenientemente formalizzato in termini di passi permessi lungo il percorso.

- pendenza del percorso: sono state testate svariate funzioni euristiche per esprimere il coefficiente . Quella scelta è stata .

Il coefficiente di normalizzazione  viene solitamente scelto in modo che le distorsioni siano indipendenti dalle durate dei pattern X ed Y. Ad esempio , relativamente alla  scelta,  può essere rappresentato come .

Per risolvere il problema dell’ottimizzazione relativo al calcolo della distorsione tra i pattern X ed Y, la formula di ricorsione locale usata è :

 
dove è la distanza accumulata lungo il percorso ottimale dall’origine (1,1) fino al punto (i,j).
Da notare come l’espressione di g(i,j) tenga conto del coefficiente .


 

 

       




 


Capitolo 2 : Teoria ed algoritmi

 


Il riconoscimento vocale effettuato dal programma Spear prevede l'utilizzo di un training set contenente i vari fonemi delle parole da individuare. La lunghezza del training set dipende quindi essenzialmente dal numero dei fonemi, nonchè dal numero dei soggetti addestrati.

E' chiaro che, col crescere di questi due fattori fondamentali, le dimensioni del file aumentano drasticamente e con esse anche il tempo impiegato dal programma per riconoscere una parola.

Gli algoritmi che sono alla base del programma (Lloyd e K-means) cercano di ridurre notevolmente tali parametri, cercando di non perdere le informazioni necessarie al riconoscimento.

Se, cioè, un singolo fonema e' contraddistinto da k punti in un N-spazio, mediante l'algoritmo si cerca di portare tali punti ad un valore più piccolo di diversi ordini di grandezza (es. k/100).

Compito dei due algoritmi e' quindi minimizzare l'errore che si compie in questa riduzione.

Il principale problema affrontato e' stata la realizzazione di un modulo flessibile che consentisse al programma di funzionare anche in seguito a cambiamenti nel file di training, come ad esempio una riduzione di classi (fonemi) o del numero dei parametri che le contraddistinguono. Mi sono inoltre proposto di rendere scalabile il fattore di riduzione delle classi.

I due algoritmi utilizzati sono molto simili, e praticamente differiscono per il numero di passi in cui vengono eseguiti. Infatti, mentre l'algoritmo di Lloyd converge, quello dei K-Means prevede un numero massimo di iterazioni.

L'algoritmo di Lloyd parte dalla definizione casuale dei vettori finali, che verranno spostati nei passi successivi. In realtà, la definizione di tali vettori non e' del tutto casuale, ma viene fatta in modo da avere già in partenza un numero di punti sufficienti per ogni classe.

In seguito si passa a definire il Voronoi set (VS), un'area dell' N-spazio che fa riferimento ad un solo vettore. In pratica, si scandiscono tutti i vettori del set di partenza e per essi si cerca il  “vincitore", quello, cioè, più vicino.

Il VS e' rappresentato da tutti i vettori più vicini ad uno di riferimento. Fatto questo per ogni classe si può passare a ricalcolare la posizione dei vari vettori.

Ognuno di questi viene calcolato come la somma di tutti i vettori del suo VS, diviso il loro numero.

E' dimostrato che l'algoritmo converge, e questo avviene quando nessuno dei vettori viene più spostato.

L'algoritmo dei K-Means prevede, invece, la cosiddetta on-line update, cioè , invece di calcolare il VS, ogni vettore viene spostato singolarmente.

Questo algoritmo termina dopo un numero di iterazioni che e' possibile scegliere.

 

 

2.1 Algoritmo di LLOYD

 

L’algoritmo di Lloyd (conosciuto anche con il nome LBG) lavora muovendo ripetitivamente tutti i valori di riferimento alla media del loro Voronoi Set.

Questo è  fatto per minimizzare l’errore di distorsione:

dovuto al fatto che ogni vettore di riferimento w si posiziona come centroide di un insieme di punti.  Questo fa si che alcuni punti che farebbero riferimento allo stesso vettore (e quindi a quella specifica classe) finiscono per fare riferimento ad altri.

Se “A” è l’insieme dei punti di riferimento, mentre D è l’insieme del training set di partenza, l’algoritmo procede come di seguito:

1. Si inizializza l’insieme A=C1,C2,…..,Cn che contiene N unità con vettori di riferimento w scelti a caso dall’insieme D di partenza.

2. Si calcola per ogni vettore w il suo Voronoi Set R.

3. Si muove ogni vettore w alla media del suo Voronoi Set R.

4. Se al passo 3 almeno uno dei vettori w si è mosso si ritorna al passo 2.
5. Fine dell’algoritmo.

 

I passi 2 e 3 sono chiamati Lloyd iteration e garantiscono che l’errore di distorsione sia decrementato o almeno lasciato inalterato. E’ dimostrabile che l’algoritmo converge in un numero finito di iterazioni.


Figura 2.1a: spostamento dei vettori di riferimento

 

2.2 Algoritmo K-MEANS

In alcuni casi l’insieme di partenza D è talmente grande che praticare l’LBG è impossibile.
 In questo caso conviene utilizzare l’algoritmo dei K-Means.

Non è prevista la convergenza, è necessario pertanto impostare un numero massimo di iterazioni. Inoltre, come già detto, non è necessario calcolare il Voronoi Set.

L’algoritmo procede come di seguito.

 

1. Si inizializza l’insieme A=C1,C2,….Cn che contiene N unità con i vettori di riferimento w scelti a caso dall’insieme D di partenza.
2. Si considera il segnale di ingresso  preso dal set D.

3. Si determina il vincitore s cioè il punto di riferimento più vicino a

4. Si sposta il vettore di riferimento ws del vincitore s.

5. Finchè non si è raggiunto il numero massimo di passi si continua con il passo 2.

Nell’algoritmo compare il parametro   detto “learning rate”, che determina lo spostamento di ws. Questo parametro può essere reso costante oppure decrescente, come nel caso del KM decrescente come 1/t dove t rappresenta il numero del passo dell’algoritmo.

Ovviamente, poiché non ci si ferma quando l’algoritmo converge (cosa non prevista), un numero non sufficiente di passi potrebbe dare risultati non adeguati, così come un numero troppo elevato potrebbe far eseguire calcoli superflui.

L’errore che si commette utilizzando questo algoritmo è comunque maggiore di quello ottenuto attraverso l’utilizzo di Lloyd.

 

2.2 Diagrammi di VORONOI  

Si è implementato l’algoritmo che permette di generare il diagramma di Voronoi che è così definito:

 

Def: Un diagramma di Voronoi calcolato su un numero di semi di un piano euclideo P = (p1 , p2 , p3 , …. ) permette di dividere il piano assegnando a ciascun punto il seme più vicino.

 

Una regione di Voronoi ( anche detta cella di Voronoi ) raggruppa tutti i punti di un piano assegnati ad un medesimo seme. In termini matematici possiamo scrivere:

V(pi) = { x: |pi - x| <= |pj- x| For all j != i}

dove V(pi) è la cella di Voronoi.

 Figura 2.2b: celle di Voronoi.

Il principio base è il seguente: per ciascun seme del piano determinare la linea formata dai punti equidistanti tra il seme e gli atri  semi ed unire i semipiani che si creano.
Le immagini seguenti mostrano come opera l’algoritmo:

Figura 2.2c: ordinare tutti i punti in secondo x ascendente.

 

Figura 2.2d: Dai primi due semi si genera il più semplice diagramma di Voronoi.


Figura 2.2e: Generazione ed inserimento di una nuova linea bisettrice derivante dalla considerazione del terzo punto e del primo.

Figura 2.2f: individuazione delle intersezioni tra le rette e creazione di una nuova retta bisettrice dell’angolo formato dalle prime due rette.

Figura 2.2g: termine dell’algoritmo.
Il costo computazionale O di questo algoritmo è:

-         caso migliore

-         caso peggiore

-         caso medio

 

 


Capitolo 3 : Ottimizzazione

 

Per rendere ulteriormente più veloce l’esecuzione del programma Spear o gli algoritmi Lloyd e K-Means sono stati realizzati 2 metodi di riduzione che agiscono rispettivamente prima e dopo aver eseguito gli algoritmi Lloyd e K-means.

Il metodo agisce eliminando quei punti di ciascuna classe che risultino essere più vicini a quelli  di un’altra rispetto alla loro.

Le immagini seguenti mostrano indicativamente come opera il criterio:

 

Figura 3a: Insieme di partenza.

Figura 3b: I punti neri sono stati disattivati.

Figura 3c: Punti rimasti.

Per individuare quali punti devono essere disattivati si considera ogni punto di ciascuna classe e si calcola la distanza tra il punto e tutti gli altri.

Per ciascun punto si sommano le distanze appena calcolate rispetto alla medesima classe di appartenenza e alle altre e si divide per il numero totale dei punti contenuti nella classe.

Infine si confrontano i valori ottenuti: se la distanza tra il punto e tutti i punti della propria classe di appartenenza , diviso il numero di punti della classe, è minore delle distanze tra il punto e i punti di ciascun’altra classe, diviso il numero di punti totali di ogni classe, allora il punto viene mantenuto. In caso contrario viene disattivato.

Si può operare attraverso i passi seguenti:

Per ogni punto considerato:

dove:

= distanza

* = classe del punto considerato

= punti totali per la classe del punto considerato 

            = punto per ogni classe 

* = tutte le classi (da 0 ad nc dove nc = totale classi)

 = numero totale di punti per la classe cl1

 

Se   allora il punto è mantenuto.

 

Questo metodo consente ,nella maggior parte dei casi, di ridurre notevolmente il numero dei punti e/o dei campioni (mediamente del 50%) e di rendere molto più definite le classi.

 

 

 

 

 

 

 

 

 

 

 

 

 


Capitolo 4 : I programmi


Il programma “lk” nasce dalla modifica di un codice base già esistente privo di interfaccia grafica che effettuava una riduzione di vettori tramite l’uso degli algoritmi di Lloyd e dei K-means.
Le modifiche effettuate riguardano  la costruzione  di un’interfaccia grafica per Windows, ma anche la possibilità di effettuare ulteriori riduzioni sui dati di ingresso attraverso l’implementazione nuove metodologie.

Il programma principale realizzato prevede la possibilità di aprire un file in ingresso contenente i dati e di visualizzarli in una finestra. La visualizzazione è bidimensionale, ma è possibile scegliere quali dimensioni vengano mostrate nella finestra: le dimensioni corrispondono ai parametri, che per il sistema di acquisizione PLP da noi usato sono 6.

 I dati in ingresso vengono visualizzati come dei cerchi pieni colorati: il colore ne indica la classe di appartenenza. E’ inoltre possibile selezionare la grandezza dei cerchi visualizzati ( per ottimizzarne la visualizzazione a seconda del numero e della disposizione degli stessi).
Per quanto riguarda la riduzione dei dati attraverso gli algoritmi  Lloyd e  K-Means è possibile selezionare il fattore di riduzione. Questo valore, indicato con il nome “fatrid”, è per default pari a 50 e rappresenta il numero per cui si vuole scalare il set di partenza. Se, ad esempio, si ha un insieme di 1000 e si sceglie di utilizzare 100 come fattore di riduzione, alla fine si avranno 100 punti. Il programma prevede comunque che per ogni classe vi sia almeno un punto.
Un altro parametro modificabile è il numero di iterazioni (passi) compiuti nel caso della riduzione tramite K-Means : infatti questo algoritmo non converge ed è necessario che l’utente fissi il numero di passi da eseguire. 

Selezionando dal menu  “execute” la voce “modo”  è possibile selezionare il tipo di riduzione:

X à V

Non effettua alcuna riduzione.

X à V à V*

Riduce il numero dei campioni dopo aver calcolato gli algoritmi.

X à X* à V

Riduce il numero dei punti su cui calcolare gli algoritmi.

 

Se si vuole visualizzare il diagramma di Voronoi calcolato sui campioni, ovvero sui punti finali calcolati in precedenza attraverso gli algoritmi Lloyd e K-Means è necessario selezionare “Voronoi” dalla tendina “execute”. E’ possibile anche definirne i seguenti parametri:

-         passo : precisione con cui viene disegnato il diagramma sullo schermo. Piu’ il passo è piccolo maggiore è il tempo di esecuzione, che però è totalmente indipendente dalla complessità del diagramma che si visualizza.

-         modalità colori : permette di scegliere tra due set diversi di colori e può essere utile per avere maggiore visibilità in alcune situazioni.

-         assi : visualizza tutti gli assi tra i tutti i campioni rappresentati (utile nella fase di test).

-         intersez : individua le intersezioni tra i vari assi (utile nella fase di test).

-         campioni : permette di visualizzare o di nascondere i campioni che danno luogo al diagramma.   

-         classe : permette di specificare la classe di cui si vuole visualizzare il diagramma di Voronoi.

 

Attraverso il menu “View” è possibile specificare i seguenti parametri:

-         Asse x : specifica quale dimensione rappresentare come asse x nella finestra.

-         Asse y: specifica quale dimensione rappresentare come asse x nella finestra.

-     Dim punti : specifica la dimensione con cui i punti vengono visualizzati.

-     Dim campioni : specifica la dimensione con cui i campioni vengono visualizzati.

 

 

 

 

 

 


4.1 Soluzioni principali e funzioni del programma

 

VISUALIZZAZIONE

Nel corso della realizzazione del programma principale sono emersi dei problemi per i quali sono state trovate soluzioni.

A esempio è utile poter visualizzare nella finestra del programma tutti i dati che vengono elaborati , anche se non si conosce a priori che valori assumano.

E’ necessario effettuare una stima del  valore minimo e massimo che raggiunge il set di dati da elaborare, considerando invece che i campioni provenienti da successive riduzione rimangano sempre all’interno di tali valori. Tali valori permettono di calcolare alcuni coefficienti che verranno moltiplicati per ogni punto in modo da averne una rappresentazione fedele sempre nel campo visibile della finestra del programma, lasciando lo spazio per la “barra di stato”.

Per ogni punto che dovrà essere rappresentato sarà necessario moltiplicarlo per il coefficiente moltiplicativo e sommare l’offset.

 

ALLOCAZIONE MEMORIA

Un altro problema è la creazione delle matrici multidimensionali: infatti è impossibile conoscere a priori il numero di classi, parametri e punti che dovranno essere letti ed elaborati. E’ necessario che le matrici vengano costruite in maniera dinamica, anche per ottimizzare l’utilizzo della memoria da parte del programma.

Un esempio molto semplice è il seguente:

bool ***att; // viene dichiarata all’inizio del codice (se variabile globale)

Viene lanciata una volta soltanto la procedura che crea la matrice quando si sono determinate le dimensioni che dovrà avere.

void creaatt()  // crea la matrice per la attivazione / disattivazione dei punti

{

            att = new bool**[NUMCLASS];

            int s = 0;

            int z = 0;

 

            while (s<NUMCLASS)

            {

                        att[s] =  new bool*[thetal[s]];

                        while (z<thetal[s])

                        {

                                   att[s][z] =  new bool[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

           

}

In questo modo, più complicato di un dimensionamento statico, ma più performante, si alloca solo la memoria che verrà effettivamente utilizzata.
 

 

 

PROGRESSBAR

Talvolta le elaborazioni, a causa della lentezza del calcolatore o della considerevole mole dei dati, si prolungano nel tempo anche per qualche minuto.

Per fornire all’utente una stima di quanto tempo dovrà ancora trascorrere per terminare l’operazione è stata aggiunta una progressbar, ovvero una barra formata da 10 segmenti la cui accensione in progressione indica l’avanzamento dei calcoli.

La progressbar è realizzata tramite una procedura che viene chiamata ad esempio all’interno di un ciclo For  nel quale vengono eseguiti tutti i calcoli, caso molto frequente per questo programma.
La procedura:

void progressbar(int par , int tot)

Stampa a video la progressbar e deve ricevere come parametri 2 interi che rappresentano il massimo valore possibile (tipicamente il termine del ciclo) ed il valore corrente.

 

STATUSBAR
La barra di stato, situata nella parte bassa della finestra, è uno spazio in cui vengono annotati tutti i settaggi principali e le operazioni eseguite in modo tale da informare l’utente sul significato di quanto viene visualizzato nella finestra.

Ad esempio vengono indicate le dimensioni x ed y rappresentate, quale algoritmo è stato utilizzato o quale classe è correntemente visualizzata tramite Voronoi.

 

SALVATAGGIO

Il programma prevede che l’utente possa salvare i risultati ottenuti ad esempio per poterli elaborare attraverso altri programmi come Spear.

Poiché spesso ci si dimentica di salvare gli ultimi dati, è possibile che il programma effettui un salvataggio automatico  ogni volta che vengono modificati. Per sfruttare questa comoda opzione basta attivarla dal menu “File”.


4.2 Programmi accessori

 

Sono stati realizzati anche 2 altri programmi di supporto:

Il primo programma, scritto in qbasic, è molto semplice ed è stato utilizzato unicamente come semplice riscontro e come ulteriore visualizzatore. Il programma non compie alcuna elaborazione, ma tramite la lettura del file contenete i dati sorgenti e del file contente i dati elaborati permette di visualizzare i dati contestualmente in una finestra. E’ stato scelto questo linguaggio per la semplicità e per velocità di programmazione , purtroppo non è particolarmente performante, ma non dovendo effettuare alcun calcolo di rilievo i tempi di esecuzione si mantengono contenuti.
Il secondo programma offre la possibilità di visionare i dati, dopo averli elaborati tramite Lloyd e k-means, in 3 dimensioni.

 Tale visualizzazione tridimensionale prevede anche una rotazione modificabile secondo i diversi assi tale da poter vedere contemporaneamente il massimo dei parametri possibili confondendoli il meno possibile.



 

 

 

 

 

 

 

 


Capitolo 5 : I risultati

I risultati seguenti comprendono la maggior parte dei casi di funzionamento corrispondenti a differenti files di dati in ingresso ed alle principali elaborazioni possibili su questi.
Nelle immagini seguenti ( a,b,c,d,e,f ) vengono rappresentate elaborazioni su una mole modesta di dati tramite k-means e Lloyd con differenti parametri.

 

Figura 5a: Lloyd  fatrid =  50 modo XàV

Figura 5b: k-means  fatrid =  50 modo XàV

 

Figura 5c: k-means  fatrid =  10 modo XàV

 

Figura 5d: k-means  fatrid =  10 modo XàVàV*

 

 

 

Figura 5e: k-means  fatrid =  10 modo XàX*àV

 

 

Figura 5f: Voronoi di k-means  fatrid =  10 modo  XàV

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Nelle immagini seguenti ( g,h,i,l ) vengono mostrate le elaborazioni di files di ingresso contenenti un vasto set di dati.

 

Figura 5g: k-means  fatrid =  100 modo  XàV

 

 

Figura 5h: k-means  fatrid =  100 modo XàVàV*

 

 

 

Figura 5i: k-means  fatrid =  100 modo XàX*àV

 

 

Figura 5l: Voronoi  di k-means fatrid =  100 modo XàV

 

Figura 5m: Voronoi  di k-means fatrid =  100 modo XàVàV*

 

 

Figura 5n: Voronoi  di k-means fatrid =  100 modo XàX*àV

 

 

 

 

 

 

 

 

 

 

 

 


5.1 Risultati ottenuti tramite l’uso di Spear

 

I risultati hanno evidenziato esiti piuttosto positivi, a fronte di un margine di errore contenuto si è avuto un notevole incremento della velocità di computazione del programma Spear, soprattutto per quelle classi i cui punti sono molto numerosi.

 Le prove sono state effettuate testando voci maschili e femminili applicando gli algoritmi Lloyd e K-Means con fattore di riduzione 10 e 100 utilizzando anche le modalità  ,  X à V , X à V à V* e X à X* à V descritte precedentemente.

Per effettuare le prove è stato utilizzato un database di registrazioni composto da un certo numero di parole pronunciate da numerosi parlatori, maschi e femmine, in varie sessioni.
Per ogni parlatore ho utilizzato due diversi file di training: uno contenente una sola sessione di prova, l’altro tutte e cinque.

le parole da riconoscere sono state scelte secondo il seguente criterio. 2 per la sessione corrente, 2 per lo stesso parlatore , ma con una sessione diversa, 2 per un altro parlatore dello stesso sesso ed infine 2 per un parlatore di sesso diverso.

La grande maggioranza delle parole riconosciute dai file interi sono state riconosciute anche dai files ridotti.

Generalmente si è potuto osservare una buona percentuale di riconoscimento (tra il 50 % e il 70 %) nel caso di parlatori addestrati ed un sostanziale miglioramento nel caso di parlatori non addestrati. Questo miglioramento è stato tanto più visibile, tanto più grande è stato il file di training. In tutte le prove effettuate l’algoritmo Lloyd di è dimostrato più efficiente di quello effettuato tramite quello dei K-Means.

Per quanto riguarda le riduzioni ulteriori ,ottenute attraverso la decimazione dei punti di partenza (X à X* à V ) o di quelli rimasti dopo l’esecuzione degli algoritmi di Lloyd e dei K-means (X à V à V* )  è risultato che il secondo metodo è più performante del primo nella maggior parte delle prove effettuate.

In alcuni casi, come mostrano le figure 5h e 5i, il modo X à V à V*  causa una riduzione eccessiva delle dimensioni del file di training, con conseguente perdita di informazione; tuttavia in altri casi questo metodo risulta comunque performante.

Di seguito sono riportate le tabelle relative alle prove effettuate. Ogni file di training è affiancato dalle sue versioni ridotte. La colonna R ci dice se la parola è stata riconosciuta.


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           83.5

S           68.5

Ancos01

2#3

S           100

S           78.8

S           59

Ancos02

0#1

S            60

S            60

S           38.6

Ancos02

2#3

S           70.4

S           70.4

S           70.4

Lucas01

5#3

S            52

S            50

S            54.6

Lucas01

9#4

S            47

S            47

S            39.4

Cabos03

6#1

N           33.7

N           36.6

S           31.1

Cabos03

0#3

N           26.4

S            22.9

S           18.4

 

Tabella 5.1: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à V.

 

 

 

Grafico 5.1: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à V.

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           57.5

N           30.1

Ancos01

2#3

S           100

S           65

S            28

Ancos02

0#1

S            60

S           54.6

N           28

Ancos02

2#3

S           70.4

S           58.7

S           62.1

Lucas01

5#3

S            52

S            50.2

S            42.5

Lucas01

9#4

S            47

S            39.3

S            29

Cabos03

6#1

N           33.7

N           24.5

S            20.9

Cabos03

0#3

N           26.4

N           16.6

N           14.2

 

Tabella 5.2: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à V à V*  .

 

 

 

Grafico 5.2: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à V à V*  .

 

 


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S           68.4

Ancos01

2#3

S           100

S           72.3

S           52.8

Ancos02

0#1

S            60

S          57.3

S           61.3

Ancos02

2#3

S           70.4

S           66.1

S           65.2

Lucas01

5#3

S            52

S            45.9

S            49.1

Lucas01

9#4

S            47

S            45

S            35.9

Cabos03

6#1

N           33.7

N           32.7

S           28.5

Cabos03

0#3

N           26.4

S            18.3

S           16.5

 

Tabella 5.3: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à X* à V .

 

 

 

Grafico 5.3: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd modo X à X* à V .

 

 

 

 

 

 

Ancoalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           80.8

S           68.4

Ancos01

2#3

S           100

S           78.8

S            59

Ancos02

0#1

S           100

S           70.6

S           54.6

Ancos02

2#3

S           100

S           70.4

S           70.4

Lucas01

5#3

S            52

S             50

S            54.6

Lucas01

9#4

S            44

S             47

S            39.4

Cabos03

6#1

N           44

N           36.6

S            31.1

Cabos03

0#3

N           29.8

S            22.9

S            18.4

 

Tabella 5.4: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd  modo X à V .

 

 

Grafico 5.4: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd  modo X à V .

 

 

 

 

 

 

 

 

Ancoalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           60.2

N           32.8

Ancos01

2#3

S           100

S           73.6

S           58.3

Ancos02

0#1

S           100

S           50.6

N          29.3

Ancos02

2#3

S           100

S           67.4

S            66

Lucas01

5#3

S            52

S            41.3

S           43.2

Lucas01

9#4

S            44

N           32.7

S            30.8

Cabos03

6#1

N           44

S           17.1

N            22

Cabos03

0#3

N           29.8

S            28.8

N            16.9

 

Tabella 5.5: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd modo X à V à V*   .

 

 

 

Grafico 5.5: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd modo X à V à V*   .

 

 

 

 

 

 

 

Ancoalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           72.6

S           65.7

Ancos01

2#3

S           100

S           75.6

S           52.3

Ancos02

0#1

S           100

S           72

S           62.6

Ancos02

2#3

S           100

S           70

S           66.2

Lucas01

5#3

S            52

S            44.1

S           50.1

Lucas01

9#4

S            44

N           30.4

S           36.4

Cabos03

6#1

N           44

S           18.8

S           27.9

Cabos03

0#3

N           29.8

N            20.1

N           19.2

 

Tabella 5.6: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd modo X à X* à V .

 

 

 

 

Grafico 5.6: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd modo X à X* à V .

 

 


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           79.4

S           60.2

Ancos01

2#3

S           100

S           78.8

S             44

Ancos02

0#1

S            60

S            56

S            53.3

Ancos02

2#3

S           70.4

S           70.4

S             44

Lucas01

5#3

S            52

S            43

S            47.7

Lucas01

9#4

S            47

S            78

S            81.7

Cabos03

6#1

N           33.7

S           36.6

N            35.1

Cabos03

0#3

N           26.4

S            25.3

N            13.8

 

Tabella 5.7: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means modo X à V .

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           56.1

N            31.5

Ancos01

2#3

S           100

S           70.2

S            34.6

Ancos02

0#1

S            60

S           52

N             28

Ancos02

2#3

S           70.4

S            62

S            40.1

Lucas01

5#3

S            52

S           39.9

S            42.5

Lucas01

9#4

S            47

S           71.1

S            76.4

Cabos03

6#1

N           33.7

S           25.7

S            36.2

Cabos03

0#3

N           26.4

N           19.9

N           10.7

 

Tabella 5.8: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-means modo X à V à V*   .


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S           60.2

Ancos01

2#3

S           100

S           75.9

S           37.1

Ancos02

0#1

S            60

S            60

S           66.6

Ancos02

2#3

S           70.4

S           67.3

S           40.2

Lucas01

5#3

S            52

S           38.9

S           42.5

Lucas01

9#4

S            47

S           50.1

S           60.7

Cabos03

6#1

N           33.7

S           32.2

N          25.1

Cabos03

0#3

N           26.4

N            22

S          15.2

 

Tabella 5.9: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means modo X à X* à V .

 

 

 

Ancosalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S           64.3

Ancos01

2#3

S           100

S           66.7

S             53

Ancos02

0#1

S           100

S           70.6

S             60

Ancos02

2#3

S           100

S            63

S             56

Lucas01

5#3

S            52

S           55.8

S            38.3

Lucas01

9#4

S            44

S           77.5

N           43.6

Cabos03

6#1

N           44

N           36.4

N            35

Cabos03

0#3

N          29.8

N            39

S             32

 

Tabella 5.10: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con K-Means modo X à V .

 

 


 

 

 

Ancosalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           60.2

S            60.1

Ancos01

2#3

S           100

S           64.5

S            47.8

Ancos02

0#1

S           100

S           50.6

S             57

Ancos02

2#3

S           100

S           58.1

S            50.5

Lucas01

5#3

S            52

S           44.2

S            32.4

Lucas01

9#4

S            44

S           50.2

S             40

Cabos03

6#1

N           44

N          34.9

N           30.8

Cabos03

0#3

N          29.8

S           37.7

N            24

 

Tabella 5.11: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con K-Means modo X à V à V* .

 

 

 

 

Ancosalls

Ancoalls.10

Ancoalls.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           69.8

S           64.3

Ancos01

2#3

S           100

S           64.8

S           45.5

Ancos02

0#1

S           100

S            72

S            60

Ancos02

2#3

S           100

S           59.9

S           47.6

Lucas01

5#3

S            52

S           52.7

S             35

Lucas01

9#4

S            44

S           75.6

N           36.1

Cabos03

6#1

N           44

S            35

N           30.3

Cabos03

0#3

N          29.8

N          34.9

S            32.2

 

Tabella 5.12: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con K-Means modo X à X* à V .

 

 

 

Sono state eseguite ulteriori prove utilizzando file di training ottenuti dalla prima sessione di Anco e da tutte le sessioni di Anco e si è valutato il riconoscimento  con registrazioni dello stesso parlatore.
Di seguenti risultati è ben visibile che il modo X à X* à V  è molto piu’ performante del modo 
X à V à V* .

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           83.5

S            68.4

Ancos01

0#2

S           100

S            79

S            66.6

Ancos02

0#1

S           60

S            60

S            38.6

Ancos02

0#2

S           53.9

S           68.5

S            50.7

Ancos03

0#1

S           61.3

S           58.6

S            53.3

Ancos03

0#1

S            56.3

S           61.9

S            50.7

 

Tabella 5.13: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd  modo X à V

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           57.5

N            30.1

Ancos01

0#2

S           100

S           56.5

N            30.4

Ancos02

0#1

S           60

S           54.6

N             28

Ancos02

0#2

S           53.9

S           55.5

N            31.7

Ancos03

0#1

S           61.3

N            48

N            24

Ancos03

0#1

S            56.3

S           54.9

N           23.9

 

Tabella 5.14: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd  modo X à V à V* .

 


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S            68.4

Ancos01

0#2

S           100

S           75.3

S            65.2

Ancos02

0#1

S           60

S           57.3

S            61.3

Ancos02

0#2

S           53.9

S           63.4

S            58.7

Ancos03

0#1

S           61.3

S            64

S            58.6

Ancos03

0#1

S            56.3

S           52.1

S            59.1

 

Tabella 5.15: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd  modo X à X à V* .

 

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           80.8

S            68.4

Ancos01

0#2

S           100

S           86.9

S             71

Ancos02

0#1

S           100

S           70.6

S            54.6

Ancos02

0#2

S           100

S           74.6

S            68.2

Ancos03

0#1

S           100

S           78.6

S            69.3

Ancos03

0#1

S           100

S           80.2

S            61.9

 

Tabella 5.16: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd  modo X à V .


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

N           60.2

N            32.8

Ancos01

0#2

S           100

N            55

N            27.5

Ancos02

0#1

S           100

N           50.6

N            29.3

Ancos02

0#2

S           100

N           58.7

N            33.3

Ancos03

0#1

S           100

N            52

N            21.3

Ancos03

0#1

S           100

N           57.7

N            23.9

 

Tabella 5.17: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con Lloyd  modo X à V à V* .

 

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           72.6

S            65.7

Ancos01

0#2

S           100

S           66.6

S            69.5

Ancos02

0#1

S           100

S           72

S            62.6

Ancos02

0#2

S           100

S           66.6

S            63.4

Ancos03

0#1

S           100

S           72

S            70.6

Ancos03

0#1

S           100

S           76

S            67.6

 

Tabella 5.18: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd  modo X à X à V .


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           79.4

S            60.2

Ancos01

0#2

S           100

S           82.6

S            59.4

Ancos02

0#1

S           60

S            56

S            53.3

Ancos02

0#2

S           53.9

S           47.6

S            58.7

Ancos03

0#1

S           61.3

S            56

S            58.6

Ancos03

0#1

S            56.3

S           49.2

S            52.1

 

Tabella 5.19: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means  modo X à V

 

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           56.1

N            31.5

Ancos01

0#2

S           100

S           53.6

N            31.8

Ancos02

0#1

S           60

S            52

N             28

Ancos02

0#2

S           53.9

N          52.3

N            28.5

Ancos03

0#1

S           61.3

N          45.3

N            24

Ancos03

0#1

S            56.3

N           52.1

N           21.1

 

Tabella 5.20: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means  modo X à V à V* .


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S            60.2

Ancos01

0#2

S           100

S           75.3

S            68.1

Ancos02

0#1

S           60

S            60

S            66.6

Ancos02

0#2

S           53.9

S           61.9

S            57.1

Ancos03

0#1

S           61.3

S            64

S             64

Ancos03

0#1

S            56.3

S           49.3

S            60.5

 

Tabella 5.21: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means  modo X à X à V* .

 

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           73.9

S            68.4

Ancos01

0#2

S           100

S           79.7

S             71

Ancos02

0#1

S           100

S           70.6

S            54.6

Ancos02

0#2

S           100

S           68.2

S            68.2

Ancos03

0#1

S           100

S           77.3

S            69.3

Ancos03

0#1

S           100

S            69

S            61.9

 

Tabella 5.22: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con Lloyd  modo X à V .


 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

N           60.2

N             15

Ancos01

0#2

S           100

N            55

N            8.6

Ancos02

0#1

S           100

N           50.6

N            9.3

Ancos02

0#2

S           100

N           57.1

N            9.5

Ancos03

0#1

S           100

N            52

N            12

Ancos03

0#1

S           100

N           54.9

N            14

 

Tabella 5.23: Riconoscimento di file interni con la sessione 1 di anco e le sue riduzioni con K-Means  modo X à V à V* .

 

 

 

 

 

 

 

Ancos01

Ancos01.10

Ancos01.100

Parlatore

Parola

R            %

R           %

R            %

Ancos01

0#1

S           100

S           69.8

S            64.3

Ancos01

0#2

S           100

S           69.5

S            69.5

Ancos02

0#1

S           100

S           72

S             60

Ancos02

0#2

S           100

S           68.2

S             65

Ancos03

0#1

S           100

S           73.3

S             68

Ancos03

0#1

S           100

S           77.4

S             69

 

Tabella 5.24: Riconoscimento di file interni con tutte le sessioni di anco e le sue riduzioni con K-Means  modo X à X à V .
Capitolo 6 : Conclusioni

I risultati ottenuti nelle prove evidenziano la possibilità di ottenere buoni risultati e la velocizzazione del processo di riconoscimento vocale senza perdite significative. Il programma lk richiede buone risorse computazionali, e comunque il tempo richiesto e' abbastanza alto, soprattutto se si utilizzano file molto grandi.

La compressione dei file di training però  e' fatta off-line ed il tempo richiesto non influisce sul tempo di riconoscimento.

Il software sviluppato è molto flessibile e versatile poiché permette di decidere sia il tipo di riduzione da effettuare sia l’entità della stessa dando la possibilità all’utente di stimare graficamente i risultati ottenuti.

I numerosi risultati, ottenuti tramite prove di diverso tipo, evidenziano come la riduzione Xà Xà V con una scelta appropriata del fattore di riduzione, permetta di ridurre notevolmente la dimensione del file di training e di conseguenza il tempo di calcolo richiesto dal programma di riconoscimento vocale “Spear”, senza compromettere, nella maggior parte dei casi, il riconoscimento corretto delle parole.

Generalmente la riduzione attraverso l’algoritmo di Lloyd è risultata migliore rispetto a quella effettuata tramite l’algoritmo dei K-Means.

Sebbene i risultati differiscano di poco il costo computazionale richiesto dall’algoritmo di Lloyd è però più gravoso di quello richiesto dall’algoritmo dei K-Means.

 Esistono molti altri algoritmi di quantizzazione vettoriale, un possibile sviluppo futuro in quest'ambito potrebbe fornire dati e risultati ancora migliori. Gli algoritmi di Lloyd e dei K-Means hano comunque dimostrato un'ottima affidabilità senza commettere errori rilevanti nel riconoscimento.

 

 

 

 

 

 

 

 

 

 

 

 

Capitolo 7 : Appendice

// lk.cpp

//

 

#include "stdafx.h"

#include "resource.h"

#include <windows.h>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <fstream.h>

#include <fstream>

#include <time.h>

#define MAX_LOADSTRING 300

#define IDM_ELLIPSE    1100

#define IDM_RECTANGLE  1200

#define IDM_ROUNDRECT  1300

static BOOL param2=FALSE;

HDC hdc;

int wmId, wmEvent;

bool save = false;

long x = 100;

long y = 50;

char lork='k';

int ftrd=100;

bool sw = false;

int lloyddaeseguire=0;

int kmeansdaeseguire=0;

int voronoidaeseguire=0;

double valoremaxx=0.0;

double coeffmoltiplx=0.0;

double offsetx=0.0;

double valoremaxy=0.0;

double coeffmoltiply=0.0;

double offsety=0.0;

double valoreminx=0.0;

double valoreminy=0.0;

int finestrax = 750;

int finestray = 470;

double valoretotale=0.0;

int ftrd1=50;

int iterr=100;

int dimx=0;

int dimy=1;

float dimpunti=(float)1.8;

float dimcampioni=5;

float ***theta;

float ***thetamod;

float ***lly;

bool ***att;

bool ***attc;

int **md;

int thetal[30];

int thetalmod[30];

float vor[300][6];

int acluster=0;

int apunti=0;

int parametri=0;

float vx=0;

float vy=0;

int ytu=0;

int llyl[30];

int  NUMCLASS = 0;

int  NUMPAR = 0;

float intersx=0;

float intersy=0;

int giu=0;

int done=0;

int vnd=0;

int swp=0;

int vpasso=2;

int vdim=2;

int vrid=0;

int vinters=0;

int vassi=0;

int vcl=0;

int tipoxv=0;

bool luy = false;

bool savenow = false;

int provetta=0;

bool paramwrite = false;

int lop = 0;

PAINTSTRUCT ps;

HWND hWnd;

HBRUSH hbrush;

HPEN hpen;

 

 

// Global Variables:

HINSTANCE hInst;                                                                                          // current instance

TCHAR szTitle[MAX_LOADSTRING];                                                                                        // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];                                                                                      // The title bar text

int parametro2var=0;

 

// Foward declarations of functions included in this code module:

ATOM                                      MyRegisterClass(HINSTANCE hInstance);

BOOL                                      InitInstance(HINSTANCE, int);

LRESULT CALLBACK   WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK   About(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK   SaveAs(HWND, UINT, WPARAM, LPARAM);

 

float coord_distance (float a, float b);

void progressbar(int par , int tot);

 

double valass(double tre)

{

            double tre1=0;

if (tre > 0) tre1 = tre;

if (tre == 0) tre1 = tre;

if (tre <0 ) tre1 = double (-1) * tre;

return (tre1);

}

// Disegna un quadrato

void disegnaquadrato(int x,int y,int a)

{

//Rectangle(hdc, x,y, x+a,y+a);  

Rectangle(hdc, x-a/2,y-a/2, x+a/2,y+a/2);          

}

// Disegna un ellisse

void disegnaellisse(int x,int y,int a)

{

 

//Ellipse(hdc, x, y, x+a, y+a);

            Ellipse(hdc,x-a,y-a,x+a,y+a);

}

// cambia il colore della penna

void colorepenna(int col1)

{

           

            int r,g,b,col,tr;

 

            if (giu == 15) giu =0;

            tr=0;

            if ((col1 == 14) || (col1 < 14)) col = col1;

            if (col1 > 14)

            {

                        while (tr < 1)

                        {

                                   col1 = col1 - 15;

                                   col = col1;

                                   if (col1 < 15) tr = 2;

                        }

            }

 

            if (col==0) {

                                               r=0;

                                               g=0;

                                               b=0;

                                               }

            if (col==1) {

                                               r=255;

                                               g=0;

                                               b=0;

                                               }

            if (col==2) {

                                                r=255;

                                               g=255;

                                               b=0;

                                               }

            if (col==3) {

                                               r=255;

                                               g=0;

                                               b=255;

                                               }

            if (col==4) {

                                               r=0;

                                               g=0;

                                               b=255;

                                               }

            if (col==5) {

                                               r=128;

                                               g=255;

                                               b=0;

                                               }

            if (col==6) {

                                               r=128;

                                               g=0;

                                               b=255;

                                               }

            if (col==7) {

                                               r=128;

                                               g=128;

                                               b=128;

                                               }

            if (col==8) {

                                               r=128;

                                               g=64;

                                               b=64;

                                               }

            if (col==9) {

                                               r=64;

                                               g=128;

                                               b=128;

                                               }

            if (col==10) {

                                               r=0;

                                               g=255;

                                               b=255;

                                               }

            if (col==11) {

                                               r=100;

                                               g=0;

                                               b=100;

                                               }

            if (col==12) {

                                               r=0;

                                               g=100;

                                               b=100;

                                               }

            if (col==13) {

                                               r=100;

                                               g=100;

                                               b=0;

                                               }

            if (col==14) {

                                               r=220;

                                               g=60;

                                               b=100;

                                               }

 

DeleteObject(hpen);      

hpen = CreatePen(PS_SOLID, 1, RGB(r, g, b));

SelectObject(hdc, hpen);

}

// cambia il colore del pennello

void colorepennello(int col)

{

                        int r,g,b;

            if (col==0) {

                                               r=0;

                                               g=0;

                                               b=0;

                                               }

            if (col==1) {

                                               r=255;

                                               g=0;

                                               b=0;

                                               }

            if (col==2) {

                                               r=255;

                                               g=255;

                                               b=0;

                                               }

            if (col==3) {

                                               r=255;

                                               g=0;

                                               b=255;

                                               }

            if (col==4) {

                                               r=0;

                                               g=0;

                                               b=255;

                                               }

            if (col==5) {

                                               r=128;

                                               g=255;

                                               b=0;

                                               }

            if (col==6) {

                                               r=128;

                                               g=0;

                                               b=255;

                                               }

            if (col==7) {

                                               r=128;

                                               g=128;

                                               b=128;

                                               }

            if (col==8) {

                                               r=128;

                                               g=64;

                                               b=64;

                                               }

            if (col==9) {

                                               r=64;

                                               g=128;

                                               b=128;

                                               }

            if (col==10) {

                                               r=0;

                                               g=255;

                                               b=255;

                                               }

            if (col==11) {

                                               r=100;

                                               g=0;

                                               b=100;

                                               }

            if (col==12) {

                                               r=0;

                                               g=100;

                                               b=100;

                                               }

            if (col==13) {

                                               r=100;

                                               g=100;

                                               b=0;

                                               }

            if (col==14) {

                                               r=220;

                                               g=60;

                                               b=100;

                                               }

DeleteObject(hbrush);   

hbrush = CreateSolidBrush(RGB(r, g, b));

SelectObject(hdc, hbrush);

}

 

float radicequadrata(float radq)

{

return (sqrt(radq));

}

void creaatt()  // crea la matrice per la attivazione / disattivazione dei punti

{

            att = new bool**[NUMCLASS];

            int s = 0;

            int z = 0;

 

            while (s<NUMCLASS)

            {

                        att[s] =  new bool*[thetal[s]];

                        while (z<thetal[s])

                        {

                                   att[s][z] =  new bool[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

           

}

void creaattc() // crea la matrice per la attivazione / disattivazione dei campioni

{

            attc = new bool**[NUMCLASS];

            int s = 0;

            int z = 0;

 

            while (s<NUMCLASS)

            {

                        attc[s] =  new bool*[llyl[s]];

                        while (z<llyl[s])

                        {

                                   attc[s][z] =  new bool[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

           

}

 

void creathetamod()  // crea la matrice per la attivazione / disattivazione dei punti

{

            thetamod = new float**[NUMCLASS];

            int s = 0;

            int z = 0;

 

            while (s<NUMCLASS)

            {

                        thetamod[s] =  new float*[thetal[s]];

                        while (z<thetal[s])

                        {

                                   thetamod[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

           

}

void disattivacampioni() // disattiva i campioni

{

            int s=0;

            int z=0;

            int s1=0;

            int z1=0;

            float xw=(float)0.0;

            float yw=(float) 0.0;

            float xe=(float)0.0;

            float ye=(float) 0.0;     

            float argom=(float) 0.0;

            float sommadist = (float) 0.0;

            float sommadistpe = (float) 0.0;

            float mindistc=(float) 10000000.0;

            int classeapp=0;

 

 

            while (s<NUMCLASS)

            {

                        while (z<llyl[s])           

                        {

                        mindistc=(float) 1000000000.0;

                        xw = lly[s][z][dimx];

                        yw = lly[s][z][dimy];

                       

                                                           while (s1<NUMCLASS)

                                                           {

                                                           sommadist=0;

                                                           sommadistpe=0;

                                                                       while (z1<llyl[s1])        

                                                                       {

                                                                       xe=lly[s1][z1][dimx];

                                                                       ye=lly[s1][z1][dimy];

                                                                      argom = ((xe - xw) * (xe - xw)) + ((ye - yw)*(ye - yw));

                                                                       sommadist = sommadist +        sqrt(argom);

                                                                       z1 = z1 + 1;

                                                                       }

                                                           if (llyl[s1] > 0) sommadistpe = (sommadist / llyl[s1]); // pesa la distanza e il numero dei campioni

                                                           if (sommadistpe < mindistc)

                                                           {

                                                           mindistc = sommadistpe;

                                                           classeapp = s1;

                                                           }

                                                           z1 = 0;

                                                           s1 = s1 + 1;

                                                           }

                        attc[s][z][0] = false;

                        if (classeapp == s) attc[s][z][0] = true;

                        z = z + 1;

                        z1=0;

                        s1=0;

                        }

            progressbar(s,NUMCLASS);

            s = s + 1;

            z = 0;

            }

 

 

}

 

 

void disattivapunti() // disattiva i punti ---> dalla theta crea thetamod

{

            creathetamod();

            int s=0;

            int z=0;

            int s1=0;

            int z1=0;

            int z2=0;

            float xw=(float)0.0;

            float yw=(float) 0.0;

            float xe=(float)0.0;

            float ye=(float) 0.0;     

            float argom=(float) 0.0;

            float sommadist = (float) 0.0;

            float sommadistpe = (float) 0.0;

            float mindistc=(float) 10000000.0;

            int classeapp=0;

            int ci=0;

 

 

            while (s<NUMCLASS)

            {

                        z2=0;

                        while (z<thetal[s])       

                        {

                        mindistc=(float) 1000000000.0;

                        xw = theta[s][z][dimx];

                        yw = theta[s][z][dimy];

                       

                                                           while (s1<NUMCLASS)

                                                           {

                                                           sommadist=0;

                                                           sommadistpe=0;

                                                                       while (z1<thetal[s1])    

                                                                       {

                                                                       xe=theta[s1][z1][dimx];

                                                                       ye=theta[s1][z1][dimy];

                                                                       argom = ((xe - xw) * (xe - xw)) + ((ye - yw)*(ye - yw));

                                                                       sommadist = sommadist +        sqrt(argom);

                                                                       z1 = z1 + 1;

                                                                       }

                                                           if (thetal[s1] > 0) sommadistpe = (sommadist / thetal[s1]); // pesa la distanza e il numero dei campioni

                                                           if (sommadistpe < mindistc)

                                                           {

                                                           mindistc = sommadistpe;

                                                           classeapp = s1;

                                                           }

                                                           z1 = 0;

                                                           s1 = s1 + 1;

                                                           }

                        att[s][z][0] = false;

                        if (classeapp == s)

                        {

                        att[s][z][0] = true;

                                   while(ci < NUMPAR)

                                   {

                                               thetamod[s][z2][ci]=theta[s][z][ci];

                                               ci=ci+1;

                                   }

                        ci=0;

                        z2 = z2 + 1;

                        }

                        z = z + 1;

                        z1=0;

                        s1=0;

                        }

            z = 0;

            thetalmod[s] = z2;

           

            z2=0;

            progressbar(s,NUMCLASS);

            s = s + 1;

            }

 

s=0;

float xx=0;

float yy=0;

z=0; // MODIFICA LA MATRICE THETA e THETAL partendo da thetalmod e thetamod

ci=0;

            while (s<NUMCLASS)

            {

                        thetal[s] = thetalmod[s];

                        while (z < thetalmod[s])

                        {

                                   ci = 0;

                                   while (ci<NUMPAR)

                                   {                                 

                                   theta[s][z][ci] = thetamod[s][z][ci];

                                   ci = ci + 1;                                          

                                   }

                                   colorepenna(s);

                                   colorepennello(s);

                                   xx = thetamod[s][z][dimx];

                                   yy = thetamod[s][z][dimy];

                                   disegnaellisse ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimpunti);

                                   z = z + 1;

                        }

                        z = 0;

                        s = s + 1;

            }

 

}

 

 

char * conversione(int value)

{

            char *c="";

            if (value==0) c = "0";

            if (value==1) c = "1";

            if (value==2) c = "2";

            if (value==3) c = "3";

            if (value==4) c = "4";

            if (value==5) c = "5";

            if (value==6) c = "6";

            if (value==7) c = "7";

            if (value==8) c = "8";

            if (value==9) c = "9";

            if (value==10) c = "10";

            if (value==25) c = "25";

            if (value==50) c = "50";

            if (value==75) c = "75";

            if (value==100) c = "100";

 

            return(c);

}

 

void scriviparametri(RECT rt)

{

            char *testo[20];

            int lp=0;

            rt.top=finestray-10;

            rt.bottom=finestray+5;

            if (lop==0) testo[0] = "default";

            if (lop==1) testo[0] = "k-means";

            if (lop==2) testo[0] = "lloyd  ";

            if (tipoxv==0) testo[10] = "x -> v      ";

            if (tipoxv==1) testo[10] = "x -> v -> V";

            if (tipoxv==2) testo[10] = "x -> X -> v";

            if (voronoidaeseguire==0) testo[11] = "    ";

            if (voronoidaeseguire==1) testo[11] = "cl =";

            testo[1] = "dim x =";

            testo [2] = conversione(dimx+1);

            testo[3] = "dim y =";

            testo [4] = conversione(dimy+1);

            testo[5] = "ftrd = ";

            testo [6] = conversione(ftrd1);

            testo[7] = "iter = ";

            testo [8] = conversione(iterr);

            testo [9] = "modo";

            if (voronoidaeseguire==0) testo [12] = "  ";

            if (voronoidaeseguire==1) testo [12] = conversione(vcl+1);

            rt.left=5;

            rt.right=770;

            DrawText(hdc, "_______________________________________________________________________________________________________",85 , &rt, DT_CENTER);

 

            rt.left=5;

            rt.right=65;

            DrawText(hdc, testo[0],strlen(testo[0]) , &rt, DT_CENTER);

            rt.left=90;

            rt.right=140;

            DrawText(hdc, testo[1],strlen(testo[1]) , &rt, DT_CENTER);

            rt.left=140;

            rt.right=150;

            DrawText(hdc, testo[2],strlen(testo[2]) , &rt, DT_CENTER);

            rt.left=165;

            rt.right=215;

            DrawText(hdc, testo[3],strlen(testo[3]) , &rt, DT_CENTER);

            rt.left=215;

            rt.right=225;

            DrawText(hdc, testo[4],strlen(testo[4]) , &rt, DT_CENTER);

            rt.left=230;

            rt.right=280;

            DrawText(hdc, testo[5],strlen(testo[5]) , &rt, DT_CENTER);

            rt.left=280;

            rt.right=305;

            DrawText(hdc, testo[6],strlen(testo[6]) , &rt, DT_CENTER);

            rt.left=310;

            rt.right=365;

            DrawText(hdc, testo[7],strlen(testo[7]) , &rt, DT_CENTER);

            rt.left=365;

            rt.right=390;

            DrawText(hdc, testo[8],strlen(testo[8]) , &rt, DT_CENTER);

            rt.left=410;

            rt.right=460;

            DrawText(hdc, testo[9],strlen(testo[9]) , &rt, DT_CENTER);

            rt.left=460;

            rt.right=535;

            DrawText(hdc, testo[10],strlen(testo[10]) , &rt, DT_CENTER);

            rt.left=540;

            rt.right=590;

            DrawText(hdc, testo[11],strlen(testo[11]) , &rt, DT_CENTER);

            rt.left=590;

            rt.right=610;

            DrawText(hdc, testo[12],strlen(testo[12]) , &rt, DT_CENTER);

}

 

void progressbar(int par , int tot)

{          

            int gr=0;

            double res;

            RECT rt;

            rt.top=finestray-10;

            rt.bottom=finestray+5;

            char *testo[1];

            //testo[0]="____________";

            rt.left=610;

            rt.right=650;

            DrawText(hdc, "prog",strlen("prog") , &rt, DT_LEFT);

            rt.left=650;

            rt.right=770;

            //if (tot == 0) return;

            res = (par*10) / tot;

            gr = (int) res;;

            if (gr==0) testo[0]="";

            if (gr==1) testo[0]="*";

            if (gr==2) testo[0]="**";

            if (gr==3) testo[0]="***";

            if (gr==4) testo[0]="****";

            if (gr==5) testo[0]="*****";

            if (gr==6) testo[0]="******";

            if (gr==7) testo[0]="*******";

            if (gr==8) testo[0]="********";

            if (gr==9) testo[0]="*********";

            if (gr==10) testo[0]="              ";

            DrawText(hdc, testo[0],strlen(testo[0]) , &rt, DT_LEFT);

 

}

float bisettrice(float k1 , float k2)

{

            float k11 = 0;

            float k22 = 0;

            float k3 = 0;

            k11 = atan(k1);

            k22 = atan(k2);

 

            k3 = tan((k2 - k1));

return (k3);

}

 

int intersezione(int k1, int k2) // passare gli indici della matrice

{

            float k11 = 0;

            float k12 = 0;

            float k22 = 0;

            float x1 = 0;

            float x2 = 0;

            float y1 = 0;

            float y2 = 0;

            float x11 = 0;

            float x22 = 0;

            float y11 = 0;

            float y22 = 0;

            float tmp = 0;

 

            int k3 = 0;

            k11 = ((vor[k2][1] - vor [k1][1]) / (vor [k1][0] - vor [k2][0])); // valore x di intersezione

            if ((k11 < 0) || (k11 > finestrax)) return (0); // non si interscano nella finestra

            k12 = (vor[k2][0]*k11) + vor[k2][1];         

            if ((k12 < 0) || (k12 > (finestray-10))) return (0); // non si interscano nella finestra

                        x1 = vor [k1][2]; // inizio

                        x2 = vor [k1][4]; // fine

                        y1 = vor [k1][3];

                        y2 = vor [k1][5];

                        x11 = vor [k2][2]; // inizio

                        x22 = vor [k2][4]; // fine

                        y11 = vor [k2][3];

                        y22 = vor [k2][5];

if (x1 > x2)

{                                              // ordina i punti dei segmenti

tmp = x2;

x2 = x1;

x1 = tmp;

}

if (x11 > x22)

{

tmp = x22;

x22 = x11;

x11 = tmp;

}

if (y1 > y2)

{

tmp = y2;

y2 = y1;

y1 = tmp;

}

if (y11 > y22)

{

tmp = y22;

y22 = y11;

y11 = tmp;

}

intersx = k11; // punti di intersezione tra le 2 rette

intersy = k12;

tmp = 0;

if ((x1 < k11) && (x2 > k11) && (x11 < k11) && (x22 > k11)) tmp = 1;

if (tmp == 0) return (0);

tmp = 0;

if ((y1 < k12) && (y2 > k12) && (y11 < k12) && (y22 > k12)) tmp = 1;

if (tmp == 0) return (0);

intersx = k11; // punti di intersezione tra le 2 rette

intersy = k12;

return (1);

}

 

void matricecalcolata(float ***lly)  //  Ordina la matrice lly !!!!

{

            float precedente = 0;

            float temporanea = 0;

            float precedentey = 0;

            float temporaneay = 0;

            float xx=0;

            float yy=0;

            int s = 0;

            int z = 0;

            int r = 0;

            int ci = 0;

            float m=0;

            float mp=0;

            float pq=0;

            float px=0;

            float py=0;

            float pg=0;

            float pg1=0;

                                               // dalla dimensione x piccola alla piu' grande

            s=0;

            z=1;                 // importante inizializzazione

            while (s < NUMCLASS)

            {

           

                        while (r < llyl[s])

                        {

                                   while (z < llyl[s])

                                   {

                                   precedente = lly[s][z-1][dimx];

                                   temporanea = lly[s][z][dimx];

                                   precedentey = lly[s][z-1][dimy];

                                   temporaneay = lly[s][z][dimy];

                                                          

                                                           if (temporanea < precedente)

                                                           {

                                                                       lly[s][z-1][dimx]=temporanea;     // scambio x e y

                                                                       lly[s][z][dimx]=precedente;

                                                                       lly[s][z-1][dimy]=temporaneay;  

                                                                       lly[s][z][dimy]=precedentey;

                                                           }

                                   z = z+1;

                                   }

                        z = 1;

                        r = r +1;

                        }

            r=0;

            s = s+1;

           

            }

 

s=0;

z=0;

float bis=0;

                        // Qui inizia il calcolo di voronoi **** **** **** **** VORONOI **** **** **** ****

            if (voronoidaeseguire == 0) return;

           

 

 

            z=0;

            int xs=0;

            int ys=0;

            double d = 0.0;

            double dd = 0.0;

            double dmin=0.0;

            int pd=0;

            int pdv=0;

            int ghg=0;

            double nx = 0.0;

            double ny = 0.0;

            double xr = 0.0;

            double yr = 0.0;

 

 

            s = vcl; // setta la classe da calcolare

            if ((tipoxv == 0) || (tipoxv == 2)) 

            {

            while (xs < finestrax )

            {

                        while (ys < (finestray-10))

                        {                      

                                    z = 0;

                                   pdv = pd;

                                   while (z < llyl[vcl])  // llyl[vcl]

                                   {

 

                                   ghg = z;                 // discendente

                                   nx = lly[vcl][ghg][dimx];

                                   ny = lly[vcl][ghg][dimy];

                                   xr = nx * coeffmoltiplx + offsetx;

                                   yr = ny * coeffmoltiply + offsety;

                                   //colorepenna(7);

                                   //disegnaellisse(xr,yr,4);

                                   d = (double) radicequadrata((double) ((xs - xr)*(xs - xr) + (ys - yr)*(ys-yr)));

                                   if ((d < dmin) || (z == 0))

                                   {  

                                               dmin = d;

                                               pd = z;

                                   }

                                   z = z + 1;

                                   }

                                   z = 0;

                        colorepenna(pd+1+swp+vcl);

                        disegnaellisse(xs,ys,vdim);

 

                        if (pdv != pd)

                        {

                        colorepenna(0+swp);

                        disegnaellisse(xs,ys,2);

                        }

                        ys = ys + vpasso;

                        d=0.0;

                        dmin = 0.0;

                        }

            ys=0;

            xs = xs + vpasso;

            progressbar(xs,finestrax);

            dmin=0.0;

            }

            }

 

            if ((tipoxv == 1)) 

            {

            while (xs < finestrax )

            {

           

                        while (ys < (finestray-10))

                        {                      

                                   z = 0;

                                   pdv = pd;

                                   while (z < llyl[vcl])  // llyl[vcl]

                                   {

                                   ghg = z; 

                                   if (attc[vcl][ghg][0] == true)

                                   {

                                   nx = lly[vcl][ghg][dimx];

                                   ny = lly[vcl][ghg][dimy];

                                   xr = nx * coeffmoltiplx + offsetx;

                                   yr = ny * coeffmoltiply + offsety;

                                   d = (double) radicequadrata((double) ((xs - xr)*(xs - xr) + (ys - yr)*(ys-yr)));

                                   if ((d < dmin) || (z == 0))

                                   {  

                                               dmin = d;

                                               pd = z;

                                   }

                                   }

                                   z = z + 1;

                                   }

                                   z = 0;

                        colorepenna(pd+1+swp+vcl);

                        disegnaellisse(xs,ys,vdim);

                        if (pdv != pd)

                        {

                        colorepenna(0+swp);

                        disegnaellisse(xs,ys,2);

                        }

                        ys = ys + vpasso;

                        d=0.0;

                        dmin = 0.0;

                        }

            ys=0;

            xs = xs + vpasso;

            dmin=0.0;

            }

            }

 

            if (vrid==1)

            {

            z=0;  // ridisegna i campioni

            while (z < llyl[vcl])

                                   {

 

                        if (tipoxv == 1) 

                        {

                                   if ((attc[vcl][z][0]) == true)

                                   {

                                   colorepenna(vcl);

                                   colorepennello(vcl);

                                   xx = lly[vcl][z][dimx];

                                   yy = lly[vcl][z][dimy];

                                   disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                                   }

                        }

                        if ((tipoxv == 0) || (tipoxv == 2)) 

                        {

                                   colorepenna(vcl);

                                   colorepennello(vcl);

                                   xx = lly[vcl][z][dimx];

                                   yy = lly[vcl][z][dimy];

                                   disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                        }

                                   z = z + 1;

                                   }

            }

                       

 

            z=1;

            s=vcl;

            int cnt=0;

            int itis=0;

            int kuj=0;

 

            //while (s < NUMCLASS)

            if (vinters==1) {

                        while (z < llyl[s])

                        {          

                                   if (s==vcl)

                                   {

                                   xx = lly[vcl][z][dimx];

                                   yy = lly[vcl][z][dimy];

                                   vx = lly[vcl][z-1][dimx];

                                   vy = lly[vcl][z-1][dimy];

                                  

                                   xx = xx*coeffmoltiplx+offsetx;

                                   yy = yy*coeffmoltiply+offsety;

                                   vx = vx*coeffmoltiplx+offsetx;

                                   vy = vy*coeffmoltiply+offsety;

                                   px = ( xx + vx ) / 2;

                                   py = ( yy + vy ) / 2;

                                   m = ((yy - vy) / (xx - vx)); // retta Y=mpX + pq

                                   mp = - (1 / m);              // coefficiente angolare della retta

                                   pq = py - (mp * px); // punto di intersezione della retta

                                   pg = pq;

                                   pg1 = finestrax * mp + pq;                    

 

                                   colorepenna(1);

                                   if (vassi==1)

                                   {

                                   MoveToEx(hdc, 0 , pg , (LPPOINT) NULL);         

                                   LineTo(hdc, finestrax , pg1 );

                                   }

                                   if (z == 1)    // la prima semiretta è sicuramente non intersecata

                                   {

                                               vor[z-1][0] = mp;

                                               vor[z-1][1] = pq;

                                               vor[z-1][2] = 0;

                                               vor[z-1][3] = pg;

                                               vor[z-1][4] = finestrax;

                                               vor[z-1][5] = pg1;

                                   }

                                   if (z > 1)

                                   {

                                               int cnt1=0;

                                               while (cnt < z)

                                               {

                                                           cnt1 = (z-1) - cnt;

                                                           itis = intersezione(z-1, cnt1);

                                                           colorepenna(6);

                                                           colorepennello(6);

                                                           if (( itis == 1 ) && (vinters==1)) disegnaellisse(intersx-3,intersy-3,2);

                                                           if (itis == 0)  // il segmento non interseca nessun altro segmento

                                                           {

                                                                       vor[z-1][0] = mp;

                                                                       vor[z-1][1] = pq;

                                                                       vor[z-1][2] = 0;

                                                                       vor[z-1][3] = pg;

                                                                       vor[z-1][4] = finestrax;

                                                                       vor[z-1][5] = pg1;

                                                           }

                                            if ((itis ==1 ))

                                                            {

                                                                        kuj=1;

                                                                       float pqa=0;

                                                                       float pga=0;

                                                                       bis = bisettrice(vor[z-1][0],vor[cnt1][0]);

                                                                       pqa = intersy - (bis * intersx); // punto di intersezione della retta

                                                                       pga = finestrax * bis + pqa;                   

                                                                       //colorepenna(2);

                                                                       //MoveToEx(hdc, 0 , pqa , (LPPOINT) NULL);    

                                                                       //LineTo(hdc, finestrax , pga );                                                                         

                                                            }

 

                                                           cnt = cnt + 1;

 

                                               }

                                   }

                                   }

                                   cnt = 0;

                                   z = z + 1;

                        }

                        z = 1;

                        cnt = 0;

                        s = s + 1;

}

           

}

 

 

 

 

 

//function prototypes

 

time_t longtime;

float coord_distance (float a, float b)

{

            return ( (a - b) * (a - b) ) ;

}

 

float dist (float *v1, float *v2)

{

            int cont = 0;

            float sum = 0;

            while (cont<NUMPAR)

            {

                        sum = sum+coord_distance(v1[cont],v2[cont]);

                        cont = cont+1;

            }

            return (sum) ;

}

 

void mindist (float ***theta, float ***lly, int **md, int *thetal, int *llyl, int nclasse)

{

            int cont1 = 0,cont2=0;

            float distanza = 9999;

            while (cont1<thetal[nclasse])

            {

                        while (cont2<llyl[nclasse])

                        {

                                   if (dist (theta[nclasse][cont1], lly[nclasse][cont2]) <distanza)

                                   {

                                               distanza = dist(theta[nclasse][cont1],lly[nclasse][cont2]);

                                               md[nclasse][cont1] = cont2;

                                   }

                                   cont2 = cont2+1;

                        }

                        cont1 = cont1+1;

                        cont2 = 0;

                        distanza = 9999;

            }

}

 

void somma (float *v1, float *v2)

{

            int cont = 0;

            while (cont<NUMPAR)

            {

                        v1[cont] = v1[cont]+v2[cont];

                        cont = cont+1;

            }

}

 

void calcola (float *v1, float *sum, int n)

{

            int cont = 0;

            while (cont<NUMPAR)

            {

                        v1[cont] = sum[cont]/n;

                        cont = cont+1;

            }

}

 

void azzerav (float *v)

{

            int cont = 0;

            while (cont<NUMPAR)

            {

                        v[cont] = 0;

                        cont = cont+1;

            }

}

 

void passo (float ***theta, float ***lly, int **md, int *thetal, int *llyl, int nclasse)

{

            printf("."); fflush(stdout);

//BY     cout << "."; flush (cout) ;

            int cont1 = 0,cont2=0;

            float sum[10000];

            int n = 0;

            mindist (theta, lly, md, thetal, llyl, nclasse) ;

            while (cont1<llyl[nclasse])

            {

                        azzerav (sum) ;

                        while (cont2<thetal[nclasse])

                        {

                                   if (md[nclasse][cont2] == cont1)

                                   {

                                               n = n+1;

                                               somma (sum, theta[nclasse][cont2]) ;

                                   }

                                   cont2 = cont2+1;

                        }

                        if (n != 0)

                        {

                                   calcola (lly[nclasse][cont1], sum, n) ;

                        }

                        cont2 = 0;

                        n = 0;

                        cont1 = cont1+1;

            }

}

 

void azzeram (float **m, int numpat)

{

            int cont1 = 0,cont2=0;

            while (cont1<numpat)

            {

                        while (cont2<NUMPAR)

                        {

                                   m[cont1][cont2] = 0;

                                   cont2 = cont2+1;

                        }

                        cont1 = cont1+1;

                        cont2 = 0;

            }

}

 

void copiam (float **m1, float **m2, int numpat)

{

            int cont1 = 0,cont2=0;

            while (cont1<numpat)

            {

                        while (cont2<NUMPAR)

                        {

                                   m1[cont1][cont2] = m2[cont1][cont2];

                                   cont2 = cont2+1;

                        }

                        cont1 = cont1+1;

                        cont2 = 0;

            }

}

 

int confronta (float **m1, float **m2, int numpat)

{

            int cont1 = 0,cont2=0,s=0;

            while (cont1<numpat)

            {

                        while (cont2<NUMPAR)

                        {

                                   if (m1[cont1][cont2] != m2[cont1][cont2])

                                   {

                                               s = s+1;

                                   }

                                   cont2 = cont2+1;

                        }

                        cont1 = cont1+1;

                        cont2 = 0;

            }

            return (s) ;

}

 

void algoritmo (float ***theta, float ***lly, int **md, int *thetal, int *llyl, int nclasse)

{

            float **interna;

            interna = new float*[llyl[nclasse]];

            int cont = 0;

            while (cont<llyl[nclasse])

            {

                        interna[cont] = new float[NUMPAR];

                        cont = cont+1;

            }

            azzeram (interna, llyl[nclasse]) ;

            int confronto = 1;

            while (confronto != 0)

            {

                        copiam (interna, lly[nclasse], llyl[nclasse]) ;

                        passo (theta, lly, md, thetal, llyl, nclasse) ;

                        confronto = confronta(interna,lly[nclasse],llyl[nclasse]);

            }

}

 

void lloyd (float ***theta, float ***lly, int **md, int *thetal, int *llyl)

{

            int cont = 0;

            while (cont<NUMCLASS)

            {

                        algoritmo (theta, lly, md, thetal, llyl, cont) ;

                        cont = cont+1;

            }

}

 

void copiav (float *v1, float *v2)

{

            int cont = 0;

            while (cont<NUMPAR)

            {

                        v1[cont] = v2[cont];

                        cont = cont+1;

            }

}

 

void crea (float ***theta, float ***lly, int *thetal, int *llyl)

{

            int mod = 0;

            int cont1 = 0,cont2=0,cont3=0;

            while (cont1<NUMCLASS)

            {

                        mod = thetal[cont1]/llyl[cont1];

                        while (cont2<llyl[cont1])

                        {

                                   while (cont3<NUMPAR)

                                   {

                                               lly[cont1][cont2][cont3] = theta[cont1][cont2*mod][cont3];

                                               cont3 = cont3+1;

                                   }

                                    cont2 = cont2+1;

                                   cont3 = 0;

                        }

                        cont1 = cont1+1;

                        cont2 = 0;

                        cont3 = 0;

            }

}

 

void creal (int *thetal, int *llyl, int fatrid)

{

            int cont = 0;

            int fint = fatrid;

            while (cont<NUMCLASS)

            {

                        while ( (thetal[cont]/fint)  == 0)

                        {

                                   fint = fint-1;

                        }

                        llyl[cont] = (thetal[cont]/fint);

                        fint = fatrid;

                        cont = cont+1;

            }

}

 

void deltaw (float *v1, float *v2, float epsilon)

{

            int cont = 0;

            while (cont<NUMPAR)

            {

                        v1[cont] = v1[cont]+(epsilon*(v2[cont]-v1[cont]));

                        cont = cont+1;

            }

}

 

int pvicino (float *v, float **km, int kml)

{

            int cont = 0;

            int fine = 0;

            float distanza = 9999;

            while (cont<kml)

            {

                        if (dist (v, km[cont]) <distanza)

                        {

                                   distanza = dist(v,km[cont]);

                                   fine = cont;

                        }

                        cont = cont+1;

            }

            return (fine) ;

}

 

 

void km (float ***theta, float ***km, int *thetal, int *kml, float epsilon, int maxiter)

{

            int cont1 = 0,cont2=0;

            int buff = 0;

            while (cont1<NUMCLASS)

            {

                        while (cont2<thetal[cont1])

                        {

                                   deltaw (km[cont1][pvicino (theta[cont1][cont2], km[cont1], kml[cont1]) ], theta[cont1][cont2], epsilon) ;

                                   cont2 = cont2+1;

                        }

                        buff = buff+1;

                        if (buff == maxiter)

                        {

                                   buff = 0;

                                   cont1 = cont1+1;

                        }

                        cont2 = 0;

            }

}

 

void creathetal (int *thetal, char v[])

{

            FILE *pippo;

            int cont = 0,ci=0;

    //float flo[3];

            //float xx,yy,zz;

            while (cont<NUMCLASS)

            {

                        pippo = fopen(v,"rb");

                        float a = 0;

                        int b = 0;

                        int buf = 0;

                        while (!feof (pippo) )

                        {

                                   fscanf (pippo, "%d", &b) ;

                                   if ( (b - 1)  == cont) buf = buf+1;

                                   ci = 0;

                                   while (ci<NUMPAR)

                                   {

                                               fscanf (pippo, "%f", &a) ;

 

 

 

                                               ci = ci+1;

                                   }

                        }

                        fclose (pippo) ;

                        thetal[cont] = buf;

                        buf = 0;

                        cont = cont+1;

            }

}

 

void creatheta (float ***theta, char v[])

{

            FILE *pippo;

            int cont = 0;

            double flo[13];

            double xx,yy,xxx,yyy;

            int bjt=0;

            xxx=0;

            yyy=0;

                valoremaxx=-1000.0;// utili se il programma viene fatto girare piu' volte

                        valoremaxy=-1000.0;

                        valoreminx=1000.0;

                        valoreminy=1000.0;

                        offsetx=0;

                        offsety=0;

            // pezzo di calcolo per la calibrazione della finestra (coefficienti moltiplicativi ed offset)

            while (cont<NUMCLASS)

            {

                        pippo = fopen(v,"rb");

                        float a = 0;

                        int b = 0;

                        int buf = 0,ci=0;

 

           

                       

                        while (!feof (pippo) )

                        {

                                   fscanf (pippo, "%d", &b) ;

                                   if ( (b - 1)  == cont)

                                   {

                                               ci = 0;

                                               while (ci<(NUMPAR))

                                               {

                                                           fscanf (pippo, "%f", &a) ;

                                               // ******************************************

                                if (ci ==0) flo[0]=a;           

                                               if (ci ==1) flo[1]=a;

                                if (ci ==2) flo[2]=a;           

                                               if (ci ==3) flo[3]=a;

                                if (ci ==4) flo[4]=a;           

                                               if (ci ==5) flo[5]=a;

                                if (ci ==6) flo[6]=a;           

                                               if (ci ==7) flo[7]=a;

                                if (ci ==8) flo[8]=a;           

                                               if (ci ==9) flo[9]=a;

                                               if (((ci == (NUMPAR-1))))

                                               {

 

                                                           xx = flo[dimx];

                                                           yy = flo[dimy];

 

                                                           if (xx > valoremaxx) valoremaxx=xx;

                                                           if (yy > valoremaxy) valoremaxy=yy;                             

                                                           if (xx < valoreminx) valoreminx=xx;

                                                           if (yy < valoreminy) valoreminy=yy;

                                              

                                               }

                                                           ci = ci+1;

                                               }

                                               buf = buf+1;

                                   }

                                   if ( (b - 1)  != cont)

                                   {

                                               ci = 0;

                                               while (ci < NUMPAR)

                                               {

                                                           fscanf (pippo, "%f", &a) ;

                                                           ci = ci+1;

                                               }

                                   }

                        }

                        fclose (pippo) ;

                        buf = 0;

                        cont = cont+1;

            }

            cont=0;

 

            //valoremaxx=4;

            //valoremaxy=4;

            //valoreminx=1;

            //valoreminy=-1;

 

            valoretotale=valass(valoremaxx-valoreminx);

            coeffmoltiplx = (double) valass(double(double (finestrax) / (double)valoretotale));

            offsetx = - valoreminx;

 

            valoretotale=valass(valoremaxy-valoreminy);

            coeffmoltiply = (double) valass(double(double((finestray-10)) / (double)valoretotale));

            offsety= - valoreminy;

 

            //coeffmoltiplx=coeffmoltiplx/2;

            offsetx=offsetx*coeffmoltiplx;

            offsety=offsety*coeffmoltiply;

            // pezzo originale

 

            while (cont<NUMCLASS)

            {

                        pippo = fopen(v,"rb");

                        float a = 0;

                        int b = 0;

                        int buf = 0,ci=0;

                        while (!feof (pippo) )

                        {

                                   fscanf (pippo, "%d", &b) ;

                                   if ( (b - 1)  == cont)

                                   {

                                               ci = 0;

                                               while (ci<(NUMPAR))

                                               {

                                                           fscanf (pippo, "%f", &a) ;

                                               // ******************************************

                                              

                                if (ci ==0) flo[0]=a;           

                                               if (ci ==1) flo[1]=a;

                                if (ci ==2) flo[2]=a;           

                                               if (ci ==3) flo[3]=a;

                                if (ci ==4) flo[4]=a;           

                                               if (ci ==5) flo[5]=a;

                                if (ci ==6) flo[6]=a;           

                                               if (ci ==7) flo[7]=a;

                                if (ci ==8) flo[8]=a;           

                                               if (ci ==9) flo[9]=a;

                                               if ((ci == (NUMPAR-1)))

                                               {

                                                           xx = flo[dimx];

                                                           yy = flo[dimy];

                                                           if ((tipoxv == 0) || (tipoxv == 1))

                                                           {

                                                           colorepenna(cont);

                                                           colorepennello(cont);

                                                           disegnaellisse ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimpunti);                             

                                                           }

                                                           }

 

 

                                                           theta[cont][buf][ci] = a;

                                                           ci = ci+1;

                                               }

                                               buf = buf+1;

                                   }

                                   if ( (b - 1)  != cont)

                                   {

                                               ci = 0;

                                               while (ci<NUMPAR)

                                               {

                                                           fscanf (pippo, "%f", &a) ;

                                                           ci = ci+1;

                                               }

                                   }

                        }

                        fclose (pippo) ;

                        buf = 0;

                        cont = cont+1;

            }

}

 

 

int contaclass (char v[])

{

            FILE *pippo;

            int fine = 0;

            int cont = 0,ci=0;

            pippo = fopen(v,"rb");

            float a = 0;

            int b = 0;

            while (!feof (pippo) )

            {

                        fscanf (pippo, "%d", &b) ;

                        if (b>fine) fine = b;

                        ci = 0;

                        while (ci<NUMPAR)

                        {

                                   fscanf (pippo, "%f", &a) ;

                                   ci = ci+1;

                        }

            }

            fclose (pippo) ;

            cont = cont+1;

            return (fine) ; 

}

 

void creafile (char vin[], char vout[])

{

            FILE *filein;

            FILE *fileout;

            char ci;

            filein = fopen(vin,"rb");

            fileout = fopen(vout,"w");

            while (!feof (filein) )

            {

                        fscanf (filein, "%c", &ci) ;

                        if (ci != '#')

                        {

                                   fprintf (fileout, "%c", ci) ;

                        }

                        if (ci == '#')

                        {

                                   while (ci != '\n')

                                   {

                                               fscanf (filein, "%c", &ci) ;

                                   }

                        }

            }

            fclose (filein) ;

            fclose (fileout) ;

}

 

int contapar (char v[])

{

            int nump = 0;

            FILE *filein;

            filein = fopen(v,"rb");

            char ci = 'c';

            while (ci != '\n')

            {

                        fscanf (filein, "%c", &ci) ;

                        if (ci == '.') nump = nump+1;

            }

            fclose (filein) ;

            return (nump) ;

}

 

void calibral (int *llyl, int *calibl)

{

            int cont = 0;

            while (cont<NUMCLASS)

            {

                        calibl[cont] = (llyl[cont]+1);

                        cont = cont+1;

            }

}

 

 

void calibra (float ***theta, float ***lly, float ***calib, int *thetal, int *llyl, int *calibl)

{

            float mint[30][1000][10000];

            int a1 = 0,a2=0;

            int b1 = 0,b2=0;

            float di = 999;

            int classe = 999;

            int conta = 0;

            while (a1<NUMCLASS)

            {

                        while (a2<thetal[a1])

                        {

                                   di = 999;

                                   while (b1<NUMCLASS)

                                   {

                                               while (b2<llyl[b1])

                                               {

                                                           if (dist (theta[a1][a2], lly[b1][b2]) <di)

                                                           {

                                                                       di = dist(theta[a1][a2],lly[b1][b2]);

                                                                       classe = b1;

                                                           }

                                                           b2 = b2+1;

                                               }

                                               b2 = 0;

                                               b1 = b1+1;

                                   }

                                   b2 = 0;

                                   b1 = 0;

                                   if (classe != a1)

                                   {

                                               copiav (mint[a1][conta], theta[a1][a2]) ;

                                               if (conta<999) conta = conta+1;

                                   }

                                   classe = 999;

                                   di = 999;

                                   a2 = a2+1;

                        }

                        b2 = 0;

                        b1 = 0;

                        classe = 999;

                        di = 999;

                        a2 = 0;

                        a1 = a1+1;

            }

            conta = 0;

            a1 = 0;

            a2 = 0;

            float x = 1;

            while (a1<NUMCLASS)

            {

                        while (a2<llyl[a1])

                        {

                                   copiav (calib[a1][a2], lly[a1][a2]) ;

                                   a2 = a2+1;

                        }

                        a2 = 0;

                        a1 = a1+1;

            }

            a1 = 0;

            a2 = 0;

            b1 = 0;

            int mint2l[30];

            float mint2[30][10000];

            while (a1<NUMCLASS)

            {

                        while (a2<NUMPAR)

                        {

                                   mint2[a1][a2] = 0;

                                   a2 = a2+1;

                        }

                        a2 = 0;

                        a1 = a1+1;

            }

            a1 = 0;

            a2 = 0;

            while (a1<NUMCLASS)

            {

                        while (b1<1000&&x != 0)

                        {

                                   x = mint[a1][b1][0];

                                   while (a2<NUMPAR)

                                   {

                                               mint2[a1][a2] = mint2[a1][a2]+mint[a1][b1][a2];

                                               a2 = a2+1;

                                   }

                                   a2 = 0;

                                   b1 = b1+1;

                        }

                        mint2l[a1] = b1;

                        b1 = 0;

                        a2 = 0;

                        a1 = a1+1;

            }

            a1 = 0;

            a2 = 0;

            while (a1<NUMCLASS)

            {

                        while (a2<NUMPAR)

                        {

                                   mint2[a1][a2] = (mint2[a1][a2]/mint2l[a1]);

                                   a2 = a2+1;

                        }

                        a2 = 0;

                        a1 = a1+1;

            }

            a1 = 0;

            while (a1<NUMCLASS)

            {

                        copiav (calib[a1][calibl[a1] - 1], mint2[a1]) ;

                        a1 = a1+1;

            }

           

}

 

 

void kmeans (int friduzione, int iter, char vin[], char vout[])

{  

            float xx,yy,zz=0;

            time (&longtime) ;

            creafile (vin, vout) ;

            NUMPAR = contapar(vout);

            NUMCLASS = contaclass(vout);

            //float ***theta;

            //float ***lly;

            int **md;

 

 

            theta = new float**[NUMCLASS];

            int s = 0;

            int z = 0;

            creathetal (thetal, vout) ;

            while (s<NUMCLASS)

            {

                        theta[s] =  new float*[thetal[s]];

                        while (z<thetal[s])

                        {

                                   theta[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            creatheta (theta, vout) ;

            lly = new float**[NUMCLASS];

            creal (thetal, llyl, friduzione) ;

            s = 0;

            z = 0;

            while (s<NUMCLASS)

            {

                        lly[s] =  new float*[llyl[s]];

                        while (z<llyl[s])

                        {

                                   lly[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            md = new int*[NUMCLASS];

            s = 0;

            z = 0;

            while (s<NUMCLASS)

            {

                        md[s] = new int[thetal[s]];

                        s = s+1;

            }

            crea (theta, lly, thetal, llyl) ;

            if (tipoxv == 2)

            {

            creaatt();

            disattivapunti(); // disattiva i punti

            }

            km (theta, lly, thetal, llyl, (float).1, iter) ; // chiama la procedura di calcolo

            FILE *uscita;

            uscita = fopen(vout,"w");

            fprintf (uscita, "# VQ Date : %s", ctime (&longtime) ) ;

            FILE *entrata;

            entrata = fopen(vin,"rb");

            char ki = 'p';

            while (!feof (entrata) )

            {

                        fscanf (entrata, "%c", &ki) ;

                        if (ki == '#')

                        {

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {          

                                               //  scrive i commenti iniziali

                                               fscanf (entrata, "%c", &ki) ;

                                               fprintf (uscita, "%c", ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                        }

            }

            fclose (entrata) ;

            entrata = fopen(vin,"rb");

            char si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

                        // scrive commento

                        fprintf (uscita, "%c", si) ;

            }

            fclose (entrata) ;

            s = 0;

            z = 0;

            int ci = 0;

            if (tipoxv == 1)

            { // ************** ******** *********

            creaattc();

            disattivacampioni();

            }

            while (s<NUMCLASS)

            {

                        while (z<llyl[s])

                        {

                                   // ************************************  numero classe

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   }

 

                                   ci = 0;

                                   while (ci<NUMPAR)

                                   {

                                               if ((tipoxv ==0) || (tipoxv == 2))

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ; // scrive i numeri

                                               }

                                               if (tipoxv == 1)

                                               {

                                               if (attc[s][z][0] == true)

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ; // scrive i numeri

                                               }

                                               }

                                              

                                              

                                               if ((ci == 0))

                                               {

                                                           xx = lly[s][z][dimx];

                                                           yy = lly[s][z][dimy];

                                                           //if (voronoidaeseguire==1) voronoi(xx*coeffmoltiplx+offsetx,yy*coeffmoltiply+offsety,s);

                                                           if ((tipoxv ==0) || (tipoxv == 2))

                                                           {

                                                           colorepenna(s);

                                                           colorepennello(s);

                                                           disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                                                           }

                                                           if (tipoxv == 1)

                                                           {

                                                                       if (attc[s][z][0] == true)

                                                                       {

                                                                       colorepenna(s);

                                                                       colorepennello(s);

                                                                       disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                                                                       }

                                                           }

                                                                                 

                                               }

                                               ci = ci+1;

                                              

                                   }

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "\n") ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "\n") ;                             

                                   }

                                   }

                                   z = z+1;

                        }

                        z = 0;

                        progressbar(s,NUMCLASS);

                        s = s+1;

            }

            //matricecalcolata(lly);

            fclose (uscita) ;

 

           

            /*          begin CONFRONTO

            printf ("\n\nInizio confronto\n\n") ;

            int a1 = 0,a2=0;

            int b1 = 0,b2=0;

            int conteggio = 0;

            float di = 999;

            int classe = 999;

            while (a1<NUMCLASS)

            {

                        while (a2<thetal[a1])

                        {

                                   di = 999;

                                   while (b1<NUMCLASS)

                                   {

                                               while (b2<llyl[b1])

                                               {

                                                           if (dist (theta[a1][a2], lly[b1][b2]) <di)

                                                           {

                                                                       di = dist(theta[a1][a2],lly[b1][b2]);

                                                                       classe = b1;

                                                           }

                                                           b2 = b2+1;

                                               }

                                               b2 = 0;

                                               b1 = b1+1;

                                   }

                                   b2 = 0;

                                   b1 = 0;

                                   if (classe != a1) conteggio = conteggio+1;

                                   classe = 999;

                                   di = 999;

                                   a2 = a2+1;

                        }

                        b2 = 0;

                        b1 = 0;

                        classe = 999;

                        di = 999;

                        a2 = 0;

                        a1 = a1+1;

            }

            printf ("\n\nPUNTI ERRATI : %d\n\n", conteggio) ;

            */         

           

}

 

void lloyd (int friduzione, char vin[], char vout[])

{

            time (&longtime) ;

            creafile (vin, vout) ;

            NUMPAR = contapar(vout);

            NUMCLASS = contaclass(vout);

            //float ***theta;

            //float ***lly;

            //int **md;

            //int thetal[30];

 

            theta = new float**[NUMCLASS];

            int s = 0;

            int z = 0;

            creathetal (thetal, vout) ;

            while (s<NUMCLASS)

            {

                        theta[s] =  new float*[thetal[s]];

                        while (z<thetal[s])

                        {

                                   theta[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            creatheta (theta, vout) ;

            lly = new float**[NUMCLASS];

            creal (thetal, llyl, friduzione) ;

            s = 0;

            z = 0;

            while (s<NUMCLASS)

            {

                        lly[s] =  new float*[llyl[s]];

                        while (z<llyl[s])

                        {

                                   lly[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            md = new int*[NUMCLASS];

            s = 0;

            z = 0;

            while (s<NUMCLASS)

            {

                        md[s] = new int[thetal[s]];

                        s = s+1;

            }

            crea (theta, lly, thetal, llyl) ;

            if (tipoxv == 2)

            {

            luy = true;

            creaatt();

            disattivapunti(); // disattiva i punti

            }

            lloyd (theta, lly, md, thetal, llyl) ;  // calcola lloyd

            //    (theta, lly,     thetal, llyl)

            luy = false;

           

            /* BEGIN CALIBRATION

           

            printf ("\n\n Inizio calibrazione \n\n") ;

            float ***calib;

            int calibl[NUMCLASS];

            calibral (llyl, calibl) ;

            calib = new float**[NUMCLASS];

            s = 0;

            z = 0;

            while (s<NUMCLASS)

            {

                        calib[s] =  new float*[calibl[s]];

                        while (z<calibl[s])

                        {

                                   calib[s][z] =  new float[NUMPAR];

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            calibra (theta, lly, calib, thetal, llyl, calibl) ;

           

            */

           

           

            FILE *uscita;

            uscita = fopen(vout,"w");

            fprintf (uscita, "# VQ Date : %s", ctime (&longtime) ) ;

            FILE *entrata;

            entrata = fopen(vin,"rb");

            char ki = 'p';

            while (!feof (entrata) )

            {

                        fscanf (entrata, "%c", &ki) ;

                        if (ki == '#')

                        {

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                               fprintf (uscita, "%c", ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                        }

            }

            fclose (entrata) ;

            entrata = fopen(vin,"rb");

            char si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p'; 

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

                        fprintf (uscita, "%c", si) ;

            }

            fclose (entrata) ;

            s = 0;

            z = 0;

            int ci = 0;

            if (tipoxv == 1)

            { // ************** ******** *********

            creaattc();

            disattivacampioni();

            }

 

            while (s<NUMCLASS)

            {

                        while (z<llyl[s])

                        {

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   }

                                   ci = 0;

                                   while (ci<NUMPAR)

                                   {

                                               float xx=0;

                                               float yy=0;

                                               if ((tipoxv ==0) || (tipoxv == 2))

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ;

                                               }

                                               if (tipoxv == 1)

                                               {

                                               if (attc[s][z][0] == true)

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ;                                 

                                               }

                                               }                                             

                                               if ((ci == 0))

                                               {

                                                           xx = lly[s][z][dimx];

                                                           yy = lly[s][z][dimy];

                                                           //if (voronoidaeseguire==1) voronoi(xx*coeffmoltiplx+offsetx,yy*coeffmoltiply+offsety,s);

                                                           if ((tipoxv ==0) || (tipoxv == 2))

                                                           {

                                                           colorepenna(s);

                                                           colorepennello(s);

                                                           disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                                                           }

                                                           if (tipoxv == 1)

                                                           {

                                                                       if (attc[s][z][0] == true)

                                                                       {

                                                                       colorepenna(s);

                                                                       colorepennello(s);

                                                                       disegnaquadrato ((xx*coeffmoltiplx+offsetx),(yy*coeffmoltiply+offsety),dimcampioni);

                                                                       }

                                                           }                      

                                               }

                                               ci = ci+1;

                                   }

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "\n") ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "\n") ;

                                   }

                                   }

                                   z = z+1;

                        }

                        z = 0;

                        progressbar(s,NUMCLASS);

                        s = s+1;

            }

            //matricecalcolata(lly);

            fclose (uscita) ;

           

            /* begin CONFRONTO

            printf ("\n\nInizio confronto\n\n") ;

            int a1 = 0,a2=0;

            int b1 = 0,b2=0;

            int conteggio = 0;

            float di = 999;

            int classe = 999;

            while (a1<NUMCLASS)

            {

                        while (a2<thetal[a1])

                        {

                                   di = 999;

                                   while (b1<NUMCLASS)

                                   {

                                               while (b2<llyl[b1])

                                               {

                                                           if (dist (theta[a1][a2], lly[b1][b2]) <di)

                                                           {

                                                                       di = dist(theta[a1][a2],lly[b1][b2]);

                                                                       classe = b1;

                                                           }

                                                           b2 = b2+1;

                                               }

                                               b2 = 0;

                                               b1 = b1+1;

                                   }

                                   b2 = 0;

                                   b1 = 0;

                                   if (classe != a1) conteggio = conteggio+1;

                                   classe = 999;

                                   di = 999;

                                   a2 = a2+1;

                        }

                        b2 = 0;

                        b1 = 0;

                        classe = 999;

                        di = 999;

                        a2 = 0;

                        a1 = a1+1;

            }

            printf ("\n\nPUNTI ERRATI : %d\n\n", conteggio) ;

            */

           

}

 

// Inizio MAIN

 

void main1 ()

{

 

            if ( (lork == 'k') )

            {

                        //printf("\nComputing"); fflush(stdout);

//BY                 cout << "\nComputing"; flush (cout) ;

                        lloyd (ftrd , "dati.trn", "out.out") ;

                        //printf ("\n\n") ;

            }

            if ( ( lork= 'l') )

            {

                        //printf ("\nComputing") ;

                        kmeans (ftrd , 100, "dati.trn", "out.out") ;

                        //printf ("\n\n") ;

            }

 

 

}

 

void salva(char vin[], char vout[])

{

            if (done==0) return;

            int s=0;

            int z=0;

            int ci=0;

                        FILE *uscita;

            uscita = fopen(vout,"w");

            fprintf (uscita, "# VQ Date : %s", ctime (&longtime) ) ;

            FILE *entrata;

            entrata = fopen(vin,"rb");

            char ki = 'p';

            while (!feof (entrata) )

            {

                        fscanf (entrata, "%c", &ki) ;

                        if (ki == '#')

                        {

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                               fprintf (uscita, "%c", ki) ;

                                   }

                                   ki = 'p';

                                   while (ki != '\n')

                                   {

                                               fscanf (entrata, "%c", &ki) ;

                                   }

                        }

            }

            fclose (entrata) ;

            entrata = fopen(vin,"rb");

            char si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p';

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

            }

            si = 'p'; 

            while (si != '\n')

            {

                        fscanf (entrata, "%c", &si) ;

                        fprintf (uscita, "%c", si) ;

            }

            fclose (entrata) ;

 

                        while (s<NUMCLASS)

            {

                        while (z<llyl[s])

                        {

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "%d ",  (s + 1) ) ;

                                   }

                                   }

                                   ci = 0;

                                   while (ci<NUMPAR)

                                   {

                                               float xx=0;

                                               float yy=0;

                                               if ((tipoxv ==0) || (tipoxv == 2))

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ;

                                               }

                                               if (tipoxv == 1)

                                               {

                                               if (attc[s][z][0] == true)

                                               {

                                               fprintf (uscita, "%f ", lly[s][z][ci]) ;                                 

                                               }

                                               }                                             

                                               ci = ci+1;

                                   }

                                   if ((tipoxv ==0) || (tipoxv == 2))

                                   {

                                   fprintf (uscita, "\n") ;

                                   }

                                   if (tipoxv == 1)

                                   {

                                   if (attc[s][z][0] == true)

                                   {

                                   fprintf (uscita, "\n") ;

                                   }

                                   }

                                   z = z+1;

                        }

                        z = 0;

                        s = s+1;

            }

            fclose (uscita) ;

}

 

 

 

 

 

 

int APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     int       nCmdShow)

{

            // TODO: Place code here.

 

 

            MSG msg;

            HACCEL hAccelTable;

 

 

            // Initialize global strings

            LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

            LoadString(hInstance, IDC_MERDA, szWindowClass, MAX_LOADSTRING);

            MyRegisterClass(hInstance);

 

            // Perform application initialization:

            if (!InitInstance (hInstance, nCmdShow))

            {

                        return FALSE;

            }

 

            hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MERDA);

 

            // Main message loop:

            while (GetMessage(&msg, NULL, 0, 0))

            {

                         

                        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

                        {

                                   TranslateMessage(&msg);

                                   DispatchMessage(&msg);

                        }

            }

 

            return msg.wParam;

}

 

 

 

//

//  FUNCTION: MyRegisterClass()

//

//  PURPOSE: Registers the window class.

//

//  COMMENTS:

//

//    This function and its usage is only necessary if you want this code

//    to be compatible with Win32 systems prior to the 'RegisterClassEx'

//    function that was added to Windows 95. It is important to call this function

//    so that the application will get 'well formed' small icons associated

//    with it.

//

ATOM MyRegisterClass(HINSTANCE hInstance)

{

            WNDCLASSEX wcex;

 

            wcex.cbSize = sizeof(WNDCLASSEX);

 

            wcex.style                                = CS_HREDRAW | CS_VREDRAW;

            wcex.lpfnWndProc        = (WNDPROC)WndProc;

            wcex.cbClsExtra                       = 0;

            wcex.cbWndExtra                     = 0;

            wcex.hInstance             = hInstance;

            wcex.hIcon                               = LoadIcon(hInstance, (LPCTSTR)IDI_MERDA);

            wcex.hCursor                = LoadCursor(NULL, IDC_ARROW);

            wcex.hbrBackground     = (HBRUSH)(COLOR_WINDOW+1);

            wcex.lpszMenuName    = (LPCSTR)IDC_MERDA;

            wcex.lpszClassName    = szWindowClass;

            wcex.hIconSm              = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

 

            return RegisterClassEx(&wcex);

}

 

//

//   FUNCTION: InitInstance(HANDLE, int)

//

//   PURPOSE: Saves instance handle and creates main window

//

//   COMMENTS:

//

//        In this function, we save the instance handle in a global variable and

//        create and display the main program window.

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

   HWND hWnd;

 

   hInst = hInstance; // Store instance handle in our global variable

 

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 

   if (!hWnd)

   {

      return FALSE;

   }

 

   ShowWindow(hWnd, nCmdShow);

   UpdateWindow(hWnd);

 

   return TRUE;

}

 

//

//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)

//

//  PURPOSE:  Processes messages for the main window.

//

//  WM_COMMAND       - process the application menu

//  WM_PAINT  - Paint the main window

//  WM_DESTROY        - post a quit message and return

//

//

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

            int iu;

 

 

 

            TCHAR szHello[MAX_LOADSTRING];

            LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

  

            switch (message)

            {

                        case WM_COMMAND:

                                   wmId    = LOWORD(wParam);

                                   wmEvent = HIWORD(wParam);

                                   // Parse the menu selections:

                                   switch (wmId)

                                   {

                                  

                                               case IDM_ABOUT:

                                                  DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);

                                                  //param2 = TRUE;

                                                  break;

                                               case IDM_EXIT:

                                                  DestroyWindow(hWnd);

                                                  break;

                                               case PARAMETRO1:

                                                  //DialogBox(hInst, (LPCTSTR)FINESTRAPARAMETRO1, hWnd, (DLGPROC) fatridfin);

                                                  //iu = EndDialog(hWnd,IDC_RADIO1);

                                                  ftrd1 = (int) 10;          

                                                  //iu = InvalidateRgn(hWnd, NULL, 1);                

                                                  break;

                                               case PARAMETRO2:

                                                           ftrd1 = 25;

                                                           done=0;

                                                  break;

                                               case PARAMETRO3:

                                                           ftrd1 = 50;

                                                           done=0;

                                                  break;

                                               case PARAMETRO4:

                                                           ftrd1 = 75;

                                                           done=0;

                                                  break;

                                               case PARAMETRO5:

                                                           ftrd1 = 100;

                                                           done=0;

                                                  break;

                                               case PARAMETRO11:

                                                  iterr = (int) 10;

                                                  done=0;

                                                  break;

                                               case PARAMETRO12:

                                                           iterr = 25;

                                                           done=0;

                                                  break;

                                               case PARAMETRO13:

                                                           iterr = 50;

                                                           done=0;

                                                  break;

                                               case PARAMETRO14:

                                                           iterr = 75;

                                                           done=0;

                                                  break;

                                               case PARAMETRO15:

                                                           iterr = 100;

                                                           done=0;

                                                  break;

                                               case PARAMETRO21:

                                                   dimx = 0;     

                                                           done = 0;

                                                  break;

                                               case PARAMETRO22:

                                                           dimx = 1;

                                                           done = 0;

                                                  break;

                                               case PARAMETRO23:

                                                           dimx = 2;

                                                           done = 0;

                                                  break;

                                               case PARAMETRO24:

                                                           dimx = 3;

                                                           done = 0;

                                                  break;

                                               case PARAMETRO25:

                                                           dimx = 4;

                                                           done = 0;

                                                           break;

                                               case PARAME