Sintetični eksperiment

Opis sintetičnega eksperimenta in spoznavanje metod DIC.

V tem poglavju smo z vrsto sintetičnih preizkusov z znanimi rezultati preverjali in spoznavali delovanje optičnih metdo za izračun premikov.

Gradientna metoda na primeru premaknjenega sinusa

V programskem okolju Python smo najprej testirali delovanje gradientne metode. Kot podatke smo generirali sinusno krivuljo, ki predstavlja spreminjanje sivine skozi sliko. Sinusno krivuljo smo premikali z znanimi pomiki, nato pa s pomočjo gradientne metode poskušali te premike tudi izračunati. Največjo pozornost smo posvetili izboljšavi podatkov z interpolacijo ter težavam pri uporabi gradientne metode.

Programu določimo parametre, ki določajo kako dolg bo posnetek in za koliko v vsaki naslednji sličici sinus premaknemo v desno. Test smo izvajali s premikanjem s konstantno hitrostjo. Pomembna sta še dva parametra: širina območja(kako široko je opazovano območje) in koliko pikslov imamo na voljo za zajem (px). Izberemo lahko tudi število period sinusa na tem območju. Parametri, ki jih izbiramo zbrani v preglednici:

Pregled parametrov za sintetični preračun gradientne metode.

Koda za generiranje in premikanje sinusno spreminjajoče intenzitete:

#parametri za generiranje sinusa
px = 10 
št_period = 1
širina_območja = 10 #[mm]
dolžina = 0.1 #[s]
fps = 100

število_sličic = int((dolžina*fps))
x, h = np.linspace(0,širina_območja,px, retstep=True)
t = np.linspace(0, dolžina, število_sličic-1)


#premikanje sinusa
pravi_pomik = 0.2 #[mm]
I = np.zeros([px, število_sličic])
for i in range(0, število_sličic):
    I[:,i] += (np.sin(2*np.pi*(x-i*pravi_pomik)/(širina_območja/št_period))+1)/2
Sintetični premik sinusne krivulje.

Nato po enačbi optičnega toka izračunamo premik med zaporednimi sličicami za vsak piksel posebej:

#delta I
delta_I = np.zeros([px,število_sličic-1])
for i in range(0,število_sličic-1):
        delta_I[:,i] += I[:,i+1] - I[:,i]
        

#izračun pomikov   
odvod_x, odvod_t = np.gradient(I,h, edge_order=2)
delta_x = - delta_I / odvod_x[:,:-1]
povprečje = sum(delta_x[:,0]) / len(delta_x[:,0])
napaka = abs(pravi_pomik-povprečje)
relativno = napaka / pravi_pomik * 100
print(f'Napaka pomika iz vhodnih podatkov {napaka:.6f}mm.')
print(f'Relativna napaka pomika iz vhodnih podatkov {relativno:.2f}%.\n')

Podatke nato interpoliramo in navidezno dodamo točke na podlagi katerih lahko izvedemo izračun v več točkah:

Prikaz interpoliranih podatkov.

Če predpostavimo, da je intenziteta posledica objekta na sliki, ter da je objekt nedeformabilen, lahko sklepamo, da je gibanje enako za vse piksle. Zato lahko za točnejši premik uporabimo povprečen premik vseh pikslov. Ker jih imamo v interpolarnem primeru znatno več, je tudi povprečje precej točnejše.

(a) Prikaz težave na vhodnih podatkih in (b) interpoliranih podatkih.

Na zgornji sliki lahko opazimo, da v točki, kjer je sinus v prevoju, pride do velikih napak pri izračunu. To je tudi smiselno, saj gradientna metoda za svoje delovanje potrebuje gradient v smeri premika, v našem primeru je to v desno, oziroma vodoravno. V točki v prevoju, kjer ima sinus svoj maksimum, pa je gradient enak 0.

Ta težava je še toliko bolj izrazita pri interpoliranih podatkih, saj je gradient še bliže 0. Najbolj pride do izraza, če prikažemo izračunane pomike v določenem časovnem trenutku za vse piksle. Na grafu je prikazano še spreminjanje intenzitete po x in njen gradient.

Iterativni izračun na premaknjenem sinusu - Lucas-Kanade

Izboljšava natančnosti z iteracijami

Tudi drugi del sintetičnega preizkusa smo opravljali na premaknjenem sinusu. Prav tako izberemo vse zgoraj opisane parametre za generiranje in premikanje sinusnega spreminjanja intenzitete svetlobe. Od prvega izračuna se razlikuje v tem, da je ta način iterativen. Deluje na način, da izračuna premik, nato pa prvo sličico premakne za izračunan pomik. To ponavljamo dokler ne dosežemo želene natančnosti oz. dosežemo maksimuma števila iteracij.

Izberemo si piksel in sličici, ki nas zanima. Prikaz dveh zaporednih sličic in točke izračuna z enakimi parametri kot pri prejšnjem poskusu.

Prikaz točke izračuna pomika.

Tokrat si poleg vseh parametrov za generiranje naštetih v prvem sinteičnem eksperimentu, izberemo še točko preračuna, sličico preračuna in število željenih iteracij. Iteriranje nam znatno izboljša natančnost preračuna. Izboljševanje izračuna med vsako zaporedno iteracijo je prikazano na spodnjem v tabeli in na grafu.

Prikaz iteracij na grafu.

Izračun večjih pomikov s pomočjo iteracij

Prednost iterativnega preračuna pomika pa je tudi, da lahko natančno računamo tudi večje premike.

V našem primeru imamo ponavlajoč sinusni vzorec, zato moramo paziti na problem korespondence opisan v poglajvju o problemih DIC. Torej premik ne sme biti večji od polovice periode sinusa. Za prikaz smo izbrali pomik za 3mm, kjer je merilo 1px=1mm.

Prikaz točke izračuna pomika.

Tudi pri tem primeru koda deluje tako, da is ročno izberemo točko preračuna, časovni trenutek preračuna (oz. sličico preračuna) in število želenih iteracij.

Prikaz iteracij pri nadpikselnem pomiku.

Kot lahko opazimo iz grafa in tabele, razultati prve iteracije niso uporabni, saj je napaka pomika kar 72%. Zato je pri večjih pomikih nujna uporaba poravnave sličic po metodi Lucas-Kanade. Relativna napaka hitro pade in po peti iteraciji znaša le 0,05%.

Last updated