Beruflich Dokumente
Kultur Dokumente
Versione 0.1.1
Flavio Bernardotti f.bernardotti@amcitaly.net
PROJECT MANAGER PROGETTO BIOTRACCIABILITA
Introduzione
Il progetto biotracciabilit costituito da diversi gruppi logici
relativi ciascuno ad una problematica differente come ad esempio
l'acquisizione dell'immagine della retina, la sua elaborazione
grafica, la creazione del codice di preselezione all'interno di un
database, la sua comparazione con un'immagine di retina acquisita
precedentemente e cos via sino a giungere al sistema informativo
destinato alla gestione logica di tutto insieme.
Uno dei blocchi, tra l'altro uno di quelli pi delicati da cui
dipende la buona riuscita di tutto resto del progetto, quello
relativo alla creazione del sistema ottico capace di eseguire
l'acquisizione dell'immagine della retina.
Normalmente quando si progetto un obiettivo si tiene conto dei
parametri relativi allo stesso per cui le modifiche del percorso
ottico vengano considerate esclusivamente ed intrinsecamente al
obiettivo.
Purtroppo la retina non come uno degli oggetti che ci circondano
nel mondo esterno ma un qualche cosa presente all'interno di una
sfera dentro la quale si accede tramite un foro di dimensioni
ridotte il quale possiede a sua volta una lente utilizzata
dall'occhio stesso per la focalizzazione delle immagine del nostro
mondo reale.
Questa lente costituisce un'alterazione del percorso ottica o di
un ipotetico obiettivo studiato per acquisire l'immagine retinale.
In altre parole nella progettazione di questo obiettivo si deve
considerare il potere diottrico del cristallino.
Nella progettazione degli obiettivi fotografici ci si deve tener
conto delle focalizzazione relativamente al mondo esterno ma anche
del modo per illuminarlo.
Essendo la retina contenuta all'interno dell'occhio e chiaro che
l'unico metodo per illuminarla e quella di fare passare la luce
attraverso la pupilla e quindi attraverso il cristallino.
Senza considerare dati altamente scientifici e facile immaginare
come la luce potrebbe di fatto creare grossi problemi nell'ambito
del sistema di ripresa a causa della superficie lucida costituita
dalla cornea dell'occhio e di fatto anche dal potere al ferrante
rispetto a percorso ottico che possiede il cristallino.
In effetti la riflessione causata dalla lucidit della cornea
potrebbe costituire un problema all'interno dell'attivit di
ripresa.
Il sistema ottico.
La ripresa di una retina all'interno dell'occhio di una mucca di
fatto un'operazione complessa che deve tenere conto di molti
fattori.
Nei normali sistemi di ripresa l'obiettivo tiene conto di una
focalizzazione minima ma di fatto generalmente non deve aver a che
fare con una oggetti che modificano il percorso ottico.
Nel caso dell'occhio della mucca abbiamo, all'interno della
pupilla, una lente che possiede sui due lati delle focali
differenti che permettano di creare le immagine virtuale, da una
parte, sulla retina e, dall'altra parte, sull'ambiente esterno.
Se
mediante
una
macchina
da
ripresa
dovessimo acquisire le
immagine delle parti
esterne
dell'occhio
non
avremmo
nessun
tipo di problema in
quanto l'occhio stesso
risulterebbe
essere
come un normalissimo
oggetto
del
mondo
esterno per cui gli
unici problemi di cui
dovremmo tenere conto
sarebbero quelli della
quantit
di
luce
e
quindi
della
regolazione
di
un
diaframma atto a aumentare o diminuire la quantit di questa che
arriverebbe alla cella di ripresa
e della focale ovvero del
sistema di lenti necessario per mettere a fuoco loggetto ad una
certa distanza.
La massima difficolt che potremmo incontrare
potrebbe essere collegata al fatto che locchio
essendo una superficie lucida potrebbe riflettere
le cose posizionate davanti a lui oltre alla luce
dellilluminazione.
Essendo la retina oltre questa lente chiamata
cristallino
il
sistema
di
acquisizione
dell'immagine deve essere calcolato tenendo conto
delle focali relative alla sua parte interna e a
quella esterna.
Inoltre i problemi relativi all'acquisizione delle
retinali coinvolge anche il sistema di illuminazione.
immagini
rivolta
alla
ricerca di quanto esiste gi
fatto
con il fine di
trovare almeno un indirizzamento.
Sfortunatamente in questo settore non esiste nulla se non gli
oftalmoscopi i quali comunque sono molto differenti in quanto la
ripresa dellimmagine retinale avviene a contatto con locchio.
I metodi legati all'acquisizione della retina nell'ambito umano
differiscono a causa di molte particolarit anche se di fatto la
cosa fondamentale rimane la non collaborazione che c' da parte
dell'animale al momento della ripresa stessa.
Gli portavano scoppi esistenti per uso umano sono essenzialmente
di due tipi e precisamente:
Tipo indiretto
Tipo diretto
delle
lenti
una guida di
delle
lenti
Designed to Give Increased Resolution and Smaller Spot Sizes for NIR Wavelengths (700-1100nm)
Decreased Spherical Aberration for Monochromatic Sources Out to 2m
Broadband AR Coating has <1% Reflectivity Between 7001550nm
Our new Tech Spec Near IR doublets are designed to provide the smallest spot size possible for
polychromatic light between 700 and 1100nm. By utilizing our NIR doublets instead of standard doublets
designed for the visible, RMS spot diameter can be reduced from 43m to 22.5m, for example, when using
polychromatic light. Spot size will be smaller when focusing monochromatic sources. Near-IR doublets also
reduce spherical aberration and have superior performance when used with a monochromatic source up to 2m
in wavelength. Typical applications for these doublets include: CCD imaging lenses for the near infrared,
focusing and expanding of NIR lasers, and focusing/collimating lenses for fiber optics and NIR LEDs .
Specification Table
Diameter
Surface Quality
Dia. Tolerance
C.T. Tolerance
Centering Tolerance
3.00
40-20
+0.0/-0.05
0.2
3 - 5 arc min.
6.00 - 25.00
40-20
+0.0/-0.10
0.2
3 - 5 arc min.
50.00
60-40
+0.0/-0.10
0.2
3 - 5 arc min.
Notes
Bevel
Clear Aperture
Description
LENS ACH-
3.00mm dia.:
50.00mm dia.:
CA = diameter - 1.00mm
Glass Type
LaKN22-SFL6
Focal Length
Coating
E.T. Tolerance
Reference
Dia. E.F.L.
(mm) (mm)
Back
Radius Radius Radius
C.T.1 C.T.2 E.T.
MTF
F.L.
R1
R2
R3
(mm) (mm) (mm)
Curve
(mm)
(mm) (mm) (mm)
Stock Number
12
18
12.3
2.5
8.41
12.05
-8.65
-37.28
MTF
Curve
NT45-791
12
20
14.18
2.5
8.65
13.13
-9.59
-45.11
MTF
Curve
NT45-792
12
25
21.05
4.5
2.5
5.58
15.56
-13.75
-84.13
MTF
Curve
NT45-793
12
30
25.83
4.5
2.5
5.82
17.77
-16.46
-136.8
MTF
Curve
NT45-794
12
35
30.73
4.5
2.5
20.23
-19.17 -193.84
MTF
Curve
NT45-795
12
40
35.67
4.5
2.5
6.12
22.81
-21.91 -250.49
MTF
Curve
NT45-796
12
50
46.7
2.5
4.8
28.51
-322.09
MTF
Curve
NT45-797
12
60
56.67
2.5
4.92
33.92
-33.81 -419.99
MTF
Curve
NT45-798
12
75
71.65
2.5
4.03
42.11
-565.11
MTF
Curve
NT45-799
15
25
19.49
5.65
3.7
6.76
14.94
-14.94 -120.18
MTF
Curve
NT45-826
15
30
25.62
5.15
17.36
-17.36 -187.86
MTF
Curve
NT45-827
NIR 25 X 100
NIR-II
25
100
93.89
8.49
57.01
-56.72 -656.51
MTF
Curve
NT45-806
LENS ACH-
25
200
193.9
9.25
NIR 12 X 18
NIR-II
LENS ACHNIR 12 X 20
NIR-II
LENS ACHNIR 12 X 25
NIR-II
LENS ACHNIR 12 X 30
NIR-II
LENS ACHNIR 12 X 35
NIR-II
LENS ACHNIR 12 X 40
NIR-II
LENS ACHNIR 12 X 50
NIR-II
LENS ACHNIR 12 X 60
NIR-II
LENS ACHNIR 12 X 75
NIR-II
LENS ACHNIR 15 X 25
NIR-II
LENS ACHNIR 15 X 30
NIR-II
LENS ACH-
NIR 25 X 200
-28.2
-42.3
112.88 -112.88
MTF
1415.62 Curve
NT47-271
NIR-II
LENS ACHNIR 25 X 35
NIR-II
LENS ACHNIR 25 X 40
NIR-II
LENS ACHNIR 25 X 45
NIR-II
LENS ACHNIR 25 X 50
NIR-II
LENS ACHNIR 25 X 60
NIR-II
LENS ACHNIR 25 X 75
NIR-II
LENS ACHNIR 3 X 10
NIR-II
LENS ACHNIR 3 X 15
NIR-II
LENS ACH-
NIR 50 X 100
NIR-II
LENS ACHNIR 6 X 12
NIR-II
LENS ACHNIR 6 X 15
NIR-II
LENS ACHNIR 6 X 20
NIR-II
LENS ACHNIR 6 X 25
NIR-II
LENS ACHNIR 6 X 30
NIR-II
LENS ACHNIR 6 X 35
NIR-II
LENS ACHNIR 6 X 40
NIR-II
LENS ACHNIR 6 X 9
NIR-II
LENS ACHNIR 9 X 15
NIR-II
LENS ACHNIR 9 X 20
NIR-II
MTF
Curve
NT45-800
-22.26 -105.93
MTF
Curve
NT45-801
29.01
-25.53 -132.92
MTF
Curve
NT45-802
8.94
31.69
-28.45 -161.05
MTF
Curve
NT45-803
9.46
36.27
-33.8
-248.86
MTF
Curve
NT45-804
7.98
43.96
-42.9
-392.21
MTF
Curve
NT45-805
8.09
1.8
2.58
5.2
-5.2
MTF
Curve
NT45-822
15
13.07
1.8
2.65
7.71
-7.71
MTF
Curve
NT45-823
50
100
87.86
14.5
5.5
13.89
59.74
-59.74
-494.7
MTF
Curve
NT47-317
50
150
139.87
11
5.5
12.47
86.84
-86.84
-894.7
MTF
Curve
NT47-318
12
9.3
3.2
3.15
6.84
-5.99
-69.82
MTF
Curve
NT45-784
15
12.42
1.2
3.61
8.8
-7.93
-71.17
MTF
Curve
NT45-785
20
17.27
1.3
3.86
11.29
-10.63
-134.8
MTF
Curve
NT45-786
25
22.24
1.3
3.95
13.95
-13.4
-193.19
MTF
Curve
NT45-787
30
27.22
1.3
4.01
16.66
-16.18 -246.07
MTF
Curve
NT45-788
35
32.22
1.3
4.05
19.39
-297.39
MTF
Curve
NT45-789
40
37.17
1.3
4.08
21.81
-22.07 -454.78
MTF
Curve
NT45-790
6.66
1.3
4.26
7.34
-4.18
-11.58
MTF
Curve
NT45-783
15
11.59
4.2
4.84
9.68
-7.91
-39.89
MTF
Curve
NT45-824
20
16.46
3.5
4.49
11.01
-11.01
-222.6
MTF
Curve
NT45-825
25
35
26.87
11
10.48
23.4
25
40
31.74
11
11.09
26.27
25
45
37.8
9.59
25
50
43.29
25
60
52.96
25
75
69.06
10
-20.11
-19
-87.52
Le lenti THORLAB
Product Summary
Wavelength Range: 170nm to 8.0m, Un coated
Focal Lengths from 20mm to 1000mm
Plano-Convex optics are best used where one conjugate point (object distance, S or image distance S) is more than five
times the other.This lens shape is near best-form for either focusing collimated light or for collimating a point source.
Part Number
LA5315
LA5183
LA5458
LA5370
LA5763
LA5042
LA5817
LA5012
LA5714
LA5255
LA5464
LA5956
DIA
efl
tc
Material
12.7
20.0
4.3
CAF2
12.7
50.0
2.5
CAF2
12.7
80.0
2.1
CAF2
25.4
40.0
7.5
CAF2
25.4
50.0
6.1
CAF2
25.4
75.0
4.6
CAF2
25.4
100.0
3.9
CAF2
25.4
150.0
3.3
CAF2
25.4
200.0
2.9
CAF2
25.4
250.0
2.8
CAF2
25.4
500.0
2.4
CAF2
25.4
750.0
2.3
CAF2
25.4
LA5835
1000.0
2.2
CAF2
Product Summary
Best Possible Performance from a Spherical Singlet
Ideal for High Powered Applications
These lenses are an ideal choice for application from 200nm to 6m. Magnesium Fluoride is extremely durable in
comparison to other materials that reach this far down into the UV or out into the IR. The C-axis is oriented to minimize
birefringence.
Plano-Convex optics are best used where one conjugate point (object distance, S or image distance S) is more than five
times the other.This lens shape is near best-form for either focusing collimated light or for collimating a point source.
Order
Part Number
LA6002
LA6003
LA6004
LA6005
LA6006
LA6007
LA6008
LA6009
LA6010
DIA
efl
fb
tc
Material
25.4
50.0
45.0
6.9
MgF2
25.4
60.0
55.5
6.0
MgF2
25.4
75.0
71.4
5.0
MgF2
25.4
100.0
97.1
4.3
MgF2
25.4
150.0
147.7
3.2
MgF2
25.4
200.0
197.7
3.2
MgF2
25.4
250.0
248.0
2.8
MgF2
25.4
500.0
498.1
2.6
MgF2
25.4
1000.0
998.3
2.4
MgF2
Product Summary
Wavelength Range: 185nm to 2.1m, Uncoated
Focal Lengths from 10mm to 1000mm
Diameters from 5mm to 75mm
Standard AR UV Coating Available: 290-370nm
Plano-Convex optics are best used where one conjugate point (object distance, S or image distance S) is more than five
times the other.This lens shape is near best-form for either focusing collimated light or for collimating a point source.
Part Number
LA4249
LA4280
LA4917
LA4194
LA4966
LA4647
LA4936
LA4130
LA4765
LA4327
LA4600
LA4052
LA4306
LA4148
LA4725
LA4380
LA4236
LA4874
LA4924
LA4102
LA4158
LA4579
LA4184
LA4716
LA4663
LA4464
LA4078
LA4545
LA4904
LA4984
LA4538
LA4855
LA4782
DIA
efl
tc
Material
Price
5.0
10.0
2.2
UVFS
$73.20
6.0
10.0
2.6
UVFS
$69.80
6.0
15.0
2.2
UVFS
$69.50
6.0
20.0
2.0
UVFS
$68.00
6.0
30.0
1.8
UVFS
$68.00
12.7
20.0
4.3
UVFS
$71.80
12.7
30.0
3.4
UVFS
$67.00
12.7
40.0
2.9
UVFS
$60.00
12.7
50.0
2.7
UVFS
$54.00
12.7
75.0
2.4
UVFS
$54.00
12.7
100.0
2.2
UVFS
$48.00
25.4
35.0
8.2
UVFS
$113.00
25.4
40.0
7.1
UVFS
$88.00
25.4
50.0
5.8
UVFS
$83.50
25.4
75.0
4.4
UVFS
$75.90
25.4
100.0
3.8
UVFS
$74.20
25.4
125.0
3.4
UVFS
$72.00
25.4
150.0
3.2
UVFS
$69.90
25.4
175.0
3.0
UVFS
$68.50
25.4
200.0
2.9
UVFS
$67.90
25.4
250.0
2.7
UVFS
$66.80
25.4
300.0
2.6
UVFS
$66.50
25.4
500.0
2.4
UVFS
$65.80
25.4
750.0
2.2
UVFS
$65.30
25.4
1000.0
2.2
UVFS
$65.00
50.8
60.0
19.8
UVFS
$240.00
50.8
75.0
14.2
UVFS
$230.00
50.8
100.0
10.7
UVFS
$214.00
50.8
150.0
7.8
UVFS
$206.00
50.8
200.0
6.6
UVFS
$194.80
50.8
250.0
5.8
UVFS
$182.00
50.8
300.0
5.4
UVFS
$168.00
50.8
500.0
4.4
UVFS
$156.00
LA4745
LA4337
LA4384
LA4372
LA4795
LA4246
LA4249-UV
LA4280-UV
LA4917-UV
LA4194-UV
LA4966-UV
LA4647-UV
LA4936-UV
LA4130-UV
LA4765-UV
LA4327-UV
LA4600-UV
LA4052-UV
LA4306-UV
LA4148-UV
LA4725-UV
LA4380-UV
LA4236-UV
LA4874-UV
LA4924-UV
LA4102-UV
LA4158-UV
LA4579-UV
LA4184-UV
LA4716-UV
LA4663-UV
LA4464-UV
LA4078-UV
LA4545-UV
LA4904-UV
LA4984-UV
LA4538-UV
LA4855-UV
LA4782-UV
LA4745-UV
LA4337-UV
LA4384-UV
LA4372-UV
LA4795-UV
LA4246-UV
50.8
750.0
3.9
UVFS
$146.00
50.8
1000.0
3.7
UVFS
$146.00
75.0
90.0
26.9
UVFS
$398.00
75.0
150.0
14.1
UVFS
$350.00
75.0
200.0
11.0
UVFS
$326.00
75.0
500.0
6.1
UVFS
$278.00
5.0
10.0
2.2
UVFS
$87.20
6.0
10.0
2.6
UVFS
$83.80
6.0
15.0
2.2
UVFS
$83.50
6.0
20.0
2.0
UVFS
$82.00
6.0
30.0
1.8
UVFS
$82.00
12.7
20.0
4.3
UVFS
$85.80
12.7
30.0
3.4
UVFS
$81.00
12.7
40.0
2.9
UVFS
$74.00
12.7
50.0
2.7
UVFS
$68.00
12.7
75.0
2.4
UVFS
$68.00
12.7
100.0
2.2
UVFS
$62.00
25.4
35.0
8.2
UVFS
$141.00
25.4
40.0
7.1
UVFS
$116.00
25.4
50.0
5.8
UVFS
$111.50
25.4
75.0
4.4
UVFS
$103.90
25.4
100.0
3.8
UVFS
$102.20
25.4
125.0
3.4
UVFS
$100.00
25.4
150.0
3.2
UVFS
$97.90
25.4
175.0
3.0
UVFS
$96.50
25.4
200.0
2.9
UVFS
$95.90
25.4
250.0
2.7
UVFS
$94.80
25.4
300.0
2.6
UVFS
$94.50
25.4
500.0
2.4
UVFS
$93.80
25.4
750.0
2.2
UVFS
$93.30
25.4
1000.0
2.2
UVFS
$93.00
50.8
60.0
19.8
UVFS
$292.00
50.8
75.0
14.2
UVFS
$282.00
50.8
100.0
10.7
UVFS
$266.00
50.8
150.0
7.8
UVFS
$258.00
50.8
200.0
6.6
UVFS
$246.80
50.8
250.0
5.8
UVFS
$234.00
50.8
300.0
5.4
UVFS
$220.00
50.8
500.0
4.4
UVFS
$208.00
50.8
750.0
3.9
UVFS
$198.00
50.8
1000.0
3.7
UVFS
$198.00
75.0
90.0
26.9
UVFS
$450.00
75.0
150.0
14.1
UVFS
$402.00
75.0
200.0
11.0
UVFS
$378.00
75.0
500.0
6.1
UVFS
$330.00
Presbiopia
Hyperopia la condizione in
che l'immagine di oggetti
distanti cade dietro alla
retina.
Questo
accade
quando
la
lunghezza assiale della lente
troppo corta per il potere
del sistema della lente.
Una parte che a prima vista sembrerebbe centrare poco con gli
studi relativi al sistema di acquisizione dell'immagine della
retina, potrebbe essere quella legata al uso delle lenti
finalizzata alla correzione dei difetti del cristallino.
Di fatto questo permette di capire come un sistema di lenti
esterne pu interagire con il cristallino spesso al fine di creare
una giusta focalizzazione sulla retina dell'occhio
Correzione della miopia
il potere tangenziale, T = 1 / Jt
i sagittal motorizzano, S = 1 / Js
Cattivo potere = (T + S) / 2
Astigmatismo = | T - S |
Motorizzi errore = il Cattivo potere - Prescrisse il potere
Le seguenti
della mucca.
immagini
mostrano
le
varie
componenti
dellocchio
La sua estrazione
Lo spessore
Liride
Il cristallino
Il fondo retinale
La retina
Le ghiandole
Il nervo ottico
Gli oftalmoscopi
Come dicevamo prima all'inizio di una ricerca sempre necessario
crearsi una visione di tutto quello patrimonio informativo che
disponibile a riguardo di quanto gi fatto in questo determinato
settore.
Chiaramente le riprese dei fondi retina alle in campo veterinario
non sono un settore cos diffuso per cui l'unica documentazione
reperibile relativa a tutto quello che riguarda la ripresa delle
retina in campo umano.
In questo settore bisogna per mettere un filtro alle ricerche in
quanto la caratteristica fondamentale del nostro progetto rimane
quella, come in tanti altri progetti, relativa al prezzo al quale
si dovr vendere il prodotto.
In campo oftalmico i prodotti sono spesso costosissimi per cui
molti progetti sono relativi ad apparecchiature composte da
strumenti tecnologicamente avanzatissime e quindi anche molto
costose.
Il tipo di apparecchiature d'anno ricercato
relativo a prodotti composte da un sistema di
illuminatore e da una cella di ripresa.
doveva
lenti,
essere
da un
20030098952
A1
May 29, 2003
351/200
351/200
A61B 003/00
20030063386
A1
April 3, 2003
adapted to be received at a patient's eye orbit. An outer diameter of a patient end of the eye cup is
sized to correspond to a patient eye orbit such that a viewing axis is substantially centered on
patient's pupil when the eye cup is received at an eye orbit. The eye cup is preferably made
deformable so that patient comfort is improved and further so that contact of the eye cup with an
eye orbit alerts a physician that the device is approaching an operative axial standoff position. The
eye cup may also be made so that the device pivots about a pivot point toward a patient end of the
eye cup such that the angular orientation of the device can be adjusted without disrupting the
device's operative radial displacement and axial standoff positioning. The eye cup further blocks
ambient light from impinging on an eye, thereby substantially eliminating a source of external glare.
By allowing the device to be stabilized against an eye orbit the eye cup eases the task of
maintaining an operative position once an operative position has been achieved.
Inventors:
Slawson, Steven R.; (Camillus, NY) ; Roberts, Chris R.; (Skaneateles, NY) ;
Krauter, Allan I.; (Skaneateles, NY) ; Goldfain, Ervin; (Syracuse, NY)
Correspondence George S. Blasiak
Name and
WALL MARJAMA & BILINSKI
Address:
101 South Salina Street, Suite 400
Syracuse
NY
13202
US
Assignee Name Welch Allyn, Inc.
and Adress:
Serial No.:
783224
Series Code:
09
Filed:
February 14, 2001
U.S. Current Class:
359/600
U.S. Class at Publication:
359/600
Intern'l Class:
G02B 021/00; G02B 023/16
20030157464
A1
August 21, 2003
Tanassi, Cesare; (Pont della Priula (TV), IT) ; Piermarocchi, Dott. Stefano;
(Padova, IT) ; Buscemi, Philip M.; (Greensboro, NC)
Correspondence Walter L. Beavers
Name and
326 South Eugene Street
Address:
Greensboro
NC
27401
US
Serial No.:
364869
Series Code:
10
Filed:
February 11, 2003
U.S. Current Class:
434/81
U.S. Class at Publication:
434/81
Intern'l Class:
G09B 011/00
20030206272
A1
November 6, 2003
Cornsweet, Tom N.; (Prescott, AZ) ; Buck, Gary F.; (Prescott, AZ)
Correspondence
Name and
Address:
351/206
351/206
A61B 003/14
Le ipotesi iniziali
Data la natura dellocchio ed in particolare del fondo retinale
riflettente i problemi legati alla creazione di un illuminatore
possono derivare da tre problemi fondamentali.
La
La
La
La
poca potenza
troppa potenza
posizione sbagliata
lunghezza donda errata
Nelle varie prove fatte
subito apparso il problema.
fatte
essere
caso
locchio
divent
luminoso
equilibrata
in
impedendo
quanto
quella
di
in
Un altro dei problemi che vennero subito alla luce era causato
dalla natura riflettente del cristallino.
La sorgente di luce veniva riflessa
problemi nellimmagine dellocchio.
per
cui
questa
creava
L illuminatore
Loss
Inoltre un altro parametro critico legato alla scelta del tipo di
illuminazione era la lunghezza d'onda e la potenza della luce
stessa.
In fatti si pensava che la luce visibile potesse di fatto far
restringere la pupilla complicando in questo modo il metodo di
acquisizione.
L'idea di poter utilizzare una luce all'infrarosso, teoricamente,
ci fece pensare che questa di fatto non avrebbe interagito con
pupilla.
D'altra parte una luce all'infrarosso di fatto non avrebbe potuto
avere una potenza pari ad una lampadina con luce visibile in
quanto avrebbe potuto recare danni all'occhio della mucca.
Alcune oftalmoscopiche avevamo in prova presso la nostra societ
utilizzavano la luce visibile ed inoltre possedevano alcuni filtri
colorati che permettevano di cambiare il contrasto relativo
all'immagine della retina.
Tre
oftalmoscopi
presi
in
esame
illuminazione simile ma non uguali.
possedevano
metodi
di
Introduction
Product Overview and Description
Product Use and Procedure
Features and Benefits
Frequently Asked Questions
Customer Testimonials
Technical Specifications
Warranty
Other Information
Product Ordering Information
Introduction
The Welch Allyn PanOptic Ophthalmoscope is a revolutio
visualizing the fundus.
Customer Testimonials
To read numerous testimonials on the PanOptic Ophthalmosco
website.
Technical Specifications
Dimensions:
Weight:
Warranty
One-year warranty on the PanOptic Ophthalmoscope.
Other Information
To view Pathologies such as normal fundus, toxoplasmas, retin
through a PanOptic click here to visit the Pathologies page on
La fisica dellottica
In questa sezione vengono riportati i principi fondamentali della
fisica dell'ottica.
Tale riporto allo scopo di indicare le teorie che sono state
utilizzate per il calcolo delle parti composte da lenti.
Le onde elettromagnetiche sono descritte da componenti costituiti
da campi elettrici e magnetici.
Una parte relativamente piccola dello spettro elettromagnetico
viene fisicamente percepita dall'occhio come colore.
Normalmente siamo abituati a dare il nome di luce a questa
porzione.
Qualsiasi campo elettrico o magnetico pu essere misurato.
L'altezza dell'onda va via con il tempo.
La sua propagazione descritta dalla formula :
La Percezione Visiva
v = ln
Figura 5.1
1,0000
1,0003
2,47 2,75
1,46
1,51 1,57
1,54 1,75
1,33
Ei = Er + Ei
Possiamo,
quindi,
introdurre
due
rispettivamente
di
riflessione
e
trasmissione), in modo da avere:
coefficienti
r
di
rifrazione
e
(o
t,
di
Er = r Ei Ei = t Ei
Sostituendo
ottiene:
queste
due
espressioni
nella
prima
relazione
si
r + t = 1
Figura 5.2a
Figura 5.2b
Figura 5.3a
Figura 5.3b
Nelle due figure 5.4a e 5.4b, vediamo applicate queste tre regole
per costruire graficamente limmagine di una sorgente estesa. Nel
primo caso (fig. 5.4a), loggetto posto ad una distanza
superiore rispetto alla focale: si vede che i raggi ottici
convergono dallaltra parte e ci restituiscono unimmagine reale
(potremmo
proiettarla
su
uno
schermo,
ad
esempio,
oppure
sfruttarla come sorgente per una seconda lente). Nel secondo caso
(fig. 5.4b), loggetto posto tra il fuoco e il centro della
lente: i prolungamenti virtuali dei raggi si incontrano dietro la
sorgente
reale,
dandoci
in
prossimit
del
secondo
fuoco
unimmagine ingrandita di essa che, essendo virtuale, pu essere
soltanto osservata dal nostro occhio ma non pu essere proiettata
su uno schermo, n usata come sorgente per una seconda lente.
Figura 5.4a
Figura 5.4b
Figura 5.5
5.3 Il Cannocchiale
Il primo cannocchiale dovrebbe essere stato costruito da un ottico
fiammingo allinizio del XVII secolo. Galileo, avuta notizia
dellinvenzione, ne produsse uno proprio, perfezionandolo in
seguito,
e
lo
rivolse
subito
al
cielo,
facendo
le
sue
importantissime
scoperte.
Keplero
ne
miglior
ancora
le
prestazioni sostituendo con una lente convessa quella concava
delloculare (vedi pi avanti) di Galileo.
Figura 5.6a
Figura 5.6b
capovolta;
con
linserzione di una terza lente tra le prime due si pu
raddrizzare limmagine, a scapito della sua qualit perch ogni
lente introduce alcuni difetti (vedi 5.5); per luso astronomico
linversione dei riferimenti non crea eccessivi problemi, quindi
non si usano dispositivi raddrizzatori.
Numerosi
miglioramenti
sono
stati
fatti
al
"primitivo"
cannocchiale che noi abbiamo esaminato, fino ad arrivare al
monumentale rifrattore di Yerkes (Wisconsin, USA), con un
obbiettivo di 102 cm di diametro...
Una lente, inoltre, assorbe una considerevole parte della
radiazione luminosa incidente e questo degenera le prestazioni dei
telescopi rifrattori al crescere del diametro e dello spessore
delle lenti (vedi nota 4). Gli specchi che si usano negli
strumenti ottici, al contrario, riflettono almeno il 90% della
radiazione incidente e non sono dispersivi; per questo motivo i
telescopi di qualit sono tutti riflettori (vedi 5.6).
LOcchio Umano
Prima di tutto opportuno dare una descrizione sommaria del
funzionamento del "sensore" della percezione visiva, cio locchio
umano, le parti principali del quale sono rappresentate in figura
5.8.
La superficie esterna anteriore dellocchio ricoperta da una
membrana trasparente, detta cornea, che, insieme al cristallino,
una vera e propria "lente", focalizza unimmagine reale e
capovolta degli oggetti sulla rtina, una membrana sensibile
interna allocchio. La luce che incide sulla retina viene
convertita in segnali elettrici. Attraverso il nervo ottico,
questi vengono condotti al cervello che provvede ad elaborarli e a
generare la sensazione visiva.
La retina costituita da uno strato di 0,2 mm di due tipi di
cellule diverse: i coni e i bastoncelli, in totale 125 milioni di
Figura 5.8
Lastigmatismo
quale, da sferica,
allora, non sono
determinato asse e
dalla distanza a
lenti cilindriche.
Figura 5.9
F = V(l) W
Figura 5.10
Questi parametri non sono assoluti; la visione
"con memoria", ovvero fortemente influenzata
osservato in precedenza. Il nostro cervello in
la
percezione
allintensit
globale
dello
una sensazione
da ci che si
grado di adattare
stimolo.
Se
la
dovuto
alcuna
prova
inconfutabile della sua esistenza, la quale perci dovrebbe essere
rifiutata.
E se si rifiuta questa esistenza, anche le ipotesi secondo le
quali la luce consiste in un moto che si propaga attraverso tale
mezzo vanno rigettate con esso.''
L'autorit e la grande considerazione di cui Newton godeva fece
propendere la maggior parte degli studiosi dell'epoca verso la
teoria corpuscolare sulla natura della luce, secondo la quale essa
composta da uno sciame di particelle di dimensioni infinitesime,
soggette anch'esse alle leggi di gravitazione.
Rimanevano per aperti i gravi problemi gi accennati insiti in
tale teoria, e di conseguenza rimaneva aperto lo scontro
dialettico fra l'una e l'altra ipotesi che doveva concludersi,
come vedremo, con il trionfo del modello ondulatorio della luce e
successivamente con il recupero di alcuni concetti espressi nella
teoria corpuscolare, all'interno della fisica quantistica e con
l'introduzione del concetto di Fotone.
La propagazione rettilinea della luce: la formazione delle ombre
ed il modello del "fronte di onda" di Huygens
Abbiamo accennato, in precedenza, al fatto che il modello
ondulatorio della luce fosse da taluni considerato in contrasto
con la propagazione rettilinea della luce in qualunque mezzo
trasparente ed omogeneo.
L' osservazione sperimentale di questo fenomeno (la propagazione
rettilinea della luce) molto semplice e certamente ognuno avr
avuto modo di osservarlo, ad esempio esaminando la luce che filtra
dalle imposte e la formazione delle ombre.
delineati
si
passa
gradualmente
; se C la velocit di tali
, il fronte di ogni singola onda di luce
e centro in
l'istante
sar ancora una retta. L'avanzamento che noi
osserviamo pertanto quello di un' onda piana che, come sappiamo,
viaggia in linea retta (fig. (3.6)).
Successivi
esperimenti
approssimare il valore a
pi
precisi
gli
, noto il valore
consentirono
di
Questo fornisce:
anzicch
una
dove
ed
orbitano i
(5.1.1)).
singoli
elettroni
che
hanno
carica
negativa
(fig.
In natura
ciascuna
coerenti
strumenti
a causa dell'illuminazione.
.
Un
Violle
l'intensit
luminosa
prodotta
dalla
superficie
di
sono
.
rispettivamente
le
intensit
sorgenti
e se
sono le distanze di
carta, vale allora la seguente legge:
luminose
delle
dal foglio di
da cui si ottiene:
Se
essere
data
ondulatoria
e
corpuscolare
e
permetter
comportamento della luce nelle lenti.
di
studiare
il
La rifrazione
Consideriamo un raggio luminoso che viaggia attraverso un mezzo
trasparente, ad esempio l'aria. Se sul suo cammino incontra un
nuovo mezzo trasparente, ad esempio acqua o vetro, nel passaggio
dall'uno all'altro mezzo il raggio subisce una deviazione
abbastanza netta. Si dice in tal caso che il raggio viene
rifratto.
Inoltre
sussiste
rispettivamente gli
osserva che:
la
seguente
relazione:
angoli di incidenza e di
se
sono
rifrazione, si
(1.1)
La (1.1) trova una spiegazione differente a seconda che
consideri valida la teoria corpuscolare o quella ondulatoria.
si
Ma come sappiamo, si ha
(1.3)
e quindi risulta:
(1.4)
Diciamo che il mezzo 2 pi rifrangente del mezzo 1 se l'angolo
di incidenza maggiore di quello di rifrazione quando un raggio
luminoso passa dal mezzo 1 al mezzo 2.
Se allora conduciamo il nostro esperimento scegliendo, ad esempio,
i mezzi aria e vetro, oppure aria ed acqua (l'acqua e il vetro
sono pi rifrangenti dell'aria), si avr:
per cui dalla teoria
corpuscolare si ricava che
corpuscolare
spiega
invece
Costruiamo,
quindi,
il
raggio
rifratto
con
dell'inviluppo piano gi introdotto precedentemente.
il
il
fenomeno
metodo
, poich si
suppone che
(1.5)
da cui:
(1.6)
Risulta pertanto dalla teoria ondulatoria una legge inversa da
quella ricavata nella teoria corpuscolare, cio:
e quindi
maggiore nei mezzi meno rifrangenti.
la
velocit
della
luce
, uguale a
il
si ottiene facilmente:
(2.1)
relazione che lega l'indice di rifrazione relativo con gli indici
di rifrazione assoluto dei due mezzi. Nella tabella abbiamo gli
indici di rifrazione assoluto per alcuni mezzi.
MEZZO
INDICE
Aria
1,000294
Idrogeno
1,000139
Ossigeno
1,000272
Acqua
1,33
Alcol etilico
1,36
NaCl
1,53
Vetro Flint
1,579
Vetro Crown
1,516
Diamante
2,419
Zaffiro
1,76
Glicerina
1,474
Olio di cedro
1,515
Quarzo
1,544
Quarzo fuso
1,46
Etere
1,352
Se
tale valore, per un angolo di incidenza maggiore di
, non
si avr la formazione di nessun raggio rifratto, ma il raggio
verr deviato totalmente all'interno del mezzo pi rifrangente,
dando luogo al fenomeno della cosiddetta riflessione totale.
prende il nome di angolo limite.
si ricava anche
Se
(3.1)
lente convergente
per
il
fuoco
deviato
parallelamente
dipender
Indichiamo con
il centro ottico.
dalla
distanza
dell'oggetto
dalla
lente.
L'immagine
capovolta,
rimpicciolita
.
posta
dall'altra
parte
parte
caso
la
(4.2.1)
Se poniamo le distanze XC e CX' pari rispettivamente a p e a q, la
(4.2.1) si scrive:
(4.2.2)
Sono inoltre simili i triangoli
Da ci possiamo ricavare:
(4.2.3)
dove f la distanza focale.
(4.2.4)
e confrontando la (4.2.2) e la (4.2.4) otteniamo
quindi
(4.2.5)
e dividendo ogni termine per pqf
(4.2.6)
Come si vede, la (4.2.6) analoga alla formula dedotta per gli
specchi sferici.
Abbiamo
ricavato
inoltre
la
formula
per
l'
ingrandimento
trasversale, definito dal rapporto fra la lunghezza dell'oggetto e
quella della sua immagine. La (4.2.4) infatti fornisce:
(4.2.7)
(4.2.8)
Lenti divergenti
La principale differenza di una lente divergente rispetto ad una
convergente costituita dal fatto che se consideriamo un fascio
di raggi paralleli all'asse principale della lente, essi verranno
rifratti non in modo da intersecarsi in un punto, ma in modo da
"divergere" senza mai intersecarsi.
Se per consideriamo i prolungamenti dei
occorrono in un punto sull'asse principale.
raggi
rifratti,
essi
si
posizione
sempre
virtuale, diritta
dell'oggetto.
rimpicciolita,
posta
dalla
stessa
parte
la riflessione, pertanto
sistema di specchi per
telescopio "acromatico".
invece dovuto al
tipo di onda, noto
fenomeno
come il
una
figura
di
interferenza costituita da una serie di sottili striscie di colore
scuro, disposte perpendicolarmente rispetto al piano che contiene
le sorgenti.
Se consideriamo un punto sullo schermo interessato dal fascio di
luce proveniente dalle due sorgenti coerenti, si osserva
se
sono
le
distanze
rispettive
del
punto
dalle
sorgenti
la lunghezza d'onda della luce, la condizione
di interferenza costruttiva
(3.1)
La condizione di interferenza distruttiva si ha invece quando si
verifica:
(3.2)
Infatti nell'esperimento, la differenza di fase che genera
l'interferenza dovuta proprio al fatto che le onde luminose
prodotte dalla stessa sorgente segnano due cammini differenti.
Come si vede dalle formule
lunghezza d'onda della luce.
l'interferenza
dipende
anche
dalla
(3.5)
per cui
(3.6)
Polarizzazione
Fu solo agli inizi del 1800 che alcune importanti esperienze
condotte
soprattutto
da
Fresnel
provarono
una
importante
caratteristica delle onde luminose che era insospettata fino ad
allora,
cio
le
onde
luminose
sono
trasversali
e
non
longitudinali, come quelle sonore. Ricordiamo che un'onda si dice
trasversale quando lo spostamento avviene perpendicolarmente alla
direzione di propagazione; si dice longitudinale se lo spostamento
parallelo alla direzione di propagazione. Tale scoperta legata
allo studio del fenomeno della polarizzazione. Abbiamo visto che
la luce si forma per le vibrazioni che avvengono a livello atomico
corrispondenti ad assorbimento e successiva emissione di energia.
Pertanto da una sorgente luminosa vengono emessi numerosissimi
treni d'onda che oscillano in differenti piani, senza che se ne
possa individuare qualcuno privilegiato.
un
Legge di
(4.1)
dove
l'angolo
polarizzatore, e
di
cui
dotato
l'analizzatore
rispetto
al
dove r il
appartiene.
raggio
della
sfera
cui
la
calotta
riflettente
ad
una
distanza
maggiore
di
2f,
dell'oggetto,
anch'essa
nel
L'immagine capovolta ed
maggiore di 2f (fig. (3.5)).
ingrandita,
posta
ad
una
distanza
che
soddisfano
contiene
la
\fig{}
Come abbiamo visto, un punto oggetto S posto dinanzi ad uno
specchio concavo avr una immagine S' determinato dal punto di
occorrenza di tutti i raggi che partono da S.
Se, per semplicit, il punto oggetto collocato sull'asse
principale il punto immagine si determina considerando un singolo
raggio incidente e l'intersezione del raggio riflesso con l'asse
ottico, poich ogni raggio che coincide con un asse viene riflesso
su s stesso.
Sia SA il raggio incidente nel punto A della superficie speculare
e AS' il segmento del raggio riflesso tagliato dall'asse
principale. Per le leggi della riflessione, se CA il segmento
normale allo specchio nel punto A, gli angoli SAC e CAS' sono
uguali cio
(4.1) SAC=CAS
Come sappiamo, la bisettrice di un angolo interno di un triangolo
divide il lato opposto in parti proporzionali agli altri due lati.
Applicando questa regola al triangolo SAS', se ne ricava:
(4.2)
Poich stiamo supponendo valide le approssimazioni di Gauss, esse
ci consentono di utilizzare le seguenti espressioni approssimate:
(4.3)
Sostituendo la (4.3) in (4.2) si ottiene:
(4.4)
Poniamo ora la distanza VS pari a p e la distanza VS' pari a q. Da
ci ne segue
dove R
speculare.
il
raggio
della
sfera
cui
appartiene
la
calotta
(4.5)
ovvero
(4.6)
e dividendo ogni termine per pqR, rimane:
(4.7)
ma come sappiamo la distanza focale f pari a: f=R/2, per cui si
pu riscrivere la (4.7) come:
(4.8)
Vediamo quali
tale formula:
informazioni
si
possono
ricavare
dall'analisi
di
se poniamo il
riprodotta in S.
punto
oggetto
in
S',
la
sua
immagine
verr
(4.9)
dalla quale possiamo determinare le informazioni sulla distanza q
dell'immagine relativamente alla distanza p dell'oggetto.
Ad esempio se
con
Dunque
(poich
).
(4.10)
che si ottiene sostituendo ad f la sua espressione rispetto ad R:
. Allora se
si avr:
ovvero
Se
, per la (4.9) l'immagine sar ad una distanza
maggiore di quella focale; per la (4.10),
ovvero
Infine,
se
il
punto
oggetto
collocato
fra
il
fuoco
lo
come
se
fosse
dietro
lo
(4.11)
Poniamo ora
AB=h e A'B'=h'.
Inoltre si osserva che B'C=q-R e CB=R-p, pertanto si ha:
(4.12)
ma per la (4.5), la (4.12) diventa:
(4.13)
ovvero per la (4.9):
(4.14)
La (4.14) esprime il rapporto fra la lunghezza dell'oggetto e
della sua immagine.
Come si vede, nota la distanza focale,
valgono
ovviamente
anche
per
gli
alterazione,
invece,
questo
tipo
di
cheratite
ulcerativa
o
ulcera
corneale,
causata
da
malattie
batteriche, micotiche, virali e
clamydiosi,
traumi,
corpi
estranei, danni di natura chimica.
Versione 0.1.2
Flavio Bernardotti f.bernardotti@amcitaly.net
PROJECT MANAGER BIOTRACCIABILITA
INTRODUZIONE
Circa un anno f si inizio a pensare seriamente a tutte le
possibili soluzioni ai problemi che componevamno il progetto
definito con il termine di BIOTRACCIABILITA.
Questo era costituito da diversi componenti tra i quali alcuni
hardware e altri software.
Premessa
Identificare una retina
per accertare lidentit di un capo
animale dopo averla ripresa dinamicamente da una telecamera una
funzione per la quale diventa necessario utilizzare diverse
metodologie informatiche a partire dai sistemi di reti neurali per
giungere sino a quelli che vengono definiti con il termine di
HIDDEN MARKOV MODELLS (modelli di Markov nascosti e ibridi
neurali/markoviani).
Tutte queste tecnologie sono considerate avanzate e se considerate
dal punto di vista algoritmico sono anche complicate da scrivere e
mettere a punto.
Le tipologie di problemi sono quelli legati alla COMPUTER VISION.
La computer vision quella branca dellinformatica che si
interessa
di
implementare
funzionalit
proprie
dellinterpretazione visiva umana.
Per svolgere queste funzioni ci si avvale di parti di software
algoritmico e di altre legate a sistemi che riproducono le reti
neurali.
Alcune funzionalit che a volte sembrano molto semplici da
svolgere a vista di fatto se analizzate dal punto di vista
algoritmico possiedono complicazioni notevoli.
Per questo motivo spesso lo svolgimento di tali funzioni vengono
eseguite mediante sistemi misti che utilizzano parti algoritmiche
e parti a reti neurali.
Le reti neurali riproducono mediante un modello matematico il
funzionamento del cervello umano simulando I modelli relativi a
neuroni, sinapsi e dendridi.
Tali sistemi mettono a punto la loro intelligienza
Un sottoinsieme della computer vision e quella definita con il
termine di object recognition il cui compito quello di
identificare, allinterno di un immagine che riproduce il nostro
spazio reale, degli oggetti particolari.
Collegate alle teorie dellobject recognition troviamo moltissime
metodologie algoritmiche che permettono lo svolgimento di compiti
particolari come ad esempio la segmentazione delle immagini.
Vedremo alcuni concetti nei capitoli che seguono.
Alcuni tipi di valutazioni legate allindividuazione di una
metodologia da applicare con la retina erano sorte dalla necessit
di estraniarsi da valutazioni di tipo geometrico-spaziale le
quali, come vedremo successivamente, non possono essere eseguite
per alcuni precisi motivi.
Solo per accennare a quelli che sono i problemi legati
allidentificazione di una retina possiamo riportare la diversit
tra una ripresa e laltra legata semplicemente al modo di tenere
la camera di acquisizione da parte delloperatore.
Questo
semplice
problema
inizialmente
ci
fece
capire
che
determinati metodi di confronto delle immagini utilizzanti dati
spaziali e geometrici non potevano essere utilizzati.
Trovandosi davanti al problema di confrontare due immagini il
metodo pi semplice ed immediato dovrebbe essere quello RAW ovvero
==
In
una
seconda
fase
la
ricerca
venne
indirizzata per somiglianza di problema.
In altre parole se si guarda un immagine di una
retina di fatto sembra di vedere una traccia
fluviale presa da un immagine satellitare.
Anche in questo caso lacquisizione potrebbe
rendere un immagine ruotata, zoomata ecc.
I percorsi fluviali possono essere in piena o con il fiume in
secca.
Dicevamo prima dei problemi legati alle diverse
immagini acquisite in tempi differenti.
Per
capire
I
problemi
bisogna
pensare
alloperatore quando esegue lacquisiizione.
In pratica avviene quanto segue :
1 - Loperatore si mette davanti al capo animale
e punta con la telecamera locchio della mucca.
Ad
un
certo
punto
nel
visore
comparir
limmagine della retina. Il software deve essere
in grado di capire quando limmagine corretta
e quindi deve eseguire il ritaglio della
porzione
interessata
alloperazione
di
riconoscimento.
2
Limmagine
ritagliata
identificata tra quelle esistenti
deve
essere
differente
causa
palmare operativo.
Microsoft.
Il sistema di sviluppo possiede, a parte maggiori funzionalit
legate allaspetto della progettazione, alcune estensioni del C++
particolarmente utili per quanto riguarda la stesura del progetto
di riconoscimento.
#include "stdafx.h"
int APIENTRY WinMain(HINSTANCE
HINSTANCE
LPSTR
int
{
#include
#include
#include
#include
#include
#include
#include
#include
hInstance,
hPrevInstance,
lpCmdLine,
nCmdShow)
"stdafx.h"
"cv.h" // include core library interface
"highgui.h" // include GUI library interface
"Recog.h"
<stdio.h>
<cmath>
<string.h>
<ctime>
int main()
{
const int n = 6;
// number of images used
const int nEigens = n-1;
// number of eigen objs
int i, j, k, digit = 6;
char name[30] = "../pca1.bmp";
// 6 bmp images
char nums[7] = "012345";
// each image has a different number
double max, val, dist;
// dist between images in nEigens-d
space
FILE* outFile;
// file to store results
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* images[n];
// input images
IplImage* eigens[nEigens];
// eigenobjects
IplImage* proj[n];
// decomposed object projection
to the eigen sub-space
IplImage* avg;
// averaged object
CvTermCriteria criteria;
// criteria to stop calculating eigen
objects
float vals[nEigens];
// eigenvalues
float coeffs[n][nEigens];
// decomposition coefficients
float normCoeffs[n][nEigens]; // normalised coefficients
cvvNamedWindow( "projections", 1);
cvvNamedWindow( "images", 1);
// ************initialise variables************
if((outFile = fopen("values.txt", "w")) == NULL)
printf(" error creating file\n");
for( i=0; i<n; i++ ){
name[digit] = nums[i]; /
images
IplImage* temp = cvvLoadImage( name );
IplImage objects
load
images
into
cvReleaseImage( &temp );
cvvShowImage( "images", images[i] );
cvvWaitKey(0);
}
1 );
);
fprintf(outFile, "\n" );
}
for( j=0; j<n; j++ )
normCoeffs[j][i]=coeffs[j][i]/max;
#ifdef _CH_
#pragma package <opencv>
#endif
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#endif
IplImage *Lena = 0;// Main Source Image
IplImage *Lena_Color = 0;
IplImage *sonuc = 0;
// Names's of windows
char barname01[] = "Threshold";
char wndname1[]="BINARY";
char wndname2[]="BINARY INV";
char wndname3[]="TRUNC";
char wndname4[]="TO ZERO";
char wndname5[]="TO ZERO INV";
/*******/
CvPoint pp1, pp2;//points for min & max values
double minVal, maxVal;// min & max values
/*******/
int main( int argc, char** argv )
{
Lena = cvLoadImage( "lena.bmp",0);
Lena_Color = cvLoadImage( "lena.bmp",3);
IplImage *arama = cvLoadImage( "lena_ara.bmp",0);
// Create Windows for each image.
cvNamedWindow("Lena", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_SQDIFF_NORMED", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_CCORR", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_CCORR_NORMED", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_CCOEFF", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_CCOEFF_NORMED", CV_WINDOW_AUTOSIZE);
cvNamedWindow("CV_TM_SQDIFF", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Aranan", CV_WINDOW_AUTOSIZE);
int a = Lena->width;
int b = Lena->height;
int a2 = arama->width;
int b2 = arama->height;
sonuc = cvCreateImage( cvSize(a - a2 + 1,b - b2 +1),IPL_DEPTH_32F ,1);
cvShowImage( "Aranan",arama);// Display image
IplImage *Thresh_Sonuc5 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
IplImage *Thresh_Sonuc1 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
IplImage *Thresh_Sonuc2 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
IplImage *Thresh_Sonuc3 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
IplImage *Thresh_Sonuc4 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
IplImage *Thresh_Sonuc6 = cvCreateImage( cvSize(a - a2 + 1,b - b2
+1),IPL_DEPTH_32F ,1);
//cvCreateTrackbar( barname01, "Lena", &slider_pos[0], 255,
my_threshold );
return 0;
#ifdef _EiC
main(1,"main.cpp");
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tiffimage.h"
#include "images.h"
extern void print_sos_lic ();
#define
#define
#define
#define
#define
#define
#define
ON 0
OFF 255
ONM1 1
CONTOUR 32
CENTROID 31
MAX_CONTOUR 10000
DISPLAY_FLAG_DFLT 0
/* binarization values */
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/* user input */
if (input (argc, argv, &maxContour, &displayFlag, &printFlag) < 0)
return (-1);
imgIO = ImageIn (argv[1]);
image = imgIO->img;
height = ImageGetHeight (imgIO);
width = ImageGetWidth (imgIO);
printf ("image size is %dx%d\n", width, height);
/* allocate contour memory */
if ((cntr = (struct cntr *) calloc (maxContour, sizeof (struct cntr)))
== NULL) {
/* determine contours */
yEndM1 = height - 1;
xEndM1 = width - 1;
nContour = 0;
maxLContour = 0;
lContourSum = 0;
for (y = 1; y < yEndM1; y++) {
for (x = 1; x < xEndM1; x++) {
/* when find ON-pixel, trace contour */
if (image[y][x] == ON && image[y][x - 1] == OFF) {
nContour++;
iDirn = 2;
cntr[0].x = xStart = x;
cntr[0].y = yStart = y;
xCentroid = (double) x;
yCentroid = (double) y;
cntr[0].iDirn = iDirn;
cntr[0].curve = 0;
lContour = 1;
do {
image[y][x] = CONTOUR;
nextcntr (image, &x, &y, &iDirn);
cntr[lContour].x = x;
cntr[lContour].y = y;
cntr[lContour].iDirn = iDirn;
xCentroid += (double) x;
yCentroid += (double) y;
temp = iDirn - cntr[lContour - 1].iDirn;
if (temp > 4)
temp -= 8;
else if (temp < -4)
temp += 8;
cntr[lContour].curve = temp;
lContour++;
if (lContour == MAX_CONTOUR) {
printf ("Nuts -- maximum contour length reached = %d\n", lContour);
return (-1);
}
} while (!(x == xStart && y == yStart));
if (lContour > maxLContour)
maxLContour = lContour;
xCentroid = xCentroid / (double) lContour;
yCentroid = yCentroid / (double) lContour;
lContourSum += lContour;
if (displayFlag > 0)
image[(long) (yCentroid + 0.5)][(long) (xCentroid + 0.5)] = CENTROID;
if (printFlag != 0)
printf ("contour %ld: length = %ld, centroid = (%5.2f,%5.2f)\n",
nContour - 1, lContour, xCentroid, yCentroid);
}
}
}
switch (displayFlag) {
case 0:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
image[y][x] = (image[y][x] == CONTOUR) ? ON : OFF;
break;
case 1:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++) {
if (image[y][x] == CENTROID)
SQUARE (image, x, y);
else if (image[y][x] == ONM1);
else
image[y][x] = OFF;
}
break;
case 2:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++) {
if (image[y][x] == CENTROID)
SQUARE (image, x, y);
else if (image[y][x] == CONTOUR)
image[y][x] = ON;
else if (image[y][x] == ONM1);
else
image[y][x] = OFF;
}
break;
default:
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
image[y][x] = (image[y][x] == CONTOUR) ? ONM1 : OFF;
}
if (nContour == 0)
printf ("no image regions\n");
else
printf ("no. contours = %d, max length = %d, avg. length = %d\n",
nContour, maxLContour, lContourSum / nContour);
ImageOut (argv[2], imgIO);
}
return (0);
/* NEXTCNTR:
*/
int
nextcntr (image, x, y, iDirn)
unsigned char **image;
long *x, *y;
long *iDirn;
{
long ring[16];
long i, j;
/* isolated pixel */
*iDirn = i % 8;
switch (i) {
case 1:
case 9:
*x = *x + 1;
*y = *y - 1;
break;
case 2:
case 10:
*x = *x + 1;
break;
case 3:
case 11:
*x = *x + 1;
*y = *y + 1;
break;
case 4:
case 12:
*y = *y + 1;
break;
case 5:
case 13:
*x = *x - 1;
*y = *y + 1;
break;
case 6:
case 14:
*x = *x - 1;
break;
case 7:
case 15:
*x = *x - 1;
*y = *y - 1;
break;
case 8:
case 0:
*y = *y - 1;
break;
default:;
}
}
return (0);
/* USAGE:
*
*
*/
long
usage (flag)
short flag;
message */
{
return (-1);
/* INPUT:
*
*/
return (0);
}
pFilter->EnumPins(&pEnum);
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (bFound = (PinDir == PinDirThis))
break;
pPin->Release();
}
pEnum->Release();
return (bFound ? pPin : 0);
OpenImageEnDialog1OpenImageEnDialog1-
Elaborate2();
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
LoadImage1();
}
//---------------------------------------------------------------------------
void TForm1::Elaborate1()
{
long ww, hh, dimens;
ww = ImageEnView1->Bitmap->Width;
hh =ImageEnView1->Bitmap->Height;
dimens = hh - 60;
ImageEnView1->SelectEllipse( ww/2,hh/2, dimens,dimens,iespReplace );
HistogramBox1->Update();
ImageEnView1->Update();
}
void TForm1::Elaborate2()
{
>Height)
HistogramBox2->Update();
ImageEnView2->Update();
void TForm1::DensityHisto1()
{
int *VertHist,*HorizHist;
AnsiString temp;
int VertHistHeight,HorizHistWidth,VertHistWidth,HorizHistHeight;
int i;
VertHistWidth = ImageEnView3->ClientWidth;
VertHistHeight = ImageEnView1->Bitmap->Height;
HorizHistWidth =ImageEnView1->Bitmap->Width;
HorizHistHeight =ImageEnView4->ClientHeight;
VertHist = (int *)malloc(VertHistHeight*sizeof(int));
HorizHist = (int *) malloc(HorizHistWidth*sizeof(int));
ImageEnView1->Proc>CalcDensityHistogram(VertHist,HorizHist,VertHistWidth,HorizHistHeight);
ImageEnView3->Bitmap->Height =HorizHistHeight;
ImageEnView3->Bitmap->Width=HorizHistWidth;
// vertical
ImageEnView4->Bitmap->Height=VertHistHeight;
ImageEnView4->Bitmap->Width=VertHistWidth;
// draw histograms
ImageEnView3->Bitmap->Canvas->Pen->Color=clBlack;
ImageEnView4->Bitmap->Canvas->Pen->Color=clBlack;
for(int u=0;u!=ListBox1->Items->Count;u++)
ListBox1->Items->Delete(u);
for(i=0;i!=HorizHistWidth-1;i++) {
temp.printf("%d",HorizHist[i]);
ListBox1->Items->Add(temp);
ImageEnView3->Bitmap->Canvas->MoveTo(i, HorizHistHeight );
ImageEnView3->Bitmap->Canvas->LineTo(i, HorizHistHeight - HorizHist[i] );
}
for(int u=0;u!=ListBox2->Items->Count;u++)
ListBox2->Items->Delete(u);
for(i=0;i!=VertHistHeight-1;i++) {
temp.printf("%d",VertHist[i]);
ListBox2->Items->Add(temp);
ImageEnView4->Bitmap->Canvas->MoveTo(0, i );
ImageEnView4->Bitmap->Canvas->LineTo(VertHist[i],i);
}
free(VertHist);
free(HorizHist);
ImageEnView3->Update();
ImageEnView4->Update();
}
void __fastcall TForm1::Button5Click(TObject *Sender)
{
DensityHisto1();
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button6Click(TObject *Sender)
{
int *VertHist,*HorizHist;
AnsiString temp;
int VertHistHeight,HorizHistWidth,VertHistWidth,HorizHistHeight;
int i;
TIEFtImage *ftimage = new TIEFtImage;
ftimage = ImageEnProc1->FTCreateImage(ieitRGB,180,120);
ImageEnProc3->FTDisplayFrom(ftimage);
ftimage->Free();
VertHistWidth = ImageEnView9->ClientWidth;
VertHistHeight = ImageEnView5->Bitmap->Height;
HorizHistWidth =ImageEnView5->Bitmap->Width;
HorizHistHeight =ImageEnView8->ClientHeight;
VertHist = (int *)malloc(VertHistHeight*sizeof(int));
HorizHist = (int *) malloc(HorizHistWidth*sizeof(int));
ImageEnView5->Proc>CalcDensityHistogram(VertHist,HorizHist,VertHistWidth,HorizHistHeight);
ImageEnView9->Bitmap->Height =HorizHistHeight;
ImageEnView9->Bitmap->Width=HorizHistWidth;
// vertical
ImageEnView8->Bitmap->Height=VertHistHeight;
ImageEnView8->Bitmap->Width=VertHistWidth;
// draw histograms
ImageEnView9->Bitmap->Canvas->Pen->Color=clBlack;
ImageEnView8->Bitmap->Canvas->Pen->Color=clBlack;
for(i=0;i!=HorizHistWidth-1;i++) {
ImageEnView9->Bitmap->Canvas->MoveTo(i, HorizHistHeight );
ImageEnView9->Bitmap->Canvas->LineTo(i, HorizHistHeight - HorizHist[i] );
}
for(i=0;i!=VertHistHeight-1;i++) {
ImageEnView8->Bitmap->Canvas->MoveTo(0, i );
ImageEnView8->Bitmap->Canvas->LineTo(VertHist[i],i);
}
free(VertHist);
free(HorizHist);
ImageEnView8->Update();
ImageEnView9->Update();
}
//--------------------------------------------------------------------------void TForm1::DensityHisto2(void)
{
AnsiString temp;
int *VertHist,*HorizHist;
int VertHistHeight,HorizHistWidth,VertHistWidth,HorizHistHeight;
int i;
VertHistWidth = ImageEnView6->ClientWidth;
VertHistHeight = ImageEnView2->Bitmap->Height;
HorizHistWidth =ImageEnView2->Bitmap->Width;
HorizHistHeight =ImageEnView7->ClientHeight;
VertHist = (int *)malloc(VertHistHeight*sizeof(int));
HorizHist = (int *) malloc(HorizHistWidth*sizeof(int));
ImageEnView2->Proc>CalcDensityHistogram(VertHist,HorizHist,VertHistWidth,HorizHistHeight);
ImageEnView6->Bitmap->Height=HorizHistHeight;
ImageEnView6->Bitmap->Width=HorizHistWidth;
// vertical
ImageEnView7->Bitmap->Height=VertHistHeight;
ImageEnView7->Bitmap->Width=VertHistWidth;
// draw histograms
ImageEnView7->Bitmap->Canvas->Pen->Color=clBlack;
ImageEnView6->Bitmap->Canvas->Pen->Color=clBlack;
for(int u=0;u!=ListBox3->Items->Count;u++)
ListBox3->Items->Delete(u);
for(i=0;i!=HorizHistWidth-1;i++) {
temp.printf("%d",HorizHist[i]);
ListBox3->Items->Add(temp);
ImageEnView6->Bitmap->Canvas->MoveTo(i, HorizHistHeight );
ImageEnView6->Bitmap->Canvas->LineTo(i, HorizHistHeight - HorizHist[i] );
}
for(int u=0;u!=ListBox4->Items->Count;u++)
ListBox4->Items->Delete(u);
for(i=0;i!=VertHistHeight-1;i++) {
temp.printf("%d",VertHist[i]);
ListBox4->Items->Add(temp);
ImageEnView7->Bitmap->Canvas->MoveTo(0, i );
ImageEnView7->Bitmap->Canvas->LineTo(VertHist[i],i);
}
free(VertHist);
free(HorizHist);
ImageEnView6->Update();
ImageEnView7->Update();
}
void __fastcall TForm1::Button7Click(TObject *Sender)
{
DensityHisto2();
}
//---------------------------------------------------------------------------
{
int *VertHist,*HorizHist;
AnsiString temp;
int VertHistHeight,HorizHistWidth,VertHistWidth,HorizHistHeight;
int i;
TIEFtImage *ftimage = new TIEFtImage;
ftimage = ImageEnProc1->FTCreateImage(ieitRGB,180,120);
ImageEnProc2->FTDisplayFrom(ftimage);
ftimage->Free();
VertHistWidth = ImageEnView12->ClientWidth;
VertHistHeight = ImageEnView10->Bitmap->Height;
HorizHistWidth =ImageEnView10->Bitmap->Width;
HorizHistHeight =ImageEnView11->ClientHeight;
VertHist = (int *)malloc(VertHistHeight*sizeof(int));
HorizHist = (int *) malloc(HorizHistWidth*sizeof(int));
ImageEnView10->Proc>CalcDensityHistogram(VertHist,HorizHist,VertHistWidth,HorizHistHeight);
ImageEnView12->Bitmap->Height =HorizHistHeight;
ImageEnView12->Bitmap->Width=HorizHistWidth;
// vertical
ImageEnView11->Bitmap->Height=VertHistHeight;
ImageEnView11->Bitmap->Width=VertHistWidth;
// draw histograms
ImageEnView12->Bitmap->Canvas->Pen->Color=clBlack;
ImageEnView11->Bitmap->Canvas->Pen->Color=clBlack;
for(i=0;i!=HorizHistWidth-1;i++) {
ImageEnView12->Bitmap->Canvas->MoveTo(i, HorizHistHeight );
ImageEnView12->Bitmap->Canvas->LineTo(i, HorizHistHeight - HorizHist[i] );
}
for(i=0;i!=VertHistHeight-1;i++) {
ImageEnView11->Bitmap->Canvas->MoveTo(0, i );
ImageEnView11->Bitmap->Canvas->LineTo(VertHist[i],i);
}
free(VertHist);
free(HorizHist);
ImageEnView12->Update();
ImageEnView11->Update();
}
//---------------------------------------------------------------------------
:
:
:
:
minimum
minimum
minimum
minimum
and
and
and
and
maximum
maximum
maximum
maximum
peak
mean
root
peak
mae_min,mae_max
void
bool
void
OnFrame( BYTE* data, int width, int height, int format, int bpp );
Initialize(HWND parent );
Uninitialize();
void
void
void
void
void
void
ClearRect();
Start();
Stop();
VideoFormatDlg();
VideoSourceDlg();
UpdateParent( bool whole );
};
Andando
ad
analizzare
la
classe
generata dal wizard troviamo una serie
di funzioni che possiedono la specifica
CAP prima del nome della funzione.
Precedentemente
abbiamo
detto
che
OPENCV si basa sulle librerie directx
per alcuni tipi di gestioni e tra
queste esistono quelle legate alla
telecamera.
Originariamente in WINDOWS la gestione dei filmati veniva fatta
dal pacchetto VIDEO FOR WINDOWS.
Le funzioni utilizzate per la gestione della camera provengono da
questa.
Ad esempio linterrogazione del formato viene eseguita mediante il
metodo :
void
{
CCamera::VideoFormatDlg()
Allinterno
di
questo
viene
utilizzata
la
capGetVideoFormat.
La definizione delle funzioni cap quella che segue.
funzione
((BOOL)AVICapSM(hwnd,
(AVICapSM(hwnd,
#define capDriverConnect(hwnd, i)
((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_CONNECT, (WPARAM)(i), 0L))
#define capDriverDisconnect(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_DISCONNECT, (WPARAM)0, 0L))
#define capDriverGetName(hwnd, szName, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_NAME, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPTSTR)(szName)))
#define capDriverGetVersion(hwnd, szVer, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_VERSION, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPTSTR)(szVer)))
#define capDriverGetCaps(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_DRIVER_GET_CAPS, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPCAPDRIVERCAPS)(s)))
#define capFileSetCaptureFile(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SET_CAPTURE_FILE, 0, (LPARAM)
(LPVOID)(LPTSTR)(szName)))
#define capFileGetCaptureFile(hwnd, szName, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_GET_CAPTURE_FILE, (WPARAM)
(wSize), (LPARAM)(LPVOID)(LPTSTR)(szName)))
#define capFileAlloc(hwnd, dwSize)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_ALLOCATE, 0, (LPARAM)(DWORD)
(dwSize)))
#define capFileSaveAs(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SAVEAS, 0, (LPARAM)(LPVOID)
(LPTSTR)(szName)))
#define capFileSetInfoChunk(hwnd, lpInfoChunk)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SET_INFOCHUNK, (WPARAM)0,
(LPARAM)(LPCAPINFOCHUNK)(lpInfoChunk)))
#define capFileSaveDIB(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_FILE_SAVEDIB, 0, (LPARAM)(LPVOID)
(LPTSTR)(szName)))
#define capEditCopy(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_EDIT_COPY, 0, 0L))
#define capSetAudioFormat(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_AUDIOFORMAT, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPWAVEFORMATEX)(s)))
#define capGetAudioFormat(hwnd, s, wSize)
((DWORD)AVICapSM(hwnd, WM_CAP_GET_AUDIOFORMAT, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPWAVEFORMATEX)(s)))
#define capGetAudioFormatSize(hwnd)
((DWORD)AVICapSM(hwnd, WM_CAP_GET_AUDIOFORMAT, (WPARAM)0,
(LPARAM)0L))
#define capDlgVideoFormat(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0L))
#define capDlgVideoSource(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0L))
#define capDlgVideoDisplay(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEODISPLAY, 0, 0L))
#define capDlgVideoCompression(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0L))
#define capGetVideoFormat(hwnd, s, wSize)
((DWORD)AVICapSM(hwnd, WM_CAP_GET_VIDEOFORMAT, (WPARAM)(wSize),
(LPARAM)(LPVOID)(s)))
#define capGetVideoFormatSize(hwnd)
((DWORD)AVICapSM(hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0L))
#define capSetVideoFormat(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_VIDEOFORMAT, (WPARAM)(wSize),
(LPARAM)(LPVOID)(s)))
#define capPreview(hwnd, f)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_PREVIEW, (WPARAM)(BOOL)(f), 0L))
#define capPreviewRate(hwnd, wMS)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_PREVIEWRATE, (WPARAM)(wMS), 0))
#define capOverlay(hwnd, f)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_OVERLAY, (WPARAM)(BOOL)(f), 0L))
#define capPreviewScale(hwnd, f)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_SCALE, (WPARAM)(BOOL)f, 0L))
#define capGetStatus(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_GET_STATUS, (WPARAM)(wSize), (LPARAM)
(LPVOID)(LPCAPSTATUS)(s)))
#define capSetScrollPos(hwnd, lpP)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_SCROLL, (WPARAM)0, (LPARAM)
(LPPOINT)(lpP)))
#define capGrabFrame(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_GRAB_FRAME, (WPARAM)0, (LPARAM)0L))
#define capGrabFrameNoStop(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_GRAB_FRAME_NOSTOP, (WPARAM)0,
(LPARAM)0L))
#define capCaptureSequence(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_SEQUENCE, (WPARAM)0, (LPARAM)0L))
#define capCaptureSequenceNoFile(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_SEQUENCE_NOFILE, (WPARAM)0,
(LPARAM)0L))
#define capCaptureStop(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_STOP, (WPARAM)0, (LPARAM)0L))
#define capCaptureAbort(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_ABORT, (WPARAM)0, (LPARAM)0L))
#define capCaptureSingleFrameOpen(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME_OPEN, (WPARAM)0,
(LPARAM)0L))
#define capCaptureSingleFrameClose(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME_CLOSE, (WPARAM)0,
(LPARAM)0L))
#define capCaptureSingleFrame(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_SINGLE_FRAME, (WPARAM)0, (LPARAM)0L))
#define capCaptureGetSetup(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_GET_SEQUENCE_SETUP, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPCAPTUREPARMS)(s)))
#define capCaptureSetSetup(hwnd, s, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_SEQUENCE_SETUP, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPCAPTUREPARMS)(s)))
#define capSetMCIDeviceName(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_SET_MCI_DEVICE, 0, (LPARAM)(LPVOID)
(LPTSTR)(szName)))
#define capGetMCIDeviceName(hwnd, szName, wSize)
((BOOL)AVICapSM(hwnd, WM_CAP_GET_MCI_DEVICE, (WPARAM)(wSize),
(LPARAM)(LPVOID)(LPTSTR)(szName)))
#define capPaletteOpen(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_PAL_OPEN, 0, (LPARAM)(LPVOID)(LPTSTR)
(szName)))
#define capPaletteSave(hwnd, szName)
((BOOL)AVICapSM(hwnd, WM_CAP_PAL_SAVE, 0, (LPARAM)(LPVOID)(LPTSTR)
(szName)))
#define capPalettePaste(hwnd)
((BOOL)AVICapSM(hwnd, WM_CAP_PAL_PASTE, (WPARAM) 0, (LPARAM)0L))
#define capPaletteAuto(hwnd, iFrames, iColors)
((BOOL)AVICapSM(hwnd, WM_CAP_PAL_AUTOCREATE, (WPARAM)(iFrames),
(LPARAM)(DWORD)(iColors)))
#define capPaletteManual(hwnd, fGrab, iColors)
((BOOL)AVICapSM(hwnd, WM_CAP_PAL_MANUALCREATE, (WPARAM)(fGrab),
(LPARAM)(DWORD)(iColors)))
Mediante queste funzioni possibile inserire altre funzione per
lo svolgimento di determinate esigenze.
Il lavoro di preparazione.
Il lavoro di preparazione prevede diverse funzioni tra le quali
alcune legate alla correzione grafica dellimmagine acquisita ed
altre invece indirizzate alla calibrazione della telecamera.
Tale
funzionalit
viene
eseguita
per
trovare
i
parametri
intrinsechi ed estrinsechi della telecamera.
Tra i primi ci sono :
Lunghezza focale
Posizione del centro dellimmagine
Dimensione effettiva del pixel
Coefficiente della distorsione radiale delle lenti
I parametri estrinsechi invece sono :
La matrice di rotazione
Il vettore di traslazione
La fase di calibrazione necessaria per determinare alcuni
parametri che identificano la posizione della telecamera nel
mondo.
Alcuni di questi parametri sono dati direttamente dal produttore
della telecamera (come il numero di pixel del CCD, le dimensioni
dei pixel stessi, ), altri invece dipendono dalla sua posizione
(come la matrice di rototraslazione).
Per la determinazione di questi parametri in una fase iniziale
stato utilizzato lalgoritmo di Horn.
Questo algoritmo sebbene di facile implementazione ed utilizzo
(necessitava di soli 5 punti), non dava una precisione sufficiente
al nostro fine, cos abbiamo optato per un algoritmo pi complesso
ma maggiormente stabile e preciso: il metodo di Tsai.
Nel caso specifico le maggiori imprecisioni del metodo di Horn
erano dovute alla soluzione di un sistema non lineare mediante
lalgoritmo di Newton-Rapson.
Il metodo di Tsai invece si basa sulla scomposizione del sistema
non lineare in due sottosistemi dei quali uno lineare.
Un ulteriore vantaggio nellutilizzo di Tsai il calcolo della
distanza focale.
Lo svantaggio sta nel numero di punti minimo richiesto per la
calibrazione: almeno 11 per ogni telecamera.
La calibrazione della camera nella sua forma pi semplice viene
eseguita dalla funzione :
CalibrateCamera
Calibrates camera with single precision
void cvCalibrateCamera( int numImages, int* numPoints, CvSize
imageSize,CvPoint2D32f* imagePoints32f, CvPoint3D32f*
objectPoints32f, CvVect32f distortion32f, CvMatr32f
Linear
Transformation
Registrare
un
immagine
lequivalente di mappare un
punto delloggetto O presente
nello spazio di questo in un
punto dellimmagine l presente
nello spazio del film.
Nel
caso
di
digitazione
limmagine
registrata
viene
proiettata nuovamente in un
immagine
l
allinterno
del
piano di proiezione.
Per
semplicit
comqunue
possibile
relazionare
direttamente
limmagine
proiettata e loggetto.
srcImage
Source (distorted) image.
dstImage
Destination (corrected) image.
intrMatrix
Matrix of the camera intrinsic parameters (3x3).
distCoeffs
Vector of the four distortion coefficients k1, k2, p1 and p2.
interpolate
Bilinear interpolation flag.
che
sono
utilizzate
per
FindExtrinsicCameraParams
Finds extrinsic camera parameters for pattern
void cvFindExtrinsicCameraParams( int numPoints, CvSize imageSize,
CvPoint2D32f* imagePoints32f, CvPoint3D32f*
objectPoints32f,
CvVect32f focalLength32f, CvPoint2D32f
principalPoint32f,
CvVect32f distortion32f, CvVect32f rotVect32f,
CvVect32f transVect32f );
numPoints
Number of the points.
ImageSize
Size of the image.
imagePoints32f
Pointer to the image.
objectPoints32f
Pointer to the pattern.
focalLength32f
Focal length.
principalPoint32f
Principal point.
distortion32f
Distortion.
rotVect32f
Rotation vector.
transVect32f
Translate vector.
SEGMENTAZIONE
Non per tutte le immagini possibile con una sola soglia ricavare
le informazioni desiderate.
sola
soglia
separa
le
due
regioni
Relaxation
Effetto Rilievo: si basa su operatori di gradiente, opportunamente
modificati. Ai diversi livelli di luminosit si applica un
algoritmo che restituisce delle curve di livello.
Lutilizzo
della
segmentazione
di
fatto
semplifica
la
gestione
thresholdType=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold
0, otherwise
thresholdType=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold
src(x,y), otherwise
Approccio Statistico
Reti Neurali
complessa coniugata.
3. Eseguire la moltiplicazione pixel a
complessi)
4. Antitrasformare (con algoritmo InvFFT).
pixel
(tra
numeri
Nel caso
seguono :
di
TEMPLATE
DEFORMABILI
metodi
sono
quelli
che
Free-Form deformable:
il template non vincolato a forme precise (anche se generalmente
si impongono criteri di regolarit). Si fa uso di un potential
field, cio di una funzione di energia prodotta dalle feature
salienti
dellimmagine,
per
guidare
il
processo
verso
le
deformazioni maggiormente significative.
componenti esterne.
Analytic-Form based (Parametric deformable Parametric deformable):
si tratta di template parametrici (polilinee, archi, curve spline,
o combinazione dei precedenti) regolate da un numero limitato di
parametri agendo sui quali si ottengono deformazioni controllate.
quello
dellestrazione dei particolari.
Feature Extraction (estrazione delle caratteristiche)
Lapproccio statistico richiede il mapping di un pattern in uno
spazio multidimensionale.
Come gi detto, unimmagine pu essere considerata come un punto
multidimensionale, ma tale rappresentazione mal si presta alla
maggior parte dei problemi di riconoscimento (scarsa invarianza a
piccoli
cambiamenti
locali,
deformazioni,
prospettiva,
illuminazione, ...).
Con il termine feature extraction si intende in generale il
processo di estrazione di caratteristiche da unimmagine.
Il
pre-processing
dellimmagine
unelaborazione
iniziale
dellimmagine eseguita allo scopo di semplificare e rendere pi
efficace la successiva estrazione delle caratteristiche.
Si utilizzano tecniche di filtraggio per:
Istogramma
Listogramma di unimmagine digitale a livelli di grigio indica il
numero di pixel dellimmagine per ciascun livello di grigio:
Una delle parti del software da noi scritto ipotizza lsuo dei
classificatori la cui teoria, in linea di massima, quella che
segue.
Classificazione (approccio statistico)
Una volta estratte le feature dai pattern, la classificazione
cnsiste nellassociare ogni pattern a una o pi classi.
Approccio Bayesiano
Il problema posto in termini probabilistici.
Se tutte le le distribuzioni in gioco sono note lapproccio
byesiano costituisce la migliore regola di classificazione
possibile.
Notazione e definizioni di base
Per ogni
e per ogni
indichiamo con P(wi|x) la probabilit
probabilit a posteriori a posteriori di wi dato x, ovvero la
probabilit che avendo osservato il pattern x, la classe di
appartenenza sia wi. Per il teorema di Bayes:
passati.
Le altre funzioni utilizzate
definito nel file .h
possiedono
come
prototipo
quello
/*
* cvhaartraining.h
*
* haar training functions
*/
#ifndef _CVHAARTRAINING_H_
#define _CVHAARTRAINING_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* cvCreateTrainingSamples
*
* Create training samples applying random distortions to sample image and
* store them in .vec file
*
* filename
- .vec file name
* imgfilename
- sample image file name
* bgcolor
- background color for sample image
* bgthreshold
- background color threshold. Pixels those colors are in
range
*
[bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
* bgfilename
- background description file name. If not NULL samples
*
will be put on arbitrary background
* count
- desired number of samples
* invert
- if not 0 sample foreground pixels will be inverted
*
if invert == CV_RANDOM_INVERT then samples will be inverted randomly
* maxintensitydev - desired max intensity deviation of foreground samples
pixels
* maxxangle
- max rotation angles
* maxyangle
* maxzangle
* showsamples
- if not 0 samples will be shown
* winwidth
- desired samples width
* winheight
- desired samples height
*/
#define CV_RANDOM_INVERT 0x7FFFFFFF
void cvCreateTrainingSamples( const char* filename,
const char* imgfilename, int bgcolor, int
bgthreshold,
const char* bgfilename, int count,
int invert = 0, int maxintensitydev = 40,
double maxxangle = 1.1,
double maxyangle = 1.1,
double maxzangle = 0.5,
int showsamples = 0,
int winwidth = 24, int winheight = 24 );
void cvCreateTestSamples( const char* infoname,
const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
int showsamples,
int winwidth, int winheight );
/*
* cvCreateTrainingSamplesFromInfo
*
* Create training samples from a set of marked up images and store them into
.vec file
* infoname
- file in which marked up image descriptions are stored
* num
- desired number of samples
* showsamples - if not 0 samples will be shown
* winwidth
- sample width
* winheight
- sample height
*
* Return number of successfully created samples
*/
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char*
vecfilename,
int num,
int showsamples,
int winwidth, int winheight );
/*
* cvShowVecSamples
*
* Show samples stored in .vec file
* filename - .vec file name
* winwidth - sample width
* winheight - sample height
*/
void cvShowVecSamples( const char* filename, int winwidth, int winheight );
/*
* cvCreateCascadeClassifier
*
* Create cascade classifier
* dirname
- directory name in which cascade classifier will be
created.
*
It must exist and contain subdirectories 0, 1, 2, ... (nstages-1).
* vecfilename
- name of .vec file with object's images
* bgfilename
- name of background description file
* npos
- number of positive samples used in training of each stage
* nneg
- number of negative samples used in training of each stage
* nstages
- number of stages
* numprecalculated - number of features being precalculated. Each precalculated
feature
*
requires (number_of_samples*(sizeof( float ) + sizeof( short ))) bytes of
memory
* numsplits
- number of binary splits in each weak classifier
*
1 - stumps, 2 and more - trees.
* minhitrate
- desired min hit rate of each stage
* maxfalsealarm
- desired max false alarm of each stage
* weightfraction
- weight trimming parameter
* mode
- 0 - BASIC = Viola
*
1 - CORE = All upright
*
2 - ALL
= All features
* symmetric
- if not 0 vertical symmetry is assumed
* equalweights
- if not 0 initial weights of all samples will be equal
* winwidth
- sample width
* winheight
- sample height
* boosttype
- type of applied boosting algorithm
*
0 - Discrete AdaBoost
*
1 - Real AdaBoost
*
2 - LogitBoost
*
3 - Gentle AdaBoost
* stumperror
- type of used error if Discrete AdaBoost algorithm is
applied
*
0 - misclassification error
*
1 - gini error
*
2 - entropy error
*/
void cvCreateCascadeClassifier( const char* dirname,
const char* vecfilename,
const char* bgfilename,
int npos, int nneg, int nstages,
int numprecalculated,
int numsplits,
float minhitrate = 0.995F, float maxfalsealarm =
0.5F,
float weightfraction = 0.95F,
int mode = 0, int symmetric = 1,
int equalweights = 1,
int winwidth = 24, int winheight = 24,
int boosttype = 3, int stumperror = 0 );
#ifdef __cplusplus
}
#endif /* extern "C" */
#endif /* _CVHAARTRAINING_H_ */
Una volta creata la struttura mediante le funzioni di training il software la
utilizzer per identificare in quale momento in una certa sequenza di immagini
provenienti dalla telecamera presente un immagine retinale.
Il programma deve identificare tale immagine e dopo averla inserita in un
rettangolo di cut tagliarla per creare limmagine finale che verr utilizzata
per la fase di identificazione.
Nella funzione main viene richiamata la funzione
InitRetinaDetect(classifierbase)
la quale ha lo scopo di inizializzare la cascata di CLASSIFICATORI HAAR.
const int root_w = 400, root_h = 400;
int main( int argc, char **argv )
{
const char* facebaseopt="--facebase=";
char* classifierbase = 0;
char* aviname = 0;
int auto_run = 0;
if( argc > 1 && argv[argc-1][0] != '-' )
{
aviname = argv[argc-1];
auto_run = 1;
argc--;
}
if( argc > 1 && strncmp(argv[argc-1],facebaseopt,strlen(facebaseopt))==0 )
{
classifierbase=argv[argc-1] + strlen(facebaseopt);
argc--;
}
if( !InitRetinaDetect(classifierbase))
{
fprintf( stderr, "Could not locate face classifier base at %s\n"
"Use --facebase=<classifier base path> option to
specify the base\n",
classifierbase );
return -1;
}
cpu_freq = cvGetTickFrequency();
printf("Tick frequency (*10^-6): %g\n", cpu_freq );
Fl_Window* w;
{
Fl_Window* o = root_window = new Fl_Window( root_w, root_h );
w = o;
{
Fl_Tabs* o = new Fl_Tabs( 10, 10, root_w - 20, root_h - 100 );
// camera tab
{
Fl_Group* o = new Fl_Group( 10, 30, root_w - 20, root_h - 110,
"Face Detection" );
{
VideoWindow* o = new VideoWindow( 15, 35, root_w - 30,
root_h - 120 );
video_window = o;
o->box( FL_BORDER_BOX );
o->color(0);
}
o->end();
}
o->end();
Fl_Group::current()->resizable(o);
}
{
const int bwidth = 30, bheight = 30;
play_button = new Fl_Button( 10, root_h - 35, bwidth, bheight,
"@>" );
play_button->callback((Fl_Callback*)cb_PauseResume);
play_button->deactivate();
stop_button = new Fl_Button( 10 + bwidth, root_h - 35, bwidth,
bheight, "@square" );
stop_button->callback((Fl_Callback*)cb_Stop);
stop_button->deactivate();
video_button = new Fl_Button( 10 + bwidth*2, root_h - 35, bwidth,
bheight, "..." );
video_button->callback((Fl_Callback*)cb_Open);
cam_button = new Fl_Button( 10 + bwidth*3, root_h - 35, bwidth,
bheight, "[o]" );
cam_button->callback((Fl_Callback*)cb_StartCam);
video_pos = new Fl_Value_Slider( 10 + bwidth*4 + 10, root_h - 35,
200, 20, "Position" );
video_pos->type( FL_HOR_NICE_SLIDER );
record_button = new Fl_Button( 10 + bwidth*4 + 230, root_h - 35,
bwidth, bheight, "@circle" );
record_button->labelcolor(FL_RED);
record_button->callback((Fl_Callback*)cb_StartStopRecord );
record_button->deactivate();
fps_box = new Fl_Box( 10, root_h - 75, bwidth*4, bheight, "<No
data>" );
fps_box->box( FL_DOWN_BOX );
}
o->end();
}
Fl::visual(FL_RGB);
w->show(argc, argv);
if( auto_run )
Fl::add_timeout( 0.1, cb_AutoRun, aviname );
Fl::run();
cb_Exit(0,0);
return 0;
Come dicevamo
precedentemente il sistema
utilizza la trasformata di
GABOR e la trasformata
WAVELET per lanalisi delle
informazioni relative ad una
generica retina.
OpenCV utilizza le HAAR
WAVELET.
La precednte figura mostra
la funzione Harr Wavelet.
Limmagine successiva invece
mostra il procedimento
concettuale per ottenere il vettore delle di dimansioni
ottimizzate.
In questo H ed L indicano il filtre passa alto e quello passa
basso mentre HH indica il filtro passa alto utilizzato su ambedue
gli assi X e Y.
Limmagine a fianco si riferisce ad un immagine di esempio di
450x60.
Ciascuna delle 87
dimensioni possiedono un
valore reale compreso tra
-1 e 1.
Per ridurre lo spazio e il
tempo computazionale
necessario per la
manipolazione il valore
viene quantizzato in m,odo
molto semplice convertendo
il valore positivo in 1 e
quello negativo in 0.
In questo modo un immagine
di 450x60 pu essere
rappresentata in 87 bits.
I valori relativi alle
dimensioni dellimmagine
sono soltanto teoricizzati
in modalit puramente casuale in quanto la loro determinazione
precisa dovr essere eseguita mediante prove eseguite realmente.
Matematicamente la funzione di HAAR SCALING definita come segue:
Supponiamo che
sia definita da
Definiamo
come
dove
La costante
support_start = ceil(1000*i/2^j)+1;
support_end = floor(1000*(1+i)/2^j);
for k=1000+support_start:1000+support_end
y(k) = 1;
end
norm_factor = sqrt(2^j);
y = norm_factor*y;
Supponiamo
sia definita da
Definiamo
come
dove
La costante
scelta
support_start = ceil(1000*i/2^j)+1;
support_middle = floor(1000*(0.5+i)/2^j);
support_end = floor(1000*(1+i)/2^j);
for k=1000+support_start:1000+support_middle
y(k) = 1;
end
for k=1001+support_middle:1001+support_end
y(k) = -1;
end
norm_factor = sqrt(2^j);
y = norm_factor*y;
a leaf)
right[i] - index of the right child (or negated index if the right child
is a leaf)
threshold[i] - branch threshold. if feature responce is <= threshold,
left branch
is chosen, otherwise right branch is chosed.
alpha[i] - output value correponding to the leaf. */
float* threshold; /* array of decision thresholds */
int* left; /* array of left-branch indices */
int* right; /* array of right-branch indices */
float* alpha; /* array of output values */
}
CvHaarClassifier;
/* a boosted battery of classifiers(=stage classifier):
the stage classifier returns 1
if the sum of the classifiers' responces
is greater than threshold and 0 otherwise */
2
8 18 9 6 0 -1
8 20 9 2 0 3
haar_y3
0.005753 0 -1
-0.874639 1.176034
1
2
3 5 4 19 0 -1
5 5 2 19 0 2
haar_x2
0.015014 0 -1
-0.779457 1.260842
1
2
6 5 12 16 0 -1
6 13 12 8 0 2
haar_y2
0.099371 0 -1
0.557513 -1.874300
1
2
5 8 12 6 0 -1
5 11 12 3 0 2
haar_y2
0.002734 0 -1
-1.691193 0.440097
1
2
11 14 4 10 0 -1
11 19 4 5 0 2
haar_y2
-0.018859 0 -1
-1.476954 0.443501
1
2
4 0 7 6 0 -1
4 3 7 3 0 2
haar_y2
0.005974 0 -1
-0.859092 0.852556
-5.042550
letti.
/* hidden (optimized) representation of Haar classifier cascade */
typedef struct CvHidHaarClassifierCascade
CvHidHaarClassifierCascade;
CvHidHaarClassifierCascade*
cvCreateHidHaarClassifierCascade( CvHaarClassifierCascade*
cascade,
const CvArr* sumImage=0,
const CvArr* sqSumImage=0,
const CvArr* tiltedSumImage=0,
double scale=1 );
cascade
original cascade that may be loaded from file using
cvLoadHaarClassifierCascade.
sumImage
Integral (sum) single-channel image of 32-bit integer format.
This image as well as the two subsequent images are used for
fast feature evaluation and brightness/contrast
normalization. They all can be retrieved from the input 8-bit
single-channel image using function cvIntegral. Note that all
the images are 1 pixel wider and 1 pixel taller than the
source 8-bit image.
sqSumImage
Square sum single-channel image of 64-bit floating-point
format.
tiltedSumImage
Tilted sum single-channel image of 32-bit integer format.
scale
Initial scale (see cvSetImagesForHaarClassifierCascade).
In altre parole la funzione converte i parametri letti mediante la
funzione precedente in un formato interno pi veloce.
Una volta creata questa catena e assegnato lhandle alla variabile
di rappresentazione nel programma la cascata viene rilasciata.
cvReleaseHaarClassifierCascade( &cascade );
Sempre allinterno del MAIN il programma continua a richiamare la
funzione GetNextFrame dentro alla quale esiste il richiamo della
funzione alla quale demandata la funzionalit di individuare se
dentro allimmagine corrente giunta dalla telecamera esiste una
retina.
Questa funzione ha il compito di tracciare un rettangolo intorno a
questa.
void DetectAndDrawRetina( IplImage* img )
{
if( hid_cascade && img )
{
int scale = 2;
cvReleaseImage( &temp );
NEGATIVE
Il SISTEMA DI IDENTIFICAZIONE.
Tutto il sistema di identificazione basato sui modelli di Markov
nascosti implementati allinetrno della libreria OpenCV.
Le funzioni utilizzate per la gestione pretendono una serie di
parametri i quali sono i valori classici utilizzati nei sistemi
HIDDEN MARKOV MODELL.
}
fprintf(file, "\n");
fprintf(file, "\n");
fprintf(file, "%s\n", "<Inverted_Deviation>");
for (k = 0; k < m_vectSize; k++)
{
fprintf(file, "%f ", inv_var[0]);
inv_var++;
}
fprintf(file, "\n");
fprintf(file, "%s %f\n", "<LogVarVal>", state>log_var_val[m] );
}
}
}
fscanf(file, "\n");
//compute total number of internal states
int total_states = 0;
for( i = 0; i < num_states[0]; i++ )
{
total_states += num_states[i+1];
}
//read number of mixtures
fscanf(file, "%s ", temp_char);
for( i = 0; i < total_states; i++ )
{
fscanf(file, "%d ", &num_mix[i] );
}
fscanf(file, "\n");
fscanf(file, "%s %d\n", temp_char, &m_vectSize);
m_hmm = cvCreate2DHMM( num_states, num_mix, m_vectSize);
//create HMM with known parameters
//!!!
cvCreate2DHMM( &m_hmm, num_states, num_mix, m_vectSize);
if (!m_hmm ) return false;
//consequently read all hmms
CvEHMM* hmm = m_hmm;
for( i = 0; i < num_states[0]+1; i++ )
{
fscanf(file, "%s\n", temp_char);
int temp_int;
fscanf(file, "%s %d\n", temp_char , &temp_int);
assert(temp_int==num_states[i]);
if ( i!= 0 )
{
for (int j = 0; j < num_states[i]; j++)
{
CvEHMMState* state = &(hmm->u.state[j]);
fscanf(file, "%s %d\n", temp_char, &temp_int); assert(temp_int
== j);
fscanf(file, "%s %d\n", temp_char, &temp_int); assert(temp_int
== state->num_mix);
float* mu = state->mu;
float* inv_var = state->inv_var;
for( int m = 0; m < state->num_mix; m++)
{
int temp_int;
fscanf(file, "%s %d %s %f\n", temp_char, &temp_int,
temp_char, &(state->weight[m]) );
assert( temp_int == m );
fscanf(file, "%s\n", temp_char );
for (int k = 0; k < m_vectSize; k++)
{
fscanf(file, "%f ", mu);
mu++;
}
fscanf(file, "\n");
fscanf(file, "%s\n", temp_char);
for (k = 0; k < m_vectSize; k++)
{
fscanf(file, "%f ", inv_var);
inv_var++;
}
fscanf(file, "\n");
>log_var_val[m]) );
}
}
hmm = &(m_hmm->u.ehmm[i]);
}
fclose(file);
return true;
3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
-10000000000.000000
-0.133531 -2.079442
-10000000000.000000
-10000000000.000000
-10000000000.000000
-10000000000.000000
-10000000000.000000
-0.133531 -2.079442
-10000000000.000000
-10000000000.000000
-10000000000.000000
-10000000000.000000
-10000000000.000000
-0.051293 -2.995732
-10000000000.000000
<Mean>
136.449188 15.072393 21.410343 0.304627 1.185207 1.440380 -1.137706 -0.825282
<Inverted_Deviation>
0.013488 0.012942 0.013954 0.020873 0.033767 0.026371 0.035187 0.069733
<LogVarVal> 34.407440
<State> 3
<NumMixes> 3
<Mixture> 0 <Weight> 0.348624
<Mean>
19.712467 3.993253 30.475801 13.512649 -4.126996 22.256044 -4.251338 -3.650669
<Inverted_Deviation>
0.023656 0.022237 0.016146 0.014870 0.050358 0.015594 0.036664 0.064872
<LogVarVal> 33.654343
<Mixture> 1 <Weight> 0.165138
<Mean>
128.506607 -7.856478 77.194824 -8.695423 -13.027184 -15.868305 -14.322035
4.716886
<Inverted_Deviation>
0.009385 0.022030 0.017512 0.022014 0.039319 0.040382 0.041146 0.070711
<LogVarVal> 33.208969
<Mixture> 2 <Weight> 0.486239
<Mean>
-41.485161 -2.108405 -60.229691 -0.742463 8.568585 2.393284 12.158751 1.010459
<Inverted_Deviation>
0.017285 0.032958 0.016136 0.020023 0.040785 0.023420 0.035068 0.060603
<LogVarVal> 33.194424
<State> 4
<NumMixes> 3
<Mixture> 0 <Weight> 0.901587
<Mean>
20.881762 -1.768637 -6.697111 -1.355091 -0.253182 -4.685781 -0.407999 -0.137556
<Inverted_Deviation>
0.027539 0.044917 0.022056 0.041149 0.070711 0.047551 0.070711 0.070711
<LogVarVal> 29.272205
<Mixture> 1 <Weight> 0.041270
<Mean>
200.368622 11.540556 45.782974 3.420283 -18.899872 4.935305 -8.701583 0.798857
<Inverted_Deviation>
0.012718 0.011904 0.028538 0.014262 0.033927 0.065217 0.070711 0.070711
<LogVarVal> 32.593105
<Mixture> 2 <Weight> 0.057143
<Mean>
-102.914154 2.887007 -68.612213 6.443975 14.543627 1.761935 9.705220 0.981170
<Inverted_Deviation>
0.015346 0.015776 0.024968 0.020148 0.044144 0.039683 0.060597 0.070711
<LogVarVal> 32.299801
<State> 5
<NumMixes> 3
<Mixture> 0 <Weight> 0.238411
<Mean>
215.408157 -2.994002 -67.357452 10.044118 17.727612 -3.746516 -5.952805 1.734724
<Inverted_Deviation>
0.011668 0.011538 0.018723 0.013939 0.020979 0.049652 0.048738 0.044163
<LogVarVal> 34.751118
<Mixture> 1 <Weight> 0.509934
<Mean>
-24.402103 17.768127 2.630338 -5.581841 0.374965 0.299918 0.793470 0.396344
<Inverted_Deviation>
0.009372 0.015522 0.061483 0.069743 0.070711 0.070711 0.070711 0.070711
<LogVarVal> 29.463020
<Mixture> 2 <Weight> 0.251656
<Mean>
<Mean>
193.838730 -0.841311 -19.025002 -1.742880 2.352849 -0.728297 -8.807205 1.636138
<Inverted_Deviation>
0.016424 0.012148 0.010296 0.017934 0.026932 0.027708 0.038896 0.040834
<LogVarVal> 35.341076
<Mixture> 1 <Weight> 0.613139
<Mean>
12.877467 3.272102 2.626410 -0.844084 -1.496272 1.243824 2.790946 0.615524
<Inverted_Deviation>
0.034123 0.047279 0.047078 0.044948 0.070711 0.070711 0.070711 0.070711
<LogVarVal> 27.763226
<Mixture> 2 <Weight> 0.138686
<Mean>
105.450005 6.511856 55.032810 4.647384 2.288129 -3.770526 1.748496 -4.205755
<Inverted_Deviation>
0.024094 0.016110 0.013488 0.014875 0.029750 0.029896 0.032855 0.048521
<LogVarVal> 34.413460
<TransP>
-0.057778 -2.879900 -10000000000.000000 -10000000000.000000 -10000000000.000000
-10000000000.000000
-10000000000.000000 -0.078472 -2.583997 -10000000000.000000 -10000000000.000000
-10000000000.000000
-10000000000.000000 -10000000000.000000 -0.089445 -2.458520 -10000000000.000000
-10000000000.000000
-10000000000.000000 -10000000000.000000 -10000000000.000000 -0.098846 -2.363210
-10000000000.000000
-10000000000.000000 -10000000000.000000 -10000000000.000000 -10000000000.000000
-0.064279 -2.776487
-10000000000.000000 -10000000000.000000 -10000000000.000000 -10000000000.000000
-10000000000.000000 0.000000
<EndEmbeddedHMM>
<BeginEmbeddedHMM>
<NumStates> 6
<State> 0
<NumMixes> 3
<Mixture> 0 <Weight> 0.079399
<Mean>
281.515320 5.062520 23.383995 -6.769423 -1.797396 -2.218050 -1.719421 0.938018
<Inverted_Deviation>
0.007033 0.005905 0.028191 0.037544 0.044815 0.068372 0.070711 0.070711
<LogVarVal> 32.605255
<Mixture> 1 <Weight> 0.831545
<Mean>
-9.736834 -1.911342 9.898236 0.245111 1.282359 -2.437490 -0.494635 -0.159903
<Inverted_Deviation>
0.016225 0.026268 0.026959 0.042149 0.070711 0.058875 0.070711 0.070711
<LogVarVal> 29.899328
<Mixture> 2 <Weight> 0.089056
<Mean>
-234.735886 2.390812 75.920830 5.356786 -11.480034 -6.676812 9.000673 0.603900
<Inverted_Deviation>
0.010240 0.011519 0.007933 0.010402 0.017930 0.036167 0.031687 0.033247
<LogVarVal> 37.223103
<State> 1
<NumMixes> 3
<Mixture> 0 <Weight> 0.068063
<Mean>
73.068626 4.208974 -108.522934 34.903324 7.557928 -18.668013 -4.114515 0.012024
<Inverted_Deviation>
0.006929 0.016683 0.015159 0.028884 0.037623 0.026465 0.039746 0.070711
<LogVarVal> 34.164383
<Mixture> 1 <Weight> 0.518325
<Mean>
-38.629051 5.369726 29.472923 7.114058 -0.945012 -12.123492 3.357934 -0.145340
<Inverted_Deviation>
0.009075 0.030282 0.013002 0.029454 0.065644 0.030550 0.070711 0.070711
<LogVarVal> 32.156143
<Mixture> 2 <Weight> 0.413613
<Mean>
134.908218 0.393828 113.515602 2.343509 -4.886399 -12.961477 -4.844072 -0.264280
<Inverted_Deviation>
0.007246 0.014630 0.011153 0.015511 0.031214 0.021559 0.046464 0.070711
<LogVarVal> 35.415352
<State> 2
<NumMixes> 3
<Mixture> 0 <Weight> 0.415414
<Mean>
-46.442204 2.625515 -39.037647 0.741800 0.109419 20.635923 1.452390 -0.398463
<Inverted_Deviation>
0.007425 0.019306 0.015365 0.019814 0.060124 0.012820 0.064612 0.070711
<LogVarVal> 34.082813
<Mixture> 1 <Weight> 0.204887
<Mean>
-25.423428 -1.808578 216.439011 -3.891537 -3.458281 27.054890 7.209569 -0.137808
<Inverted_Deviation>
0.015531 0.043220 0.010858 0.020908 0.060988 0.012498 0.039046 0.070711
<LogVarVal> 33.347191
<Mixture> 2 <Weight> 0.379699
<Mean>
28.790150 -4.355493 -174.831299 0.902964 3.188112 -11.479298 -6.226968 0.909172
<Inverted_Deviation>
0.010894 0.025712 0.012667 0.025213 0.062370 0.014423 0.047051 0.070711
<LogVarVal> 33.527699
<State> 3
<NumMixes> 3
<Mixture> 0 <Weight> 0.304348
<Mean>
86.820747 5.144733 -100.133652 -20.788786 13.970844 -1.287977 -22.528519
-0.661565
<Inverted_Deviation>
0.014922 0.025611 0.009903 0.013569 0.032377 0.014940 0.024406 0.039824
<LogVarVal> 35.933765
<Mixture> 1 <Weight> 0.462451
<Mean>
-37.885178 5.131439 33.009090 -11.834466 -1.668376 11.706657 8.278119 -1.887173
<Inverted_Deviation>
0.009802 0.020549 0.017517 0.012941 0.033183 0.015504 0.029852 0.047472
<LogVarVal> 35.612408
<Mixture> 2 <Weight> 0.233202
<Mean>
-55.076748 -2.452983 151.571808 3.877711 -13.306914 -3.478388 14.378208 2.829310
<Inverted_Deviation>
0.008172 0.019092 0.015081 0.013413 0.026307 0.017964 0.027104 0.051203
<LogVarVal> 36.087620
<State> 4
<NumMixes> 3
<Mixture> 0 <Weight> 0.529158
<Mean>
1.878654 -0.733471 33.537338 1.262277 -0.333027 7.590052 -0.060252 -1.090263
<Inverted_Deviation>
0.023968 0.055641 0.018797 0.023763 0.070711 0.017156 0.051693 0.070711
<LogVarVal> 31.238581
<Mixture> 1 <Weight> 0.276458
<Mean>
return true;
//else return false;
}
08.34
08.32
08.32
08.32
09.39
08.32
09.35
09.27
20.22
08.08
08.15
08.12
15.57
12.44
12.50
23.39
23.29
21.36
10.25
20.40
09.38
18.56
9.517
899
1.503
597
8.466
1.631
8.871
1.638
5.181
1.045
5.805
1.238
43
723
386
3.180
802
13.874
117.760
919
4.635
1.007
EHMM.cpp
EHMM.h
EHMMObj.cpp
EHMMObj.h
EHMMObjDatabase.cpp
EHMMObjDatabase.h
EHMMObjRecognition.cpp
EHMMObjRecognition.h
ImgObj.cpp
ImgObj.h
ImgObjDatabase.cpp
ImgObjDatabase.h
lista.txt
Obj.cpp
Obj.h
RecognizeEHMM.cpp
RecognizeEHMM.h
RetinaRecognition.cpp
RetinaRecognition.ncb
RetinaRecognition.sln
RetinaRecognition.vcproj
Utils.cpp
27/09/2003
18.57
504 Utils.h
Il cuore in cui sono gestiti gli HMM descritto nei files che
possiedono EHMM nella parte iniziale.
E sta per EMBEDDED.
Il primo gruppo di files contiene le funzioni adatte alla lettura
e al salvataggio dei parametri visti nelle pagine precedenti.
#ifndef _EHMM_H_
#define _EHMM_H_
//Disable OpenCv type cast warning
#pragma warning( disable : 4312 )
#include <string>
#include "cv.h"
#include "ipl.h"
#pragma warning( default : 4312 )
class EHMM
{
public:
EHMM( );
virtual ~EHMM( );
void Create( int *noStates, int *noMix, int vecSize );
void Load( const std::string &fileName );
void Save( const std::string &fileName );
void Release( );
bool GetTrained( );
void SetTrained( bool trained );
void GetNoStates( int *noStates ) const;
void GetNoMix( int *noMix ) const;
int GetVecSize( ) const;
CvEHMM* GetCvEHMM( );
private:
//Hidden markov model
CvEHMM* _ehmm;
//Size of the vector that is used as input
int _vecSize;
};
#endif //_EHMM_H
#include "EHMM.h"
#include <stdio.h>
//*****************************************************************************
EHMM::EHMM( )
{
_ehmm = 0;
_vecSize = 0;
_trained = false;
}
//*****************************************************************************
EHMM::~EHMM( )
{
Release( );
}
//*****************************************************************************
void EHMM::Release( )
{
if ( _ehmm )
{
cvRelease2DHMM( &_ehmm );
}
_vecSize = 0;
_trained = false;
//*****************************************************************************
void EHMM::Create( int *noStates, int *noMix, int vecSize )
{
assert( _ehmm == 0 );
_ehmm = cvCreate2DHMM( noStates, noMix, vecSize );
assert( _ehmm != 0 );
_vecSize = vecSize;
_trained = false;
}
//*****************************************************************************
void EHMM::Load( const std::string &fileName )
{
const int MAX_STATES = 128;
FILE *file;
int states[ MAX_STATES ];
int gaussMix[ MAX_STATES ];
char tmpChar[ MAX_STATES ];
assert( _ehmm == 0 );
}
fclose( file );
_trained = true;
}
//*****************************************************************************
void EHMM::Save( const std::string &fileName )
{
FILE* file;
int i;
int j;
int m;
int k;
assert( _ehmm != 0 );
file = fopen( fileName.c_str( ), "wt" );
assert( file != 0 );
//Write topology
fprintf( file, "%s %d\n", "<NumSuperStates>", _ehmm->num_states );
fprintf( file, "%s ", "<NumStates>" );
for( i = 0; i < _ehmm->num_states; i++ )
{
fprintf( file, "%d ", _ehmm->u.ehmm[ i ].num_states );
}
fprintf( file, "\n" );
fprintf( file, "%s ", "<NumMixtures>" );
for( i = 0; i < _ehmm->num_states; i++ )
{
}
fprintf( file, "\n" );
{
fprintf( file, "%s\n", "<BeginExternalHMM>" );
}
fprintf( file, "%s %d\n", "<NumStates>", hmm->num_states );
if ( hmm->level == 0 )
{
for ( j = 0; j < hmm->num_states; j++)
{
CvEHMMState* state = &( hmm->u.state[ j ] );
fprintf( file, "%s %d\n", "<State>", j );
fprintf( file, "%s %d\n", "<NumMixes>", state->num_mix );
float* mu = state->mu;
float* inv_var = state->inv_var;
for( m = 0; m < state->num_mix; m++)
{
fprintf( file, "%s %d %s %f\n", "<Mixture>", m, "<Weight>",
state->weight[ m ] );
fprintf( file, "%s\n", "<Mean>" );
for ( k = 0; k < _vecSize; k++)
{
fprintf( file, "%f ", mu[ 0 ] );
mu++;
}
fprintf( file, "\n" );
fprintf( file, "%s\n", "<Inverted_Deviation>" );
for ( k = 0; k < _vecSize; k++)
{
fprintf( file, "%f ", inv_var[ 0 ] );
inv_var++;
}
fprintf( file, "\n" );
fprintf( file, "%s %f\n", "<LogVarVal>", state->log_var_val[
m ] );
}
}
}
if( hmm->level == 0 )
{
fprintf( file, "%s\n", "<EndEmbeddedHMM>" );
}
else
{
fprintf( file, "%s\n", "<EndExternalHMM>" );
}
}
fclose( file );
}
//*****************************************************************************
bool EHMM::GetTrained( )
{
assert( _ehmm != 0 );
}
return _trained;
//*****************************************************************************
void EHMM::SetTrained( bool trained )
{
assert( _ehmm != 0 );
_trained = trained;
}
//*****************************************************************************
/*
*
Fill in the noStates vector with the number of states
*/
void EHMM::GetNoStates( int *noStates ) const
{
int i;
assert( _ehmm != 0 );
noStates[ 0 ] = _ehmm->num_states;
//*****************************************************************************
/*
*
Fill in the noMix vector with the number of mixtures per state
*/
void EHMM::GetNoMix( int *noMix ) const
{
int i;
int j;
int c;
assert( _ehmm != 0 );
{
//*****************************************************************************
int EHMM::GetVecSize( ) const
{
assert( _ehmm != 0 );
return _vecSize;
}
//*****************************************************************************
CvEHMM* EHMM::GetCvEHMM( )
{
assert( _ehmm != 0 );
}
return _ehmm;
#ifndef _EHMMObj_H_
#define _EHMMObj_H_
#include "Obj.h"
#include "EHMM.h"
class EHMMObj : public Obj
{
public:
EHMMObj( );
virtual ~EHMMObj( );
void Create( const std::string &userName, int *noStates, int *noMix, int
vecSize );
void Load( const std::string &userName, const std::string &path );
};
#endif //_EHMMObj_H_
#include "EHMMObj.h"
using std::string;
//Standard extension to the user file
static const string EXTENSION = ".ehmm";
//*****************************************************************************
EHMMObj::EHMMObj( )
{
}
//*****************************************************************************
EHMMObj::~EHMMObj( )
{
}
//*****************************************************************************
void EHMMObj::Create( const string &userName, int *noStates,
int *noMix, int vecSize )
{
assert( _name == "" );
Obj::Create( userName );
//*****************************************************************************
void EHMMObj::Load( const string &userName, const string &path )
{
const string EHMM_FILE = path + userName + EXTENSION;
assert( _name == "" );
Obj::Create( userName );
//****************************************************************
void EHMMObj::Save( const string &path )
{
//****************************************************************
EHMM& EHMMObj::GetEHMM( )
{
return _ehmm;
}
//****************************************************************
#ifndef _EHMMObjDatabase_H_
#define _EHMMObjDatabase_H_
#include "EHMMObj.h"
#include <vector>
#include <iostream>
//Exception specification warning
#pragma warning( disable : 4290 )
class EHMMObjDatabase
{
private:
enum{ MAX_STATES = 128 };
public:
EHMMObjDatabase( );
virtual ~EHMMObjDatabase( );
void Create( const std::string &databaseName, int *noStates,
int *noMix, int vecSize );
void Load( const std::string &databaseName, const std::string &path );
void Save( const std::string &path );
void Release( );
void LoadObj( const std::string &userName, const std::string &path );
void AddObj( const std::string &userName );
};
"EHMMObjDatabase.h"
<fstream>
<iostream>
<assert.h>
std::vector;
std::ifstream;
std::ofstream;
std::iostream;
std::ostream;
std::string;
std::cout;
std::endl;
std::cerr;
//*****************************************************************************
EHMMObjDatabase::EHMMObjDatabase( )
{
_databaseName = "";
memset( _numStates, 0, sizeof( _numStates ) );
memset( _numMix, 0, sizeof( _numMix ) );
_vecSize = 0;
}
//*****************************************************************************
EHMMObjDatabase::~EHMMObjDatabase( )
{
Release( );
}
//*****************************************************************************
/*
*
Create an empty data base
*/
void EHMMObjDatabase::Create( const string &databaseName, int *noStates,
int *noMix, int vecSize )
{
int i;
int totalNoInternalStates;
assert(
assert(
assert(
assert(
noStates != 0 );
noMix != 0 );
vecSize != 0 );
databaseName != "" );
_databaseName = databaseName;
_objs.reserve( INITIAL_SIZE );
while ( file.getline( line, sizeof( line ) ) )
{
_objs.push_back( new EHMMObj( ) );
try
{
}
}
//Save the ehmm creation parameters
if ( _objs.size( ) == 0 )
{
cerr << "Database is emtpy. Please use 'Create' before "
"adding new users" << endl;
}
else
{
_objs[ 0 ]->GetEHMM( ).GetNoStates( _numStates );
_objs[ 0 ]->GetEHMM( ).GetNoMix( _numMix );
_vecSize = _objs[ 0 ]->GetEHMM( ).GetVecSize( );
}
//Check to see if the db is consistent
for ( objsIt = _objs.begin( ); objsIt < _objs.end( ); objsIt++ )
{
CheckEHMMConsistence( *(*objsIt) );
}
}
//*****************************************************************************
/*
*
Save the database to disk. It will overwrite the previous data
*/
void EHMMObjDatabase::Save( const string &path )
{
const string DATABASE_PATH = path + _databaseName;
vector< EHMMObj* >::iterator objsIt;
ofstream file( DATABASE_PATH.c_str( ) );
assert( _databaseName != "" );
assert( file.is_open( ) );
}
//*****************************************************************************
/*
*
*/
//*****************************************************************************
/*
*
Remove the first occurance of an object from the database by name
*/
void EHMMObjDatabase::RemoveObj( const string &userName )
{
const string EXCEPTION_STR = "EHMMObjDatabase::RemoveObj: " + userName + "
not found.";
vector< EHMMObj* >::iterator objsIt;
assert( _databaseName != "" );
for ( objsIt = _objs.begin( ); objsIt < _objs.end( ); objsIt++ )
{
if ( (*objsIt)->GetName( ) == userName )
{
_objs.erase( objsIt );
return;
}
*
If more than one object has the same name the first object is returned
*/
EHMMObj& EHMMObjDatabase::GetObj( const string &userName )
{
const string EXCEPTION_STR = "EHMMObjDatabase::GetObj: " + userName + "
not found.";
vector< EHMMObj* >::iterator objsIt;
assert( _databaseName != "" );
for ( objsIt = _objs.begin( ); objsIt < _objs.end( ); objsIt++ )
{
if ( (*objsIt)->GetName( ) == userName )
{
return *(*objsIt);
}
}
}
//*****************************************************************************
size_t EHMMObjDatabase::GetNoObjs( ) const
{
assert( _databaseName != "" );
return _objs.size( );
}
//*****************************************************************************
/*
*
Check that the new loaded object has the same parameters
*
for his ehmm as the database
*/
void EHMMObjDatabase::CheckEHMMConsistence( EHMMObj &ehmmObj )
{
const string ERROR = "Database '" + _databaseName + "' is not consistent.
Terminating application.";
int noStates[ MAX_STATES ];
int noMix[ MAX_STATES - 1 ];
int totalNoInternalStates;
int i;
assert( _databaseName != "" );
ehmmObj.GetEHMM( ).GetNoStates( noStates );
ehmmObj.GetEHMM( ).GetNoMix( noMix );
//Count the number of internal states
for ( totalNoInternalStates = 0, i = 1; i < noStates[ 0 ] + 1; i++ )
{
totalNoInternalStates += noStates[ i ];
}
//Check vector size, states and mixtures
if ( ehmmObj.GetEHMM( ).GetVecSize( ) != _vecSize
|| memcmp( noStates, _numStates, _numStates[ 0 ] + 1 )
|| memcmp( noMix, _numMix, totalNoInternalStates ) )
{
}
//*****************************************************************************
ostream& operator<<( ostream &os, EHMMObjDatabase &obj )
{
vector< EHMMObj* >::iterator objsIt;
int c;
assert( obj._databaseName != "" );
os << "Database of ehmms '" << obj._databaseName << "' contains..." <<
endl;
for ( c = 1, objsIt = obj._objs.begin( ); objsIt < obj._objs.end( );
objsIt++, c++ )
{
os << c << ")" << " " << (*objsIt)->GetName( ) << endl;
}
}
return os;
//*****************************************************************************
#ifndef _EHMMObjRecognition_H_
#define _EHMMObjRecognition_H_
//Forward declarations
class EHMMObj;
class ImgObj;
class EHMMObjDatabase;
class ImgObjDatabase;
//Disable OpenCv type cast warning
#pragma warning( disable : 4312 )
#include <vector>
#include "cv.h"
#include "ipl.h"
#pragma warning( default : 4312 )
class EHMMObjRecognition
{
public:
EHMMObjRecognition( );
virtual ~EHMMObjRecognition( );
void Create( int imgWidth, int imgHeight, int obsWidth, int obsHeight, int
noDCTCoeffX,
int noDCTCoeffY, int stepX, int stepY, bool suppressIntensity =
false );
void Release( );
void Train( ImgObj &imgObj, EHMMObj &ehmmObj );
void Train( ImgObjDatabase &imgObjDb, EHMMObjDatabase &ehmmObjDb );
float ComputeLikelihood( IplImage &img, EHMMObj &ehmmObj );
size_t ComputeLikelihood( IplImage &img, EHMMObjDatabase &ehmmObjDb,
std::vector< float > &likelihood );
private:
void CountObs( IplROI &roi, CvSize &winSize, CvSize &stepSize,
CvSize &noObs );
void ExtractDCT( float* src, float* dst, int num_vec, int dst_len );
//Controls the size of the observation vectors (the DCT window size)
CvSize _dctSize;
//Step of the DCT through the input image
CvSize _stepSize;
//Number of DCT coefficients to use
CvSize _noDCTCoeff;
//Controls how the image is resizes
int _imgWidth;
int _imgHeight;
};
#endif //_EHMMObjRecognition_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
"EHMMObjRecognition.h"
"EHMMObj.h"
"ImgObj.h"
"ImgObjDatabase.h"
"EHMMObjDatabase.h"
"Utils.h"
<iostream>
<cv.h>
<vector>
<math.h>
<float.h>
using std::cerr;
using std::endl;
using std::vector;
//*****************************************************************************
EHMMObjRecognition::EHMMObjRecognition( )
{
Release( );
}
//*****************************************************************************
EHMMObjRecognition::~EHMMObjRecognition( )
{
}
//*****************************************************************************
void EHMMObjRecognition::Create( int imgWidth, int imgHeight, int obsWidth,
int obsHeight, int noDCTCoeffX,
int noDCTCoeffY,
int stepX, int stepY, bool
suppressIntensity )
{
assert( _imgWidth == -1 );
assert( _imgHeight == -1 );
_dctSize = cvSize( obsWidth, obsHeight );
_stepSize = cvSize( stepX, stepY );
_noDCTCoeff = cvSize( noDCTCoeffX, noDCTCoeffY );
//They are used only for training
_imgWidth = imgWidth;
_imgHeight = imgHeight;
_suppressIntensity = suppressIntensity;
}
//*****************************************************************************
void EHMMObjRecognition::Release( )
{
assert( _imgWidth != -1 );
assert( _imgHeight != -1 );
_imgWidth = _imgHeight = -1;
}
//*****************************************************************************
/*
*
Train the CvEHMM using A. Nefian's algorithm (See OpenCV documentation)
*/
void EHMMObjRecognition::Train( ImgObj &imgObj, EHMMObj &ehmmObj )
{
const int MAX_ITER = 80;
const double STOP_STEP_ITER = 0.01;
CvImgObsInfo **obsInfoVec;
IplImage *iplImg;
int obsVecLen = _noDCTCoeff.width * _noDCTCoeff.height;
CvSize _noObs;
CvEHMM *tmplEhmm = ehmmObj.GetEHMM( ).GetCvEHMM( );
int numImages = (int)imgObj.GetNoImages( );
bool trained = false;
float oldLikelihood = 0;
int counter = 0;
int i;
assert( _imgWidth != -1 );
assert( _imgHeight != -1 );
if( _suppressIntensity )
{
//Suppress first DCT coefficient
obsVecLen--;
}
//Create the obsinfo array
obsInfoVec = new CvImgObsInfo*[ numImages ];
assert( obsInfoVec != 0 );
{
if( _suppressIntensity )
{
float *observations = new float[ _noObs.height * _noObs.width *
( obsVecLen + 1 ) ];
cvImgToObs_DCT( iplImg, observations, _dctSize, _noDCTCoeff,
_stepSize );
ExtractDCT( observations, obsInfoVec[ i ]->obs, _noObs.height
* _noObs.width, obsVecLen );
}
else
{
if ( observations )
{
delete( observations);
}
_stepSize );
}
cvReleaseImage( &iplImg );
oldLikelihood = likelihood;
//Clear the observations
for( i = 0; i < numImages; i++ )
{
cvReleaseObsInfo( &(obsInfoVec[ i ]) );
}
delete []obsInfoVec;
//*****************************************************************************
/*
*
Apply the training algorithm on two databases of images and ehmms.
*
Train only for the users that appear in the ImgObjDatabase
*/
void EHMMObjRecognition::Train( ImgObjDatabase &imgObjDb, EHMMObjDatabase
&ehmmObjDb )
{
size_t i;
EHMMObj *tmpEHMMObj;
ImgObj *tmpImgObj;
//Train for every object in imgObjDb
for ( i = 0; i < imgObjDb.GetNoObjs( ); i++ )
{
try
{
tmpImgObj = &imgObjDb.GetObj( i );
tmpEHMMObj = &ehmmObjDb.GetObj( tmpImgObj->GetName( ) );
Train( *tmpImgObj, *tmpEHMMObj );
}
catch( exception &e )
{
cerr << e.what( ) << endl;
}
catch( ... )
{
abort( );
}
}
//Check that all users are trained
for ( i = 0; i < ehmmObjDb.GetNoObjs( ); i++ )
{
if ( !ehmmObjDb.GetObj( i ).GetEHMM( ).GetTrained( ) )
{
cerr << "Warning: Obj " << ehmmObjDb.GetObj( i ).GetName( )
<< " is not trained." << endl;
}
}
}
//*****************************************************************************
/*
*
Recognize with ehmm using A. Nefian's algorithm (See OpenCV documentation)
*
This function returns the match likelihood
*/
float EHMMObjRecognition::ComputeLikelihood( IplImage &img, EHMMObj &ehmmObj )
{
CvSize _noObs;
CvEHMM *tmplEhmm = ehmmObj.GetEHMM( ).GetCvEHMM( );
int obsVecLen = _noDCTCoeff.width * _noDCTCoeff.height;
CvImgObsInfo* info;
if( _suppressIntensity )
{
obsVecLen--;
}
//Get how many DCT transforms we compute
CountObs( *img.roi, _dctSize, _stepSize, _noObs );
info = cvCreateObsInfo( _noObs, obsVecLen );
assert( info != 0 );
if( _suppressIntensity )
{
float *observations = new float[ _noObs.height * _noObs.width *
( obsVecLen + 1 ) ];
cvImgToObs_DCT( &img, observations, _dctSize, _noDCTCoeff, _stepSize
);
}
cvEstimateObsProb( info, tmplEhmm );
return cvEViterbi( info, tmplEhmm );
}
//*****************************************************************************
/*
*
Apply the recognition algorithm on a database of ehmms. Returns all the
*
likelihoods for all the ehmms in teh database and the index of the best
match
*/
size_t EHMMObjRecognition::ComputeLikelihood( IplImage &img, EHMMObjDatabase
&ehmmObjDb,
vector< float
> &likelihood )
{
size_t i;
EHMMObj *tmpEHMMObj;
size_t maxLikelihoodPos = -1;
float maxLikelihood = -FLT_MAX;
//Train for every object in imgObjDb
for ( i = 0; i < ehmmObjDb.GetNoObjs( ); i++ )
{
try
{
tmpEHMMObj = &ehmmObjDb.GetObj( i );
if ( tmpEHMMObj->GetEHMM( ).GetTrained( ) )
{
likelihood.push_back( ComputeLikelihood( img,
*tmpEHMMObj ) );
maxLikelihood )
];
}
}
catch( exception &e )
{
cerr << e.what( ) << endl;
}
catch( ... )
{
abort( );
}
return maxLikelihoodPos;
}
//*****************************************************************************
void EHMMObjRecognition::CountObs( IplROI &roi, CvSize &winSize, CvSize
&_stepSize,
CvSize &_noObs )
{
_noObs.width = ( roi.width - winSize.width + _stepSize.width ) /
_stepSize.width;
_noObs.height = ( roi.height - winSize.height + _stepSize.height ) /
_stepSize.height;
}
//*****************************************************************************
/*
*
Used to suppress the first DCT coefficient
*/
void EHMMObjRecognition::ExtractDCT( float* src, float* dst, int numVec, int
dstLen )
{
float *tmpSrc = src + 1;
float *tmpDst = dst;
int i;
for( i = 0; i < numVec; i++ )
{
memcpy( tmpDst, tmpSrc, dstLen * sizeof( float ) );
tmpSrc += dstLen + 1;
tmpDst += dstLen;
}
}
//*****************************************************************************
/*
/*
/*
*/
#ifndef _RecognizeEHMM_H_
#define _RecognizeEHMM_H_
//Disable OpenCv type cast warning
#pragma warning( disable : 4312 )
#include <ipl.h>
#include <cv.h>
#pragma warning( default : 4312 )
//Forward declarations
class EHMMObj;
class EHMMObjDatabase;
float RecognizeEHMM( IplImage &img, EHMMObj &ehmmObj, int obsWidth, int
obsHeight,
int noDCTCoeffX, int noDCTCoeffY, int stepX, int
stepY,
bool suppressIntensity = false );
size_t RecognizeEHMM( IplImage &img, EHMMObjDatabase &ehmmObjDb, int obsWidth,
int obsHeight,
int noDCTCoeffX, int noDCTCoeffY, int stepX, int
stepY,
bool suppressIntensity = false );
#endif //_RecognizeEHMM_H_
#include "EHMMObj.h"
#include "EHMMObjDatabase.h"
#include "Utils.h"
#include
#include
#include
#include
"RecognizeEHMM.h"
<vector>
<iostream>
<float.h>
using std::cerr;
using std::endl;
using std::vector;
//*****************************************************************************
/*
*
Recognize with ehmm using A. Nefian's algorithm (See OpenCV documentation)
*
This function returns the match likelihood
*/
float RecognizeEHMM( IplImage &img, EHMMObj &ehmmObj, int obsWidth, int
obsHeight,
int noDCTCoeffX, int noDCTCoeffY, int stepX, int
stepY,
bool suppressIntensity )
{
CvSize noObs;
CvSize dctSize = cvSize( obsWidth, obsHeight );
CvSize stepSize = cvSize( stepX, stepY );
CvSize obsSize = cvSize( noDCTCoeffX, noDCTCoeffY );
CvEHMM *tmplEhmm = ehmmObj.GetEHMM( ).GetCvEHMM( );
int obsVecLen = noDCTCoeffX * noDCTCoeffY;
CvImgObsInfo* info;
if( suppressIntensity )
{
obsVecLen--;
}
//Get how many DCT transforms we compute
CountObs( *img.roi, dctSize.width, dctSize.height, stepSize.width,
stepSize.height,
noObs.width, noObs.height );
info = cvCreateObsInfo( noObs, obsVecLen );
assert( info != 0 );
if( suppressIntensity )
{
float *observations = new float[ noObs.height * noObs.width *
( obsVecLen + 1 ) ];
cvImgToObs_DCT( &img, observations, dctSize, obsSize, stepSize );
ExtractDCT( observations, info->obs, noObs.height * noObs.width,
obsVecLen );
}
else
{
if ( observations )
{
delete( observations);
}
{
maxLikelihood = likelihood[ likelihood.size( ) - 1
];
}
maxLikelihoodPos = i;
}
catch( exception &e )
{
cerr << e.what( ) << endl;
}
catch( ... )
{
abort( );
}
";
return maxLikelihoodPos;
#ifndef _ImgObj_H_
#define _ImgObj_H_
#include
#include
#include
#include
#include
#include
#include
"Obj.h"
"EHMM.h"
<vector>
<string>
<ostream>
<ipl.h>
<cv.h>
private:
//Stores the paths to the images
std::vector< std::string > _imagePaths;
int _imgWidth;
int _imgHeight;
};
"ImgObj.h"
<fstream>
<iostream>
<assert.h>
<highgui.h>
std::string;
std::vector;
std::ifstream;
std::ofstream;
std::endl;
std::ostream;
using std::cout;
//Standard extension to the user file
static const string EXTENSION = ".imobj";
//*****************************************************************************
ImgObj::ImgObj( )
{
}
//*****************************************************************************
ImgObj::~ImgObj( )
{
}
//*****************************************************************************
void ImgObj::Create( const string &userName )
{
assert( _name == "" );
Obj::Create( userName );
}
//*****************************************************************************
void ImgObj::Load( const string &userName, const string &path )
{
const int INITIAL_SIZE = 1000;
const int MAX_LINE_WIDTH = _MAX_PATH;
const string IMGUSER_FILE = path + userName + EXTENSION;
char line[ MAX_LINE_WIDTH ];
ifstream file( IMGUSER_FILE.c_str( ) );
assert( _name == "" );
assert( file.is_open( ) );
Obj::Create( userName );
_imagePaths.reserve( INITIAL_SIZE );
while ( file.getline( line, sizeof( line ) ) )
{
}
_imagePaths.push_back( line );
}
//*****************************************************************************
void ImgObj::Save( const string &path )
{
const string IMGUSER_FILE = path + _name + EXTENSION;
vector< string >::iterator imIt;
ofstream file( IMGUSER_FILE.c_str( ) );
assert( _name != "" );
assert( file.is_open( ) );
for ( imIt = _imagePaths.begin( ); imIt < _imagePaths.end( ); imIt++ )
{
file << (*imIt) << endl;
}
}
//*****************************************************************************
void ImgObj::Release( )
{
vector< string >::iterator imIt;
assert( _name != "" );
for ( imIt = _imagePaths.begin( ); imIt < _imagePaths.end( ); imIt++ )
{
(*imIt) = "";
}
_name = "";
}
//*****************************************************************************
void ImgObj::AddImage( const string &imagePath )
{
assert( _name != "" );
}
_imagePaths.push_back( imagePath );
//*****************************************************************************
/*
*
Load the image from the disk. Convert it to gray scale
*
because it is always loaded as a color image.
*
The IplImage will be returned by GetImage with
*
this dimensions no matter the dimensions
*
of image stored on disk. If one of the dimensions
*
is 0 then only the other dimension is used. If both
*
are 0 the image will not be rescaled
*/
IplImage* ImgObj::GetGrayScaleImage( size_t index, int imgWidth, int imgHeight,
bool showImage )
{
IplImage *imgDb;
IplImage *imgHdd;
IplImage *imgGray;
assert( _name != "" );
imgHdd = cvLoadImage( _imagePaths[ index ].c_str( ), 0 );
assert( imgHdd != 0 );
imgGray = cvCreateImage( cvSize( imgHdd->width, imgHdd->height ),
IPL_DEPTH_8U, 1 );
assert( imgGray != 0 );
//Resize the output image to the requested size
if ( imgWidth && imgHeight )
{
imgDb = cvCreateImage( cvSize( imgWidth, imgHeight ), IPL_DEPTH_8U,
1 );
}
else
if ( imgHeight )
{
imgDb = cvCreateImage( cvSize( imgHdd->width * imgHeight / imgHdd>height, imgHeight ),
IPL_DEPTH_8U, 1 );
}
if ( imgWidth )
{
imgDb = cvCreateImage( cvSize( imgWidth, imgHdd->height * imgWidth /
imgHdd->width ),
IPL_DEPTH_8U, 1 );
}
else
{
imgDb = cvCreateImage( cvSize( imgHdd->width, imgHdd->height ),
IPL_DEPTH_8U, 1 );
}
assert( imgDb != 0 );
//Check that the image is already grayscale
if ( imgHdd->nChannels > 1 )
{
//Make sure the output is gray scale
iplColorToGray( imgHdd, imgGray );
//Resize to the desired dimension
iplResizeFit( imgGray, imgDb, IPL_INTER_NN );
}
else
{
}
return imgDb;
//*****************************************************************************
size_t ImgObj::GetNoImages( )
{
assert( _name != "" );
return _imagePaths.size( );
}
//*****************************************************************************
ostream& operator<<( ostream &os, ImgObj &obj )
{
vector< string >::iterator imIt;
int c;
assert( obj._name != "" );
os << "Obj '" << obj._name << "' contains..." << endl << endl;
for ( c = 1, imIt = obj._imagePaths.begin( ); imIt <
obj._imagePaths.end( );
imIt++, c++ )
{
os << c << ")" << " " << (*imIt) << endl;
}
}
return os;
//*****************************************************************************
#ifndef _ImgObjDatabase_H_
#define _ImgObjDatabase_H_
#include "ImgObj.h"
#include <vector>
#include <iostream>
//Exception specification warning
#pragma warning( disable : 4290 )
class ImgObjDatabase
{
public:
ImgObjDatabase( );
virtual ~ImgObjDatabase( );
void Create( const std::string &databaseName );
void Load( const std::string &databaseName, const std::string &path );
void Save( const std::string &path );
void Release( );
void LoadObj( const std::string &userName, const std::string &path );
void AddObj( const std::string &userName );
void RemoveObj( size_t index );
void RemoveObj( const std::string &userName );
ImgObj& GetObj( size_t index );
ImgObj& GetObj( const std::string &userName ) throw( exception );
size_t GetNoObjs( ) const;
friend std::ostream& operator<<( std::ostream &os, ImgObjDatabase &obj );
private:
//Stores all the users with their
//associated properties
std::vector< ImgObj* > _objs;
//Name of the database file
std::string _databaseName;
};
std::ostream& operator<<( std::ostream &os, ImgObjDatabase &obj );
#endif //_ImgObjDatabase_H_
#include
#include
#include
#include
using
using
using
using
using
using
using
using
using
"ImgObjDatabase.h"
<fstream>
<iostream>
<assert.h>
std::vector;
std::ifstream;
std::ofstream;
std::iostream;
std::ostream;
std::string;
std::cout;
std::endl;
std::cerr;
//*****************************************************************************
ImgObjDatabase::ImgObjDatabase( )
{
_databaseName = "";
}
//*****************************************************************************
ImgObjDatabase::~ImgObjDatabase( )
{
Release( );
}
//*****************************************************************************
void ImgObjDatabase::Create( const string &databaseName )
{
assert( _databaseName == "" );
_databaseName = databaseName;
}
//*****************************************************************************
/*
*
Load a database from disk
*/
void ImgObjDatabase::Load( const string &databaseName, const string &path )
{
const string DATABASE_PATH = path + databaseName;
const int MAX_LINE_WIDTH = 255;
const int INITIAL_SIZE = 1000;
ifstream file( DATABASE_PATH.c_str( ) );
char line[ MAX_LINE_WIDTH ];
assert( file.is_open( ) );
_objs.reserve( INITIAL_SIZE );
while ( file.getline( line, sizeof( line ) ) )
{
//Create a new object
_objs.push_back( new ImgObj( ) );
try
{
}
catch( ... )
{
if ( _objs[ _objs.size( ) - 1 ] )
{
delete _objs[ _objs.size( ) - 1 ];
_objs[ _objs.size( ) - 1 ] = 0;
}
_objs.pop_back( );
cerr << "Exception occured when creating " << line << "." <<
endl;
}
//*****************************************************************************
/*
*
Save the database to disk. It will overwrite the previous data
*/
void ImgObjDatabase::Save( const string &path )
{
const string DATABASE_PATH = path + _databaseName;
vector< ImgObj* >::iterator usersIt;
ofstream file( DATABASE_PATH.c_str( ) );
assert( _databaseName != "" );
assert( file.is_open( ) );
//*****************************************************************************
void ImgObjDatabase::Release( )
{
vector< ImgObj* >::iterator usersIt;
assert( _databaseName != "" );
for ( usersIt = _objs.begin( ); usersIt < _objs.end( ); usersIt++ )
{
delete (*usersIt);
*usersIt = 0;
}
_databaseName = "";
}
//*****************************************************************************
/*
*
Load the object
*/
void ImgObjDatabase::LoadObj( const string &userName, const string &path )
{
_objs.push_back( new ImgObj( ) );
_objs[ _objs.size( ) - 1 ]->Load( userName, path );
}
//*****************************************************************************
/*
*
Add a new object to the database
*/
void ImgObjDatabase::AddObj( const string &userName )
{
_objs.push_back( new ImgObj( ) );
//*****************************************************************************
/*
*
Remove the first occurance of an object from the database by name
*/
void ImgObjDatabase::RemoveObj( const string &userName )
{
const string EXCEPTION_STR = "ImgObjDatabase::RemoveObj: " + userName + "
not found.";
vector< ImgObj* >::iterator usersIt;
assert( _databaseName != "" );
for ( usersIt = _objs.begin( ); usersIt < _objs.end( ); usersIt++ )
{
if ( (*usersIt)->GetName( ) == userName )
{
_objs.erase( usersIt );
return;
}
//*****************************************************************************
size_t ImgObjDatabase::GetNoObjs( ) const
{
assert( _databaseName != "" );
return _objs.size( );
}
//*****************************************************************************
ostream& operator<<( ostream &os, ImgObjDatabase &obj )
{
vector< ImgObj* >::iterator usersIt;
int c;
assert( obj._databaseName != "" );
os << "Database of images '" << obj._databaseName << "' contains..." <<
endl;
for ( c = 1, usersIt = obj._objs.begin( ); usersIt < obj._objs.end( );
usersIt++, c++ )
{
os << c << ")" << " " << (*usersIt)->GetName( ) << endl;
}
}
return os;
#ifndef _Obj_H_
#define _Obj_H_
#include <string>
#include <vector>
class Obj
{
public:
Obj( );
virtual ~Obj( );
void Create( const std::string &userName );
const std::string& GetName( ) const;
protected:
};
#endif //_Obj_H_
#include "Obj.h"
#include <assert.h>
using std::string;
//*****************************************************************************
Obj::Obj( ) : _name("")
{
}
//*****************************************************************************
Obj::~Obj( )
{
}
//*****************************************************************************
void Obj::Create( const string &userName )
{
assert( userName != "" );
}
_name = userName;
//*****************************************************************************
const string& Obj::GetName( ) const
{
assert( _name != "" );
return _name;
}
//*****************************************************************************
il training
il riconoscimento
Tutte le funzioni usate sono le seguenti :
Embedded Hidden Markov Models Functions
In order to support embedded models the user must
structures to represent 1D HMM and 2D embedded HMM model.
CvHMM
define
of
observations
the
following
structure
is
int*
stateNumber,
int*
numMix,
int
stateNumber
Array, the first element of the which specifies the number of
superstates in the HMM. All subsequent elements specify the
number of states in every embedded HMM, corresponding to each
superstate. So, the length of the array is stateNumber
[0]+1 .
numMix
Array with numbers of Gaussian mixture components per each
internal state. The number of elements in the array is equal
to number of internal states in the HMM, that is, superstates
are not counted here.
obsSize
Size of observation vectors to be used with created HMM.
The function cvCreate2DHMM returns the created structure of the
type CvEHMM with specified parameters.
Release2DHMM
by
dctSize
Size of image blocks for which DCT (Discrete Cosine
Transform) coefficients are to be computed.
obsSize
Number of the lowest DCT coefficients in the horizontal and
vertical directions to be put into the observation vector.
delta
Shift in pixels between two consecutive image blocks in the
horizontal and vertical directions.
The function cvImgToObs_DCT extracts observation vectors, that is,
DCT coefficients, from the image. The user must pass obsInfo.obs
as the parameter obs to use this function with other HMM functions
and use the structure obsInfo of the CvImgObsInfo type.
Calculating Observations for HMM
CvImgObsInfo* obs_info;
...
cvImgToObs_DCT( image,obs_info->obs, //!!!
dctSize, obsSize, delta );
UniformImgSegm
Performs uniform segmentation of image observations by HMM states
void cvUniformImgSegm( CvImgObsInfo* obsInfo, CvEHMM* hmm );
obsInfo
Observations structure.
hmm
HMM structure.
The function cvUniformImgSegm segments image observations by HMM
states uniformly (see Initial Segmentation for 2D Embedded HMM for
2D embedded HMM with 5 superstates and 3, 6, 6, 6, 3 internal
states of every corresponding superstate).
Initial Segmentation for 2D Embedded HMM
InitMixSegm
Segments all observations within every internal state of HMM by
state mixture components
void cvInitMixSegm(
CvEHMM* hmm );
CvImgObsInfo**
obsInfoArray,
int
numImg,
obsInfoArray
Array of pointers to the observation structures.
numImg
Length of above array.
hmm
HMM.
The function cvInitMixSegm takes a group of observations from
several training images already segmented by states and splits a
set of observation vectors within every internal HMM state into as
many clusters as the number of mixture components in the state.
EstimateHMMStateParams
Estimates all parameters of every HMM state
void cvEstimateHMMStateParams(
numImg, CvEHMM* hmm );
CvImgObsInfo**
obsInfoArray,
int
obsInfoArray
Array of pointers to the observation structures.
numImg
Length of the array.
hmm
HMM.
The
function
cvEstimateHMMStateParams
computes
all
parameters
of
every
HMM
state,
including
Gaussian
variances, etc.
EstimateTransProb
inner
means,
obsInfo
Observation structure.
hmm
HMM structure.
The function cvEstimateObsProb computes Gaussian probabilities of
each observation to occur in each of the internal HMM states.
EViterbi
Executes Viterbi algorithm for embedded HMM
float cvEViterbi( CvImgObsInfo* obsInfo, CvEHMM* hmm );
obsInfo
Observation structure.
hmm
HMM structure.
The function cvEViterbi executes Viterbi algorithm for embedded
HMM. Viterbi algorithm evaluates the likelihood of the best match
between the given image observations and the given HMM and
performs segmentation of image observations by HMM states. The
segmentation is done on the basis of the match found.
MixSegmL2
Segments observations from all training
components of newly assigned states
images
by
mixture
i,
_imgWidth,
iplImg,
observations,
_dctSize,
]->obs,
Estrae I DCT
if ( observations )
{
delete( observations);
}
}
else
{
cvImgToObs_DCT( iplImg, obsInfoVec[ i ]->obs,
_dctSize, _noDCTCoeff, _stepSize );
}
cvUniformImgSegm( obsInfoVec[ i ], tmplEhmm );
Esegue
una
segmentazione
uniforma
basandosi
sullosservazione
obsInfoVec,
numImages,
tmplEhmm );
Valuta i parametri di ogni stato HMM
cvEstimateTransProb( obsInfoVec, numImages, tmplEhmm);
Computa la matrice probabilistica delle transazioni per gli EHMM
for( j = 0; j < numImages; j++ )
{
cvEstimateObsProb( obsInfoVec[ j ], tmplEhmm );
likelihood += cvEViterbi( obsInfoVec[ j ], tmplEhmm );
}
Per ciascuna immagine presente computa la probablit di ciascun
osservatore per ogni immagine.
La seconda funzione esegue lalgoritmo di VITERBI sugli EHMM.
Tale funzionalit finalizzata a valutare la verisomiglianza sul
losservatore migliore trovato relativo ad un immagine.
Inoltre viene eseguita la segmentazione.
likelihood /= numImages * obsInfoVec[ 0 ]->obs_size;
cvMixSegmL2( &obsInfoVec[ 0 ], numImages, tmplEhmm );
ricava losservatore segmentato da tutte le immagini trainate
attraverso i misture components dei nuovi stati assegnati.
trained
fabs(
likelihood
oldLikelihood
<
STOP_STEP_ITER );
oldLikelihood = likelihood;
}
for( i = 0; i < numImages; i++ )
{
cvReleaseObsInfo( &(obsInfoVec[ i ]) );
}
delete []obsInfoVec;
ehmmObj.GetEHMM( ).SetTrained( trained );
}
La funzione che calcola la verisomiglianza la seguente :
float
EHMMObjRecognition::ComputeLikelihood(
EHMMObj &ehmmObj )
{
CvSize _noObs;
IplImage
&img,
&img,
ExtractDCT( observations,
_noObs.width, obsVecLen );
if ( observations )
{
delete( observations);
}
}
new
float[
_noObs.height
observations,
info->obs,
_dctSize,
_noObs.height
else
{
cvImgToObs_DCT( &img, info->obs, _dctSize, _noDCTCoeff,
_stepSize );
}
cvEstimateObsProb( info, tmplEhmm );
return cvEViterbi( info, tmplEhmm );
}
Un punto critico quello legato alla scelta dei valori legati ai
superstati come avviene nella funzione :
void
CEHMMRetinalIDDlg::CreateOpenRetinalEHMMDb(
const
string
&pathEhmmDb, const string &ehmmCvDbName )
{
EHMMObjDatabase ehmmDb;
int noStates[] = { 5, 4, 4, 4, 4, 4 };
int numMixtures[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
int vecSize = 15; //because we suppress the first coefficient
DCT_SIZE_X * DCT_SIZE_Y - 1
ehmmDb.Create( ehmmCvDbName, noStates, numMixtures, vecSize );
Il metodo Create della classe ehmmDb :
void EHMMObjDatabase::Create(
*noStates,
const
string
&databaseName,
int
noStates != 0 );
noMix != 0 );
vecSize != 0 );
databaseName != "" );
totalNoInternalStates += noStates[ i ];
}
memcpy(
_numMix,
totalNoInternalStates );
noMix,
sizeof(
int
_vecSize = vecSize;
}
Nel manuale, ad esempio, viene mostrata un immagine su cui vengono
applicati 5 superstati e 3, 6, 6, 6, 3 stati
interni.
Tale
scelta
di
valori
viene
graficamente
visualizzata su di un immagine come in quella a
fianco.
Nel caso della retina la scelta dovr essere fatta
in modo tale da riuscire a coprire nel modo
migliore i particolari dellimmagine stessa.
Una scelta di 5 superstati e 4,4,4,4,4 potrebbe
essere una soluzione equilibrata.
MODULE: Ado.h
#ifndef _ADO_H_
#define _ADO_H_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include <afx.h>
#include <afxdisp.h>
#include <math.h>
#pragma warning (disable: 4146)
// CG : In order to use this code against a different version of ADO, the
appropriate
// ADO library needs to be used in the #import statement
#import "C:\Program Files\Common Files\System\ADO\msado15.dll"
rename_namespace("ADOCG") rename("EOF", "EndOfFile")
using namespace ADOCG;
#pragma warning (default: 4146)
#include "icrsint.h"
class CADOCommand;
struct CADOFieldInfo
{
char m_strName[30];
short m_nType;
long m_lSize;
long m_lDefinedSize;
long m_lAttributes;
short m_nOrdinalPosition;
BOOL m_bRequired;
BOOL m_bAllowZeroLength;
long m_lCollatingOrder;
};
CString IntToStr(int nVal);
CString LongToStr(long lVal);
CString ULongToStr(unsigned long ulVal);
m_pConnection = NULL;
m_strConnection = _T("");
m_strLastError = _T("");
m_dwLastError = 0;
m_pConnection.CreateInstance(__uuidof(Connection));
m_nRecordsAffected = 0;
m_nConnectionTimeout = 0;
virtual ~CADODatabase()
{
Close();
m_pConnection.Release();
m_pConnection = NULL;
m_strConnection = _T("");
m_strLastError = _T("");
m_dwLastError = 0;
::CoUninitialize();
}
BOOL Open(LPCTSTR lpstrConnection = _T(""), LPCTSTR lpstrUserID = _T(""),
LPCTSTR lpstrPassword = _T(""));
_ConnectionPtr GetActiveConnection()
{return m_pConnection;};
BOOL Execute(LPCTSTR lpstrExec);
int GetRecordsAffected()
{return m_nRecordsAffected;};
DWORD GetRecordCount(_RecordsetPtr m_pRs);
long BeginTransaction()
{return m_pConnection->BeginTrans();};
long CommitTransaction()
{return m_pConnection->CommitTrans();};
long RollbackTransaction()
{return m_pConnection->RollbackTrans();};
BOOL IsOpen();
void Close();
void SetConnectionMode(cadoConnectModeEnum nMode)
{m_pConnection->PutMode((enum ConnectModeEnum)nMode);};
void SetConnectionString(LPCTSTR lpstrConnection)
{m_strConnection = lpstrConnection;};
CString GetConnectionString()
{return m_strConnection;};
CString GetLastErrorString()
{return m_strLastError;};
DWORD GetLastError()
{return m_dwLastError;};
CString GetErrorDescription()
{return m_strErrorDescription;};
void SetConnectionTimeout(long nConnectionTimeout = 30)
{m_nConnectionTimeout = nConnectionTimeout;};
protected:
void dump_com_error(_com_error &e);
public:
_ConnectionPtr m_pConnection;
protected:
CString m_strConnection;
CString m_strLastError;
CString m_strErrorDescription;
DWORD m_dwLastError;
int m_nRecordsAffected;
long m_nConnectionTimeout;
};
class CADORecordset
{
public:
BOOL Clone(CADORecordset& pRs);
enum cadoOpenEnum
{
openUnknown = 0,
openQuery = 1,
openTable = 2,
openStoredProc = 3
};
enum cadoEditEnum
{
dbEditNone = 0,
dbEditNew = 1,
dbEdit = 2
};
enum cadoPositionEnum
{
positionUnknown = -1,
positionBOF = -2,
positionEOF = -3
};
enum cadoSearchEnum
{
searchForward = 1,
searchBackward = -1
};
enum cadoDataType
{
typeEmpty = adEmpty,
typeTinyInt = adTinyInt,
typeSmallInt = adSmallInt,
typeInteger = adInteger,
typeBigInt = adBigInt,
typeUnsignedTinyInt = adUnsignedTinyInt,
typeUnsignedSmallInt = adUnsignedSmallInt,
typeUnsignedInt = adUnsignedInt,
typeUnsignedBigInt = adUnsignedBigInt,
typeSingle = adSingle,
typeDouble = adDouble,
typeCurrency = adCurrency,
typeDecimal = adDecimal,
typeNumeric = adNumeric,
typeBoolean = adBoolean,
typeError = adError,
typeUserDefined = adUserDefined,
typeVariant = adVariant,
typeIDispatch = adIDispatch,
typeIUnknown = adIUnknown,
typeGUID = adGUID,
typeDate = adDate,
typeDBDate = adDBDate,
typeDBTime = adDBTime,
typeDBTimeStamp = adDBTimeStamp,
typeBSTR = adBSTR,
typeChar = adChar,
typeVarChar = adVarChar,
typeLongVarChar = adLongVarChar,
typeWChar = adWChar,
typeVarWChar = adVarWChar,
typeLongVarWChar = adLongVarWChar,
typeBinary = adBinary,
typeVarBinary = adVarBinary,
typeLongVarBinary = adLongVarBinary,
typeChapter = adChapter,
typeFileTime = adFileTime,
typePropVariant = adPropVariant,
typeVarNumeric = adVarNumeric,
typeArray = adVariant
};
enum cadoSchemaType
{
schemaSpecific = adSchemaProviderSpecific,
schemaAsserts = adSchemaAsserts,
schemaCatalog = adSchemaCatalogs,
schemaCharacterSet = adSchemaCharacterSets,
schemaCollections = adSchemaCollations,
schemaColumns = adSchemaColumns,
schemaConstraints = adSchemaCheckConstraints,
schemaConstraintColumnUsage = adSchemaConstraintColumnUsage,
schemaConstraintTableUsage = adSchemaConstraintTableUsage,
shemaKeyColumnUsage = adSchemaKeyColumnUsage,
schemaTableConstraints = adSchemaTableConstraints,
schemaColumnsDomainUsage = adSchemaColumnsDomainUsage,
schemaIndexes = adSchemaIndexes,
schemaColumnPrivileges = adSchemaColumnPrivileges,
schemaTablePrivileges = adSchemaTablePrivileges,
};
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
schemaUsagePrivileges = adSchemaUsagePrivileges,
schemaProcedures = adSchemaProcedures,
schemaTables =adSchemaTables,
schemaProviderTypes = adSchemaProviderTypes,
schemaViews = adSchemaViews,
schemaProcedureParameters = adSchemaProcedureParameters,
schemaForeignKeys = adSchemaForeignKeys,
schemaPrimaryKeys = adSchemaPrimaryKeys,
schemaProcedureColumns = adSchemaProcedureColumns,
schemaDBInfoKeywords = adSchemaDBInfoKeywords,
schemaDBInfoLiterals = adSchemaDBInfoLiterals,
schemaCubes = adSchemaCubes,
schemaDimensions = adSchemaDimensions,
schemaHierarchies = adSchemaHierarchies,
schemaLevels = adSchemaLevels,
schemaMeasures = adSchemaMeasures,
schemaProperties = adSchemaProperties,
schemaMembers = adSchemaMembers,
CancelUpdate();
Update();
Edit();
AddNew();
AddNew(CADORecordBinding &pAdoRecordBinding);
m_pRecordset.Release();
if(m_pCmd)
m_pCmd.Release();
m_pRecordset = NULL;
m_pCmd = NULL;
m_pRecBinding = NULL;
m_strQuery = _T("");
m_strLastError = _T("");
m_dwLastError = 0;
m_nEditStatus = dbEditNone;
CString GetQuery()
{return m_strQuery;};
void SetQuery(LPCSTR strQuery)
{m_strQuery = strQuery;};
BOOL RecordBinding(CADORecordBinding &pAdoRecordBinding);
DWORD GetRecordCount();
BOOL IsOpen();
void Close();
BOOL Open(_ConnectionPtr mpdb, LPCTSTR lpstrExec = _T(""), int nOption =
CADORecordset::openUnknown);
BOOL Open(LPCTSTR lpstrExec = _T(""), int nOption =
CADORecordset::openUnknown);
BOOL OpenSchema(int nSchema, LPCTSTR SchemaID = _T(""));
long GetFieldCount()
{return m_pRecordset->Fields->GetCount();};
BOOL GetFieldValue(LPCTSTR lpFieldName, int& nValue);
BOOL GetFieldValue(int nIndex, int& nValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, long& lValue);
BOOL GetFieldValue(int nIndex, long& lValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, unsigned long& ulValue);
BOOL GetFieldValue(int nIndex, unsigned long& ulValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, double& dbValue);
BOOL GetFieldValue(int nIndex, double& dbValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, CString& strValue, CString
strDateFormat = _T(""));
BOOL GetFieldValue(int nIndex, CString& strValue, CString strDateFormat =
_T(""));
BOOL GetFieldValue(LPCTSTR lpFieldName, COleDateTime& time);
BOOL GetFieldValue(int nIndex, COleDateTime& time);
BOOL GetFieldValue(int nIndex, bool& bValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, bool& bValue);
BOOL GetFieldValue(int nIndex, COleCurrency& cyValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, COleCurrency& cyValue);
BOOL GetFieldValue(int nIndex, _variant_t& vtValue);
BOOL GetFieldValue(LPCTSTR lpFieldName, _variant_t& vtValue);
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
void
IsFieldNull(LPCTSTR lpFieldName);
IsFieldNull(int nIndex);
IsFieldEmpty(LPCTSTR lpFieldName);
IsFieldEmpty(int nIndex);
IsEof()
{return m_pRecordset->EndOfFile == VARIANT_TRUE;};
IsEOF()
{return m_pRecordset->EndOfFile == VARIANT_TRUE;};
IsBof()
{return m_pRecordset->BOF == VARIANT_TRUE;};
IsBOF()
{return m_pRecordset->BOF == VARIANT_TRUE;};
MoveFirst()
{m_pRecordset->MoveFirst();};
void MoveNext()
{m_pRecordset->MoveNext();};
void MovePrevious()
{m_pRecordset->MovePrevious();};
void MoveLast()
{m_pRecordset->MoveLast();};
long GetAbsolutePage()
{return m_pRecordset->GetAbsolutePage();};
void SetAbsolutePage(int nPage)
{m_pRecordset->PutAbsolutePage((enum PositionEnum)nPage);};
long GetPageCount()
{return m_pRecordset->GetPageCount();};
long GetPageSize()
{return m_pRecordset->GetPageSize();};
void SetPageSize(int nSize)
{m_pRecordset->PutPageSize(nSize);};
long GetAbsolutePosition()
{return m_pRecordset->GetAbsolutePosition();};
void SetAbsolutePosition(int nPosition)
{m_pRecordset->PutAbsolutePosition((enum PositionEnum)nPosition);};
BOOL GetFieldInfo(LPCTSTR lpFieldName, CADOFieldInfo* fldInfo);
BOOL GetFieldInfo(int nIndex, CADOFieldInfo* fldInfo);
BOOL AppendChunk(LPCTSTR lpFieldName, LPVOID lpData, UINT nBytes);
BOOL AppendChunk(int nIndex, LPVOID lpData, UINT nBytes);
BOOL GetChunk(LPCTSTR lpFieldName, CString& strValue);
BOOL GetChunk(int nIndex, CString& strValue);
BOOL GetChunk(LPCTSTR lpFieldName, LPVOID pData);
BOOL GetChunk(int nIndex, LPVOID pData);
CString GetString(LPCTSTR lpCols, LPCTSTR lpRows, LPCTSTR lpNull, long
numRows = 0);
CString GetLastErrorString()
{return m_strLastError;};
DWORD GetLastError()
{return m_dwLastError;};
void GetBookmark()
{m_varBookmark = m_pRecordset->Bookmark;};
BOOL SetBookmark();
BOOL Delete();
BOOL IsConnectionOpen()
{return m_pConnection != NULL && m_pConnection->GetState() !=
adStateClosed;};
_RecordsetPtr GetRecordset()
{return m_pRecordset;};
_ConnectionPtr GetActiveConnection()
{return m_pConnection;};
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
SetFilter(LPCTSTR strFilter);
SetSort(LPCTSTR lpstrCriteria);
SaveAsXML(LPCTSTR lpstrXMLFile);
OpenXML(LPCTSTR lpstrXMLFile);
Execute(CADOCommand* pCommand);
Requery();
public:
_RecordsetPtr m_pRecordset;
_CommandPtr m_pCmd;
protected:
_ConnectionPtr m_pConnection;
int m_nSearchDirection;
CString m_strFind;
_variant_t m_varBookFind;
_variant_t m_varBookmark;
int m_nEditStatus;
CString m_strLastError;
DWORD m_dwLastError;
void dump_com_error(_com_error &e);
IADORecordBinding *m_pRecBinding;
CString m_strQuery;
protected:
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
};
class CADOParameter
{
public:
enum cadoParameterDirection
{
paramUnknown = adParamUnknown,
paramInput = adParamInput,
paramOutput = adParamOutput,
paramInputOutput = adParamInputOutput,
paramReturnValue = adParamReturnValue
};
CADOParameter(int nType, long lSize = 0, int nDirection = paramInput,
CString strName = _T(""));
virtual ~CADOParameter()
{
m_pParameter.Release();
m_pParameter = NULL;
m_strName = _T("");
}
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
void
SetValue(int nValue);
SetValue(long lValue);
SetValue(double dbValue);
SetValue(CString strValue);
SetValue(COleDateTime time);
SetValue(_variant_t vtValue);
GetValue(int& nValue);
GetValue(long& lValue);
GetValue(double& dbValue);
GetValue(CString& strValue, CString strDateFormat = _T(""));
GetValue(COleDateTime& time);
GetValue(_variant_t& vtValue);
SetPrecision(int nPrecision)
{m_pParameter->PutPrecision(nPrecision);};
void SetScale(int nScale)
{m_pParameter->PutNumericScale(nScale);};
void SetName(CString strName)
{m_strName = strName;};
CString GetName()
{return m_strName;};
int GetType()
{return m_nType;};
_ParameterPtr GetParameter()
{return m_pParameter;};
protected:
void dump_com_error(_com_error &e);
protected:
_ParameterPtr m_pParameter;
CString m_strName;
int m_nType;
CString m_strLastError;
DWORD m_dwLastError;
};
class CADOCommand
{
public:
enum cadoCommandType
{
typeCmdText = adCmdText,
typeCmdTable = adCmdTable,
typeCmdTableDirect = adCmdTableDirect,
typeCmdStoredProc = adCmdStoredProc,
typeCmdUnknown = adCmdUnknown,
typeCmdFile = adCmdFile
};
CADOCommand(CADODatabase* pAdoDatabase, CString strCommandText = _T(""),
int nCommandType = typeCmdStoredProc);
virtual ~CADOCommand()
{
m_pCommand.Release();
m_pCommand = NULL;
m_strCommandText = _T("");
}
void SetTimeout(long nTimeOut)
{m_pCommand->PutCommandTimeout(nTimeOut);};
void SetText(CString strCommandText);
void SetType(int nCommandType);
int GetType()
{return m_nCommandType;};
BOOL AddParameter(CADOParameter* pAdoParameter);
BOOL AddParameter(CString strName, int nType, int nDirection,
int nValue);
BOOL AddParameter(CString strName, int nType, int nDirection,
long lValue);
BOOL AddParameter(CString strName, int nType, int nDirection,
double dblValue, int nPrecision = 0, int nScale = 0);
BOOL AddParameter(CString strName, int nType, int nDirection,
CString strValue);
BOOL AddParameter(CString strName, int nType, int nDirection,
COleDateTime time);
BOOL AddParameter(CString strName, int nType, int nDirection,
_variant_t vtValue, int nPrecision = 0, int nScale = 0);
CString GetText()
long lSize,
long lSize,
long lSize,
long lSize,
long lSize,
long lSize,
{return m_strCommandText;};
BOOL Execute();
int GetRecordsAffected()
{return m_nRecordsAffected;};
_CommandPtr GetCommand()
{return m_pCommand;};
protected:
void dump_com_error(_com_error &e);
protected:
_CommandPtr m_pCommand;
int m_nCommandType;
int m_nRecordsAffected;
CString m_strCommandText;
CString m_strLastError;
DWORD m_dwLastError;
};
class CADOException : public CException
{
public:
enum
{
noError,
Unknown,
// no error
// unknown error
};
DECLARE_DYNAMIC(CADOException);
CADOException(int nCause = 0, CString strErrorString = _T(""));
virtual ~CADOException();
static int GetError(int nADOError);
public:
int m_nCause;
CString m_strErrorString;
protected:
};
void AfxThrowADOException(int nADOError = 1000, CString strErrorString =
_T(""));
#endif
MODULE: Ado.cpp
#include "ado.h"
#define ChunkSize 100
///////////////////////////////////////////////////////
//
// CADODatabase Class
//
DWORD CADODatabase::GetRecordCount(_RecordsetPtr m_pRs)
{
DWORD numRows = 0;
numRows = m_pRs->GetRecordCount();
if(numRows == -1)
{
if(m_pRs->EndOfFile != VARIANT_TRUE)
m_pRs->MoveFirst();
while(m_pRs->EndOfFile != VARIANT_TRUE)
{
numRows++;
m_pRs->MoveNext();
}
if(numRows > 0)
m_pRs->MoveFirst();
}
return numRows;
}
BOOL CADODatabase::Open(LPCTSTR lpstrConnection, LPCTSTR lpstrUserID, LPCTSTR
lpstrPassword)
{
HRESULT hr = S_OK;
if(IsOpen())
Close();
if(strcmp(lpstrConnection, _T("")) != 0)
m_strConnection = lpstrConnection;
ASSERT(!m_strConnection.IsEmpty());
try
{
if(m_nConnectionTimeout != 0)
m_pConnection->PutConnectionTimeout(m_nConnectionTimeout);
hr = m_pConnection->Open(_bstr_t(m_strConnection),
_bstr_t(lpstrUserID), _bstr_t(lpstrPassword), NULL);
return hr == S_OK;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
void CADODatabase::dump_com_error(_com_error &e)
{
CString ErrorStr;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
ErrorStr.Format( "CADODataBase Error\n\tCode = %08lx\n\tCode meaning =
%s\n\tSource = %s\n\tDescription = %s\n",
m_pConnection = pAdoDatabase->GetActiveConnection();
Close();
if(strcmp(lpstrExec, _T("")) != 0)
m_strQuery = lpstrExec;
ASSERT(!m_strQuery.IsEmpty());
if(m_pConnection == NULL)
m_pConnection = mpdb;
m_strQuery.TrimLeft();
BOOL bIsSelect = m_strQuery.Mid(0, strlen("Select
")).CompareNoCase("select ") == 0 && nOption == openUnknown;
try
{
m_pRecordset->CursorType = adOpenStatic;
m_pRecordset->CursorLocation = adUseClient;
if(bIsSelect || nOption == openQuery || nOption == openUnknown)
m_pRecordset->Open((LPCSTR)m_strQuery,
_variant_t((IDispatch*)mpdb, TRUE),
adOpenStatic, adLockOptimistic,
adCmdUnknown);
else if(nOption == openTable)
m_pRecordset->Open((LPCSTR)m_strQuery,
_variant_t((IDispatch*)mpdb, TRUE),
adOpenKeyset, adLockOptimistic,
adCmdTable);
else if(nOption == openStoredProc)
{
m_pCmd->ActiveConnection = mpdb;
m_pCmd->CommandText = _bstr_t(m_strQuery);
m_pCmd->CommandType = adCmdStoredProc;
m_pConnection->CursorLocation = adUseClient;
}
else
{
{
_variant_t vtSchemaID = vtMissing;
if(strlen(SchemaID) != 0)
vtSchemaID = SchemaID;
m_pRecordset = m_pConnection->OpenSchema((enum SchemaEnum)nSchema,
vtMissing, vtSchemaID);
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::Requery()
{
if(IsOpen())
{
try
{
m_pRecordset->Requery(adExecuteRecord);
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
return TRUE;
}
BOOL CADORecordset::GetFieldValue(LPCTSTR lpFieldName, double& dbValue)
{
double val = (double)NULL;
_variant_t vtFld;
try
{
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_R4:
val = vtFld.fltVal;
break;
case VT_R8:
val = vtFld.dblVal;
break;
case VT_DECIMAL:
//Corrected by Jos Carlos Martnez Galn
val = vtFld.decVal.Lo32;
val *= (vtFld.decVal.sign == 128)? -1 : 1;
val /= pow(10, vtFld.decVal.scale);
break;
case VT_UI1:
val = vtFld.iVal;
break;
case VT_I2:
case VT_I4:
val = vtFld.lVal;
break;
case VT_INT:
val = vtFld.intVal;
break;
case VT_NULL:
case VT_EMPTY:
val = 0;
break;
default:
val = vtFld.dblVal;
}
dbValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_R4:
val = vtFld.fltVal;
break;
case VT_R8:
val = vtFld.dblVal;
break;
case VT_DECIMAL:
//Corrected by Jos Carlos Martnez Galn
val = vtFld.decVal.Lo32;
val *= (vtFld.decVal.sign == 128)? -1 : 1;
val /= pow(10, vtFld.decVal.scale);
break;
case VT_UI1:
val = vtFld.iVal;
break;
case VT_I2:
case VT_I4:
val = vtFld.lVal;
break;
case VT_INT:
val = vtFld.intVal;
break;
case VT_NULL:
case VT_EMPTY:
val = 0;
break;
default:
val = 0;
}
dbValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
if(vtFld.vt != VT_NULL && vtFld.vt != VT_EMPTY)
val = vtFld.lVal;
lValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::GetFieldValue(int nIndex, long& lValue)
{
long val = (long)NULL;
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
if(vtFld.vt != VT_NULL && vtFld.vt != VT_EMPTY)
val = vtFld.lVal;
lValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::GetFieldValue(LPCTSTR lpFieldName, unsigned long& ulValue)
{
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
case VT_NULL:
case VT_EMPTY:
val = 0;
break;
default:
val = vtFld.iVal;
}
nValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::GetFieldValue(int nIndex, int& nValue)
{
int val = (int)NULL;
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_BOOL:
val = vtFld.boolVal;
break;
case VT_I2:
case VT_UI1:
val = vtFld.iVal;
break;
case VT_INT:
val = vtFld.intVal;
break;
case VT_NULL:
case VT_EMPTY:
val = 0;
break;
default:
val = vtFld.iVal;
}
nValue = val;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
_variant_t vtFld;
try
{
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_R4:
str = DblToStr(vtFld.fltVal);
break;
case VT_R8:
str = DblToStr(vtFld.dblVal);
break;
case VT_BSTR:
str = vtFld.bstrVal;
break;
case VT_I2:
case VT_UI1:
str = IntToStr(vtFld.iVal);
break;
case VT_INT:
str = IntToStr(vtFld.intVal);
break;
case VT_I4:
str = LongToStr(vtFld.lVal);
break;
case VT_UI4:
str = ULongToStr(vtFld.ulVal);
break;
case VT_DECIMAL:
{
//Corrected by Jos Carlos Martnez Galn
double val = vtFld.decVal.Lo32;
val *= (vtFld.decVal.sign == 128)? -1 : 1;
val /= pow(10, vtFld.decVal.scale);
str = DblToStr(val);
}
break;
case VT_DATE:
{
COleDateTime dt(vtFld);
if(strDateFormat.IsEmpty())
strDateFormat = _T("%Y-%m-%d %H:%M:%S");
str = dt.Format(strDateFormat);
}
break;
case VT_EMPTY:
case VT_NULL:
str.Empty();
break;
case VT_BOOL:
str = vtFld.boolVal == VARIANT_TRUE? 'T':'F';
break;
default:
str.Empty();
return FALSE;
}
strValue = str;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_R4:
str = DblToStr(vtFld.fltVal);
break;
case VT_R8:
str = DblToStr(vtFld.dblVal);
break;
case VT_BSTR:
str = vtFld.bstrVal;
break;
case VT_I2:
case VT_UI1:
str = IntToStr(vtFld.iVal);
break;
case VT_INT:
str = IntToStr(vtFld.intVal);
break;
case VT_I4:
str = LongToStr(vtFld.lVal);
break;
case VT_UI4:
str = ULongToStr(vtFld.ulVal);
break;
case VT_DECIMAL:
{
//Corrected by Jos Carlos Martnez Galn
double val = vtFld.decVal.Lo32;
val *= (vtFld.decVal.sign == 128)? -1 : 1;
val /= pow(10, vtFld.decVal.scale);
str = DblToStr(val);
}
break;
case VT_DATE:
{
COleDateTime dt(vtFld);
if(strDateFormat.IsEmpty())
strDateFormat = _T("%Y-%m-%d %H:%M:%S");
str = dt.Format(strDateFormat);
}
break;
case VT_BOOL:
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_DATE:
{
COleDateTime dt(vtFld);
time = dt;
}
break;
case VT_EMPTY:
case VT_NULL:
time.SetStatus(COleDateTime::null);
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::GetFieldValue(int nIndex, COleDateTime& time)
{
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_DATE:
{
COleDateTime dt(vtFld);
time = dt;
}
break;
case VT_EMPTY:
case VT_NULL:
time.SetStatus(COleDateTime::null);
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_BOOL:
bValue = vtFld.boolVal == VARIANT_TRUE? true: false;
break;
case VT_EMPTY:
case VT_NULL:
bValue = false;
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_BOOL:
bValue = vtFld.boolVal == VARIANT_TRUE? true: false;
break;
case VT_EMPTY:
case VT_NULL:
bValue = false;
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_CY:
cyValue = (CURRENCY)vtFld.cyVal;
break;
case VT_EMPTY:
case VT_NULL:
{
cyValue = COleCurrency();
cyValue.m_status = COleCurrency::null;
}
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::GetFieldValue(int nIndex, COleCurrency& cyValue)
{
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
switch(vtFld.vt)
{
case VT_CY:
cyValue = (CURRENCY)vtFld.cyVal;
break;
case VT_EMPTY:
case VT_NULL:
{
cyValue = COleCurrency();
cyValue.m_status = COleCurrency::null;
}
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
try
{
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
return vtFld.vt == VT_NULL;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::IsFieldNull(int nIndex)
{
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
return vtFld.vt == VT_NULL;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::IsFieldEmpty(LPCTSTR lpFieldName)
{
_variant_t vtFld;
try
{
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
return vtFld.vt == VT_EMPTY || vtFld.vt == VT_NULL;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::IsFieldEmpty(int nIndex)
{
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
try
{
vtFld = m_pRecordset->Fields->GetItem(vtIndex)->Value;
return vtFld.vt == VT_EMPTY || vtFld.vt == VT_NULL;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::SetFieldEmpty(LPCTSTR lpFieldName)
{
_variant_t vtFld;
vtFld.vt = VT_EMPTY;
return PutFieldValue(lpFieldName, vtFld);
}
BOOL CADORecordset::SetFieldEmpty(int nIndex)
{
_variant_t vtFld;
vtFld.vt = VT_EMPTY;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
}
DWORD CADORecordset::GetRecordCount()
{
DWORD nRows = 0;
nRows = m_pRecordset->GetRecordCount();
if(nRows == -1)
{
nRows = 0;
if(m_pRecordset->EndOfFile != VARIANT_TRUE)
m_pRecordset->MoveFirst();
while(m_pRecordset->EndOfFile != VARIANT_TRUE)
{
nRows++;
m_pRecordset->MoveNext();
}
if(nRows > 0)
m_pRecordset->MoveFirst();
return nRows;
}
BOOL CADORecordset::IsOpen()
{
if(m_pRecordset != NULL && IsConnectionOpen())
return m_pRecordset->GetState() != adStateClosed;
return FALSE;
}
void CADORecordset::Close()
{
if(IsOpen())
{
if (m_nEditStatus != dbEditNone)
CancelUpdate();
m_pRecordset->PutSort(_T(""));
m_pRecordset->Close();
}
str += varChunk.bstrVal;
lngOffSet += ChunkSize;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
lngOffSet = 0;
strValue = str;
return TRUE;
}
BOOL CADORecordset::GetChunk(LPCTSTR lpFieldName, LPVOID lpData)
{
FieldPtr pField = m_pRecordset->Fields->GetItem(lpFieldName);
}
else
break;
lngOffSet += ChunkSize;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
lngOffSet = 0;
return TRUE;
}
lngOffset = 0;
//Assign the Safe array to a variant.
varChunk.vt = VT_ARRAY|VT_UI1;
varChunk.parray = psa;
hr = pField->AppendChunk(varChunk);
if(SUCCEEDED(hr)) return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
return FALSE;
m_nEditStatus = dbEditNew;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
BOOL CADORecordset::Update()
{
BOOL bret = TRUE;
if(m_nEditStatus != dbEditNone)
{
try
{
if(m_pRecordset->Update() != S_OK)
bret = FALSE;
}
catch(_com_error &e)
{
dump_com_error(e);
bret = FALSE;
}
if(!bret)
m_pRecordset->CancelUpdate();
m_nEditStatus = dbEditNone;
}
return bret;
}
void CADORecordset::CancelUpdate()
{
m_pRecordset->CancelUpdate();
m_nEditStatus = dbEditNone;
}
BOOL CADORecordset::SetFieldValue(int nIndex, CString strValue)
{
_variant_t vtFld;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
if(!strValue.IsEmpty())
vtFld.vt = VT_BSTR;
else
vtFld.vt = VT_NULL;
//Corrected by Giles Forster 10/03/2001
vtFld.bstrVal = strValue.AllocSysString();
}
if(!strValue.IsEmpty())
vtFld.vt = VT_BSTR;
else
vtFld.vt = VT_NULL;
//Corrected by Giles Forster 10/03/2001
vtFld.bstrVal = strValue.AllocSysString();
return PutFieldValue(lpFieldName, vtFld);
}
BOOL CADORecordset::SetFieldValue(int nIndex, int nValue)
{
_variant_t vtFld;
vtFld.vt = VT_I2;
vtFld.iVal = nValue;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
}
{
_variant_t vtFld;
vtFld.vt = VT_UI4;
vtFld.ulVal = ulValue;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
return PutFieldValue(vtIndex, vtFld);
}
BOOL CADORecordset::SetFieldValue(LPCTSTR lpFieldName, unsigned long ulValue)
{
_variant_t vtFld;
vtFld.vt = VT_UI4;
vtFld.ulVal = ulValue;
return PutFieldValue(lpFieldName, vtFld);
}
BOOL CADORecordset::SetFieldValue(int nIndex, double dblValue)
{
_variant_t vtFld;
vtFld.vt = VT_R8;
vtFld.dblVal = dblValue;
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
return PutFieldValue(vtIndex, vtFld);
}
BOOL CADORecordset::SetFieldValue(LPCTSTR lpFieldName, double dblValue)
{
_variant_t vtFld;
vtFld.vt = VT_R8;
vtFld.dblVal = dblValue;
}
_variant_t vtFld;
vtFld.vt = VT_DATE;
vtFld.date = time;
return PutFieldValue(lpFieldName, vtFld);
}
}
BOOL CADORecordset::SetFieldValue(int nIndex, _variant_t vtValue)
{
_variant_t vtIndex;
vtIndex.vt = VT_I2;
vtIndex.iVal = nIndex;
}
m_nEditStatus = dbEditNone;
return TRUE;
}
}
else
{
m_varBookFind = m_pRecordset->Bookmark;
return TRUE;
}
return FALSE;
m_pRecordset->Fields->GetItem(lpFieldName)->Value = vtFld;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
{
if(m_nEditStatus == dbEditNone)
return FALSE;
try
{
m_pRecordset->Fields->GetItem(vtIndex)->Value = vtFld;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
m_pRecordset->PutFilter(strFilter);
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
m_pRecordset->PutSort(strCriteria);
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
hr = m_pRecordset->Save(lpstrXMLFile, adPersistXML);
return hr == S_OK;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
return TRUE;
}
hr = m_pRecordset->Open(lpstrXMLFile, "Provider=MSPersist;",
adOpenForwardOnly, adLockOptimistic, adCmdFile);
return hr == S_OK;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADORecordset::Execute(CADOCommand* pAdoCommand)
{
if(IsOpen())
Close();
ASSERT(!pAdoCommand->GetText().IsEmpty());
try
{
m_pConnection->CursorLocation = adUseClient;
m_pRecordset = pAdoCommand->GetCommand()->Execute(NULL, NULL,
pAdoCommand->GetType());
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
void CADORecordset::dump_com_error(_com_error &e)
{
CString ErrorStr;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
ErrorStr.Format( "CADORecordset Error\n\tCode = %08lx\n\tCode meaning =
%s\n\tSource = %s\n\tDescription = %s\n",
e.Error(), e.ErrorMessage(), (LPCSTR)bstrSource,
(LPCSTR)bstrDescription );
m_strLastError = _T("Query = " + GetQuery() + '\n' + ErrorStr);
m_dwLastError = e.Error();
#ifdef _DEBUG
AfxMessageBox( ErrorStr, MB_OK | MB_ICONERROR );
#endif
}
///////////////////////////////////////////////////////
//
// CADOCommad Class
//
CADOCommand::CADOCommand(CADODatabase* pAdoDatabase, CString strCommandText, int
nCommandType)
{
m_pCommand = NULL;
m_pCommand.CreateInstance(__uuidof(Command));
m_strCommandText = strCommandText;
m_pCommand->CommandText = m_strCommandText.AllocSysString();
m_nCommandType = nCommandType;
m_pCommand->CommandType = (CommandTypeEnum)m_nCommandType;
m_pCommand->ActiveConnection = pAdoDatabase->GetActiveConnection();
m_nRecordsAffected = 0;
}
BOOL CADOCommand::AddParameter(CADOParameter* pAdoParameter)
{
ASSERT(pAdoParameter->GetParameter() != NULL);
try
{
m_pCommand->Parameters->Append(pAdoParameter->GetParameter());
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
void CADOCommand::SetText(CString strCommandText)
{
ASSERT(!strCommandText.IsEmpty());
m_strCommandText = strCommandText;
m_pCommand->CommandText = m_strCommandText.AllocSysString();
// CADOParameter Class
//
CADOParameter::CADOParameter(int nType, long lSize, int nDirection, CString
strName)
{
m_pParameter = NULL;
m_pParameter.CreateInstance(__uuidof(Parameter));
m_strName = _T("");
m_pParameter->Direction = (ParameterDirectionEnum)nDirection;
m_strName = strName;
m_pParameter->Name = m_strName.AllocSysString();
m_pParameter->Type = (DataTypeEnum)nType;
m_pParameter->Size = lSize;
m_nType = nType;
}
BOOL CADOParameter::SetValue(int nValue)
{
_variant_t vtVal;
ASSERT(m_pParameter != NULL);
vtVal.vt = VT_I2;
vtVal.iVal = nValue;
try
{
if(m_pParameter->Size == 0)
m_pParameter->Size = sizeof(int);
m_pParameter->Value = vtVal;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::SetValue(long lValue)
{
_variant_t vtVal;
ASSERT(m_pParameter != NULL);
vtVal.vt = VT_I4;
vtVal.lVal = lValue;
try
{
if(m_pParameter->Size == 0)
m_pParameter->Size = sizeof(long);
m_pParameter->Value = vtVal;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
if(m_pParameter->Size == 0)
m_pParameter->Size = sizeof(char) * strValue.GetLength();
m_pParameter->Value = vtVal;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::SetValue(COleDateTime time)
{
_variant_t vtVal;
ASSERT(m_pParameter != NULL);
vtVal.vt = VT_DATE;
vtVal.date = time;
try
{
if(m_pParameter->Size == 0)
m_pParameter->Size = sizeof(DATE);
m_pParameter->Value = vtVal;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::SetValue(_variant_t vtValue)
{
ASSERT(m_pParameter != NULL);
try
{
if(m_pParameter->Size == 0)
m_pParameter->Size = sizeof(VARIANT);
m_pParameter->Value = vtValue;
return TRUE;
}
catch(_com_error &e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::GetValue(int& nValue)
{
_variant_t vtVal;
int nVal = 0;
try
{
vtVal = m_pParameter->Value;
switch(vtVal.vt)
{
case VT_BOOL:
nVal = vtVal.boolVal;
break;
case VT_I2:
case VT_UI1:
nVal = vtVal.iVal;
break;
case VT_INT:
nVal = vtVal.intVal;
break;
case VT_NULL:
case VT_EMPTY:
nVal = 0;
break;
default:
nVal = vtVal.iVal;
}
nValue = nVal;
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::GetValue(long& lValue)
{
_variant_t vtVal;
long lVal = 0;
try
{
vtVal = m_pParameter->Value;
if(vtVal.vt != VT_NULL && vtVal.vt != VT_EMPTY)
lVal = vtVal.lVal;
lValue = lVal;
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::GetValue(double& dbValue)
{
_variant_t vtVal;
double dblVal;
try
{
vtVal = m_pParameter->Value;
switch(vtVal.vt)
{
case VT_R4:
dblVal = vtVal.fltVal;
break;
case VT_R8:
dblVal = vtVal.dblVal;
break;
case VT_DECIMAL:
//Corrected by Jos Carlos Martnez Galn
dblVal = vtVal.decVal.Lo32;
dblVal *= (vtVal.decVal.sign == 128)? -1 : 1;
dblVal /= pow(10, vtVal.decVal.scale);
break;
case VT_UI1:
dblVal = vtVal.iVal;
break;
case VT_I2:
case VT_I4:
dblVal = vtVal.lVal;
break;
case VT_INT:
dblVal = vtVal.intVal;
break;
case VT_NULL:
case VT_EMPTY:
dblVal = 0;
break;
default:
dblVal = 0;
}
dbValue = dblVal;
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::GetValue(CString& strValue, CString strDateFormat)
{
_variant_t vtVal;
CString strVal = _T("");
try
{
vtVal = m_pParameter->Value;
switch(vtVal.vt)
{
case VT_R4:
strVal = DblToStr(vtVal.fltVal);
break;
case VT_R8:
strVal = DblToStr(vtVal.dblVal);
break;
case VT_BSTR:
strVal = vtVal.bstrVal;
break;
case VT_I2:
case VT_UI1:
strVal = IntToStr(vtVal.iVal);
break;
case VT_INT:
strVal = IntToStr(vtVal.intVal);
break;
case VT_I4:
strVal = LongToStr(vtVal.lVal);
break;
case VT_DECIMAL:
{
//Corrected by Jos Carlos Martnez Galn
double val = vtVal.decVal.Lo32;
val *= (vtVal.decVal.sign == 128)? -1 : 1;
val /= pow(10, vtVal.decVal.scale);
strVal = DblToStr(val);
}
break;
case VT_DATE:
{
COleDateTime dt(vtVal);
if(strDateFormat.IsEmpty())
strDateFormat = _T("%Y-%m-%d %H:%M:%S");
strVal = dt.Format(strDateFormat);
}
break;
case VT_EMPTY:
case VT_NULL:
strVal.Empty();
break;
default:
strVal.Empty();
return FALSE;
}
strValue = strVal;
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
vtVal = m_pParameter->Value;
switch(vtVal.vt)
{
case VT_DATE:
{
COleDateTime dt(vtVal);
time = dt;
}
break;
case VT_EMPTY:
case VT_NULL:
time.SetStatus(COleDateTime::null);
break;
default:
return FALSE;
}
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
BOOL CADOParameter::GetValue(_variant_t& vtValue)
{
try
{
vtValue = m_pParameter->Value;
return TRUE;
}
catch(_com_error& e)
{
dump_com_error(e);
return FALSE;
}
}
void CADOParameter::dump_com_error(_com_error &e)
{
CString ErrorStr;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
ErrorStr.Format( "CADOParameter Error\n\tCode = %08lx\n\tCode meaning =
%s\n\tSource = %s\n\tDescription = %s\n",
e.Error(), e.ErrorMessage(), (LPCSTR)bstrSource,
(LPCSTR)bstrDescription );
m_strLastError = ErrorStr;
m_dwLastError = e.Error();
#ifdef _DEBUG
AfxMessageBox(ErrorStr, MB_OK | MB_ICONERROR);
#endif
}
IMPLEMENT_DYNAMIC(CADOException, CException)
CADOException::CADOException(int nCause, CString strErrorString) :
CException(TRUE)
{
m_nCause = nCause;
m_strErrorString = strErrorString;
}
CADOException::~CADOException()
{
}
int CADOException::GetError(int nADOError)
{
switch (nADOError)
{
case noError:
return CADOException::noError;
break;
default:
return CADOException::Unknown;
}
}
void AfxThrowADOException(int nADOError, CString strErrorString)
{
throw new CADOException(nADOError, strErrorString);
}
DrawPattern(RetrievePattern('*'));
// draw each character in the message
for (i=0;i<m_csMessage.GetLength();i++)
DrawPattern(RetrievePattern(m_csMessage.GetAt(i)));
// draw stop character, also an asterisk
DrawPattern(RetrievePattern('*'));
}
return;
////////////////////////////////////////////////////////////////////////////////
////
//
//
Name:
//
DrawPattern()
//
//
Description:
//
draws the passed character pattern at the end of the barcode
//
//
Arguments:
//
CString
csPattern
the bar pattern to draw
//
//
Return:
//
void
//
//
Called by:
//
CRationalCodabar::DrawBitmap()
//
////////////////////////////////////////////////////////////////////////////////
////
void CCode39::DrawPattern( CString csPattern )
{
int
i,nXPixel,nYPixel,nTempWidth;
CDC
oDC;
// attach to the device context
oDC.Attach(m_hDC);
// initialize X pixel value
nXPixel = m_nStartingXPixel;
for (i=0;i<csPattern.GetLength();i++)
{
// decide if narrow or wide bar
if (csPattern.GetAt(i)=='n')
nTempWidth = m_nNarrowBarPixelWidth;
else
nTempWidth = m_nWideBarPixelWidth;
// X value for loop
for
(nXPixel=m_nStartingXPixel;nXPixel<m_nStartingXPixel+nTempWidth;nXPixel++)
{
// Y value for loop
for
(nYPixel=m_nStartingYPixel;nYPixel<m_nStartingYPixel+m_nPixelHeight;nYPixel++)
{
// if this is a bar
if (i%2==0)
oDC.SetPixelV(nXPixel,nYPixel,COLORBLACK);
else
}
oDC.SetPixelV(nXPixel,nYPixel,COLORWHITE);
return;
////////////////////////////////////////////////////////////////////////////////
////
//
//
Name:
//
RetrievePattern()
//
//
Description:
//
retrieves the bar pattern for a given character
//
//
Arguments:
//
char cInputCharacter
the input character to get the bar
pattern for
//
//
Return:
//
CString
the bar pattern for the input character
//
//
Called by:
//
CRationalCodabar::DrawBitmap()
//
////////////////////////////////////////////////////////////////////////////////
////
CString CCode39::RetrievePattern(char c)
{
CString
csCharPattern;
switch (c)
{
case '1':
csCharPattern
break;
case '2':
csCharPattern
break;
case '3':
csCharPattern
break;
case '4':
csCharPattern
break;
case '5':
csCharPattern
break;
case '6':
csCharPattern
break;
= "wnnwnnnnwn";
= "nnwwnnnnwn";
= "wnwwnnnnnn";
= "nnnwwnnnwn";
= "wnnwwnnnnn";
= "nnwwwnnnnn";
case '7':
csCharPattern
break;
case '8':
csCharPattern
break;
case '9':
csCharPattern
break;
case '0':
csCharPattern
break;
case 'A':
csCharPattern
break;
case 'B':
csCharPattern
break;
case 'C':
csCharPattern
break;
case 'D':
csCharPattern
break;
case 'E':
csCharPattern
break;
case 'F':
csCharPattern
break;
case 'G':
csCharPattern
break;
case 'H':
csCharPattern
break;
case 'I':
csCharPattern
break;
case 'J':
csCharPattern
break;
case 'K':
csCharPattern
break;
case 'L':
csCharPattern
break;
case 'M':
csCharPattern
break;
case 'N':
csCharPattern
break;
case 'O':
csCharPattern
break;
case 'P':
csCharPattern
break;
case 'Q':
csCharPattern
= "nnnwnnwnwn";
= "wnnwnnwnnn";
= "nnwwnnwnnn";
= "nnnwwnwnnn";
= "wnnnnwnnwn";
= "nnwnnwnnwn";
= "wnwnnwnnnn";
= "nnnnwwnnwn";
= "wnnnwwnnnn";
= "nnwnwwnnnn";
= "nnnnnwwnwn";
= "wnnnnwwnnn";
= "nnwnnwwnnn";
= "nnnnwwwnnn";
= "wnnnnnnwwn";
= "nnwnnnnwwn";
= "wnwnnnnwnn";
= "nnnnwnnwwn";
= "wnnnwnnwnn";
= "nnwnwnnwnn";
= "nnnnnnwwwn";
break;
case 'R':
csCharPattern
break;
case 'S':
csCharPattern
break;
case 'T':
csCharPattern
break;
case 'U':
csCharPattern
break;
case 'V':
csCharPattern
break;
case 'W':
csCharPattern
break;
case 'X':
csCharPattern
break;
case 'Y':
csCharPattern
break;
case 'Z':
csCharPattern
break;
case '-':
csCharPattern
break;
case '.':
csCharPattern
break;
case ' ':
csCharPattern
break;
case '*':
csCharPattern
break;
case '$':
csCharPattern
break;
case '/':
csCharPattern
break;
case '+':
csCharPattern
break;
case '%':
csCharPattern
break;
= "wnnnnnwwnn";
= "nnwnnnwwnn";
= "nnnnwnwwnn";
= "wwnnnnnnwn";
= "nwwnnnnnwn";
= "wwwnnnnnnn";
= "nwnnwnnnwn";
= "wwnnwnnnnn";
= "nwwnwnnnnn";
= "nwnnnnwnwn";
= "wwnnnnwnnn";
= "nwwnnnwnnn";
= "nwnnwnwnnn";
= "nwnwnwnnnn";
= "nwnwnnnwnn";
= "nwnnnwnwnn";
= "nnnwnwnwnn";
return csCharPattern;
}
////////////////////////////////////////////////////////////////////////////////
////
//
//
Name:
//
BitmapToClipboard()
//
//
Description:
//
puts the specified bitmap on the clipboard
//
//
Arguments:
//
none
//
//
Return:
//
void
//
//
Called by:
//
public class interface - called by users of the class
//
////////////////////////////////////////////////////////////////////////////////
////
void CCode39::BitmapToClipboard()
{
CDC
CBitmap
memDC;
oBitmap;
memDC.CreateCompatibleDC(NULL);
m_hDC = memDC.GetSafeHdc();
// create compatible, correctly sized bitmap
oBitmap.CreateCompatibleBitmap(&memDC,m_nFinalBarcodePixelWidth,m_nPixelHeight);
// select our bitmap into the device context
CBitmap * oldbm = memDC.SelectObject(&oBitmap);
// turn area white - stock black bitmap is selected
memDC.BitBlt(0,0,m_nFinalBarcodePixelWidth,m_nPixelHeight,NULL,0,0,WHITENESS);
// draw bitmap into memory device context
DrawBitmap();
// put bitmap on clipboard
::OpenClipboard(NULL);
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, oBitmap.m_hObject);
::CloseClipboard();
//
deselect object out of device context
memDC.SelectObject(oldbm);
// make sure bitmap not deleted with CBitmap object
oBitmap.Detach();
}
return;
Il file di header :
// Code39.h: interface for the CCode39 class.
//
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CODE39_H__6FE17747_EADF_4E89_9DCF_7688B04897BC__INCLUDED_)
#define AFX_CODE39_H__6FE17747_EADF_4E89_9DCF_7688B04897BC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Barcode.h"
class CCode39 : public CBarcode
{
public:
void BitmapToClipboard();
void DrawBitmap();
CCode39();
virtual ~CCode39();
private:
void DrawPattern(CString csPattern);
CString
RetrievePattern( char c );
};
#endif // !
defined(AFX_CODE39_H__6FE17747_EADF_4E89_9DCF_7688B04897BC__INCLUDED_)