In [1]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib

Képfeldolgozás

A feladatok elvégzését igazolandó jegyzőkönyvében tisztán naplózza munkáját, beleértve eljárásainak elvét, implementációit valamint eredményeit. Ne felejtse el jegyzőkönyvéhet csatolni, azaz a jegyzőkönyvet tartalmazó munkakönyvtárba másolni a feladatok kidolgozására elkészített bemeneti képállományokat is.

Ismerkedjen meg a mérési összeállítással.

1. feladat: Műveletek állóképeken

A feladatok elvégzéséhez használja a PC-hez kötött webkamerák egyikét. Amelyik kameránál erre lehetőség van, az előtét lencse segítségével törekedjen éles képet rögzíteni.

A kép rögzítéséhez használhatja a vlc programot, amelyben a Media emnüből nyíló Open capture device ablak segítségével élőképet hozhat elő. A megfelelő beállítás elvégeztével a Video menűből a Take Snapshot hívásával pillanatfelvétel készül, amit a felhasználói home könyvtárban talál meg vlcsnap-timestamp.png formátumban, ahol a fájlnévben a timestamp a dátumot és a másodperc pontos pillanatot kódolja. A feldolgozandó fájlt töltse fel a jegyzőkönyv mellé!

1.1. Egykép műveletek

Egy tetszőlegesen kiválasztott kamera segítségével készítsen színes képet, a terem egy olyan nézetéről, ahol egyszerre jól látszanak az ablakokat sötétítő vászoncsíkok és a munkaállomások polcai is.

A következő feladatokat végezze el a képen:

  • Alakítsa ás a színes képet szürke skálájúra, amelyhez segítséget nyújt a wikipedia szócikke
    • Vajon az eredeti színes kép színcsatornái lineárisak vagy $\Gamma$-tömörítettek voltak?
  • Szerkessze meg, ábrázolja és elemezze a kép intenzitás hisztogramját,
    • Tudja azonosítani az eredeti tipikus színekhez tartozó csúcsokat?
  • Adjon meg rendre olyan kernelmátrixokat, amelyek segítségével a képen található vizszintes élek, függőleges élek vagy átlós élek emelődnek ki.
  • Mire érdemes odafigyelni a kép kicsinyítésekor illetve nagyítsásakor?
In [2]:
kep1 = imread("ablakok.png")

kep2 = kep1[:, :, 0]*0.2126 + kep1[:, :, 1]*0.7152 + kep1[:, :, 2]*0.0722
imsave(arr=kep2, fname="ablakok_sz.png")
In [3]:
# ábrázolás
title('eredeti', size=15)
imshow(kep1)
Out[3]:
<matplotlib.image.AxesImage at 0x7f749d0d6a90>
In [4]:
title("szürkeárnyalatos", size=15)
imshow(kep2, cmap="gray")
Out[4]:
<matplotlib.image.AxesImage at 0x7f749d07fac8>
In [5]:
n, bins, patches= hist(kep2.flatten(), 256)
title("Intenzitás hisztogram", size=15)
xlabel("intenzitás")
ylabel("előfordulás")
Out[5]:
Text(0,0.5,'előfordulás')

Három csúcs különül el élesen a hisztogrammon (látszik még egy, de az nem különül el nagyon a középső magastól). A 0.1 körüli, aminek alacsony az intenzitása, valószínűleg a fekete színhez tartozik (gépház, monitor ...).

A másik szín amből sok van a képen az a fal, illetve műanyag izé színe, ami a valóságban persze fehér, de a képen ilyen sárgás szerű. Mivel a képen ebből nagyon sok van, valószínűleg ehhez tartozik a legnagyobb csúcs 0.55 körül.

A harmadik csúcs 0.4 körül már kisebb, abból a képen nincs annyira sok, ez valószínűleg azoknak a fehér színű felületeknek felel meg, amikre árnyék vetül, így a kamera más színűnek érzékeli őket

In [6]:
from scipy import ndimage
In [7]:
kx = array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
ky = array([[1, 0, -1], [1, 0, -1], [1, 0, -1]])
kxy = array([[2, 1, 0], [1, 0, -1], [0, -1, -2]])
print("A vízszintes élek kiemeléséhez:\n", kx, "\n")
print("A függőleges élek kiemeléséhez:\n", ky, "\n")
print("A ferde élek kiemeléséhez:\n", kxy, "\n")
A vízszintes élek kiemeléséhez:
 [[ 1  1  1]
 [ 0  0  0]
 [-1 -1 -1]] 

A függőleges élek kiemeléséhez:
 [[ 1  0 -1]
 [ 1  0 -1]
 [ 1  0 -1]] 

A ferde élek kiemeléséhez:
 [[ 2  1  0]
 [ 1  0 -1]
 [ 0 -1 -2]] 

In [8]:
imshow(ndimage.convolve(kep2, kx), cmap="gray")
title("A vízszintes élek kiemelve", size=15)
Out[8]:
Text(0.5,1,'A vízszintes élek kiemelve')
In [9]:
imshow(ndimage.convolve(kep2, ky), cmap="gray")
title("A függőleges élek kiemelve", size=15)
Out[9]:
Text(0.5,1,'A függőleges élek kiemelve')
In [10]:
imshow(ndimage.convolve(kep2, kxy), cmap="gray")
title("A ferde élek kiemelve", size=15)
Out[10]:
Text(0.5,1,'A ferde élek kiemelve')

A kép kicsinyítésekor és nagyításakor arra érdemes odafigyelni, hogy a kép kisebb illetve nagyobb legyen, és továbbra is ugyanúgy nézzen ki. Továbbá arra is érdemes odafigyelni, hogy miközben kicsinyítünk egy képet ne lopják ki a zsebünkből a bankkártyánkat, mert ha ez megtörténik, utána egy csomót bosszankodhatunk még amiatt is.

1.2. Többkép műveletek

Készítsen időben több felvételt a kiválasztott kamera segítségével úgy, hogy a látómezőben egy tárgy (lehet az arca vagy az egér) rendre kicsit elmozdul.

  • A különbségi képek segítségével próbálja megbecsülni, hol történt a látómezőben a változás.
  • Számolja ki a képpárok között a korrelációt.
    • Mit vár a korrelációra, ha az időben egyre távolabbi képkockákat vet egybe?
In [11]:
rago1 = imread("rago1.png")
rago2 = imread("rago2.png")
rago3 = imread("rago3.png")
rago4 = imread("rago4.png")
In [12]:
figsize(10, 6)
subplots_adjust(hspace=0.4)
subplot(2, 2, 1)
imshow(rago1)
title("Rágó 1")
subplot(2, 2, 2)
imshow(rago2)
title("Rágó 2")
subplot(2, 2, 3)
imshow(rago3)
title("Rágó 3")
subplot(2, 2, 4)
imshow(rago4)
title("Rágó 4")
print("FIGYELEM! A képek termékmegjelenítést tartalmazhatnak")
FIGYELEM! A képek termékmegjelenítést tartalmazhatnak
In [13]:
suptitle("Különbségi képek", size=15)
subplot(1, 3, 1)
imshow(rago2 - rago1)
title("Rágó2 - Rágó1")
subplot(1, 3, 2)
imshow(rago3 - rago2)
title("Rágó3 - Rágó2")
subplot(1, 3, 3)
imshow(rago4 - rago3)
title("Rágó4 - Rágó3")
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Out[13]:
Text(0.5,1,'Rágó4 - Rágó3')
In [26]:
from scipy.stats.stats import pearsonr
In [44]:
print("Korrelációk szomszédos képkockák között:")
print("\t1-2:", pearsonr(rago1.flatten(), rago2.flatten())[0])
print("\t2-3:", pearsonr(rago2.flatten(), rago3.flatten())[0])
print("\t3-4:", pearsonr(rago3.flatten(), rago4.flatten())[0], "\n")

print("Korrelációk 2 távolsgú képkockák között:")
print("\t1-3:", pearsonr(rago1.flatten(), rago3.flatten())[0])
print("\t2-4:", pearsonr(rago2.flatten(), rago4.flatten())[0], "\n")

print("Korrelációk 3  távolságú képkockák között:")
print("\t1-4:", pearsonr(rago1.flatten(), rago4.flatten())[0], "\n")

print("Látható, hogy a távolabbi képkockák között valóban egyre kisebb a korreláció")
Korrelációk szomszédos képkockák között:
	1-2: 0.6650978
	2-3: 0.64407384
	3-4: 0.67007285 

Korrelációk 2 távolsgú képkockák között:
	1-3: 0.5294269
	2-4: 0.5607334 

Korrelációk 3  távolságú képkockák között:
	1-4: 0.5266086 

Látható, hogy a távolabbi képkockák között valóban egyre kisebb a korreláció

2. feladat: Kamerakalibráció

2.1. A perspektíva vizsgálata

A mérés helyszínén adott egy pepita rács. A kísérlet során az eddig használt kamerával készítsen erről a rácsról felvételeket úgy, hogy a kamerától különböző távolságokra helyezi le azt. Ügyeljen arra, hogy lehetőleg mindig a legnagyobb felületet lássa a kamera, azaz essen a kamera optikai tengelye és a rács közepén átmenő normális (a lehetőségek szerint) egybe. A képeket elemezve minden felvételen határozza meg a rács látszó méreteit (karakterisztikus távolság). Mit vár és mit tapasztal, ha ezeket a rácsot jellemző karakterisztikus távolságokat megvizsgálja a rács-kamera távolság függvényében?

A tapasztalatairől készítsen ábrát is!

Mérés távolság [cm] karakterisztikus távolság [px]
1. 08 45
2. 16 29
3. 24 17
4. 32 14
5. 40 11
6. 48 7
In [14]:
pepita = [imread("pepita" + str(i) + ".png") for i in range(8, 49, 8)]
figsize(15, 8)
for i in range(6):
    subplot(1, 6, i + 1)
    imshow(pepita[i])
    title(str((i + 1) * 8) + " cm")
In [27]:
from scipy.optimize import curve_fit
def linear(x, a0, a1):
    return a0 + a1 * x
In [34]:
figsize(10, 6)
tavolsag = array([8, 16, 24, 32, 40, 48])
karakter = array([45, 29, 17, 14, 11, 7])

eh, hiba = curve_fit(linear, tavolsag[:5], 1/karakter[:5])
x = linspace(8, 48, 100)
y = linear(x, eh[0], eh[1])
plot(x, y, label="adatokra illesztett egyenes")

plot(tavolsag, 1 / karakter, "o", label="mért pontok")
xlabel("távolság [cm]")
ylabel("1 / karakterisztikus távolság [1 / pixel]")
title("A karakterisztikus távolság a kamera távolságának függvényében", size=15)
legend()
Out[34]:
<matplotlib.legend.Legend at 0x7fddbb7c6940>
In [37]:
print("az egyenes együtthatói:", eh)
print("a hibamátrix:", hiba)
az egyenes együtthatói: [0.00327737 0.00217899]
a hibamátrix: [[ 1.06137215e-05 -3.61831429e-07]
 [-3.61831429e-07  1.50763095e-08]]

Ha $t$ a tárgytávolság, $k$ a képtávolság, $s$ a rácsok nagysága, $p$ pedig a képen a rácsok nagysága (ami arányos a karakterisztikus távolsággal), akkor a mérési leírásban leírt hasonló háromszöges mese miatt azt várjuk, hogy $$ \frac{k}{t} = \frac{p}{s} $$ Ez alapján $p \sim \frac{1}{t}$, vagyis a karakterisztikus távolság fordítottan arányos a kamera és a tárgy távolságával. A fenti ábrán a karakterisztikus távolság reciprokát ábrázoltam a távolság függvényében, és valóban egy egyenesre esnek (kivéve az utolsó pont, de ott amúgy is baromi nagy a hiba). Az egyenes egyenlete az illesztés alapján: $y = a_0 + a_1 \cdot x$, ahol $a_0 = 0,0033 \pm 0,0033$ és $a_1 = 0,00218 \pm 0,00012$

2.2. A kamera leképezési mátrixának meghatározása

A munkaterületen Salgo elemektől koordinátarendszert építettünk. Ezen fehér markerek találhatóak, melyekről készítsen felvételt a kamera segítségével. Mérje meg mérőszalag segítségével a markerek térbeli helyét és foglalja táblázatba. Határozza meg ugyanezeknek a markereknek a helyét a mintaképen és vezesse azok képkkordinátáit is fel a táblázat megfelelő helyére. A jegyzetben tárgyalt egyenletek segítségével határozza meg a kamera leképezési mátrixát!

Ellenőrzésképpen ábrázolja a 3D térben feszülő koordinátatengelyeket a képen.

Marker x [cm] y [cm] z [cm] v [px] w [px]
1. . . . . .
2. . . . . .
3. . . . . .
4. . . . . .
5. . . . . .
6. . . . . .

A 2.1. feladat ismeretében ki tudja komponálni a leképező mátrixkból a perspektíváért felelős tényezőt?

A méréssel kapcsolatos észrevételek

Kitölteni nem kötelező:

  • Itt kérjük feltűntetni, hogy mennyi idő volt szükséges a feladatok elvégzéséhez.
  • Itt lehet javaslatot tenni a méréssel kapcsolatban.
  • A méréssel kapcsolatban felmerült további ötletek.

Nem volt egy macerás mérés, de itt sincs elég idő befejezni, főleg ha minőségi munkát arakok végezni (most azért eléggé siettem). Talán az első feladatban lehetne kicsit kevesebb feladat.

Ezen kívül, egy csomó olyan dolgot kéne tudni, amit nekünk nem lenne muszáj ismernünk. Pl.: A $Gamma$-tömörítésről életemben nem hallottam, a kernel mátrixokról csak azért tudom mik, mert tavaly jártam egy specire, ahol szóba kerültek, a képek kicsinyítéséről és nagyításáról még mindig nem tudom mit kéne írni valamint a képek korrelációjánál sincs leírva, hogy pontosan mit várnak. Ezeket vagy ki kéne venni a feladatok közül vagy a mérés leírásban (vagy talán itt) leírni a lényegüket.

Egyébiránt az egész mérésre jellemző volt, ami a korábbiakra nem annyira, hogy kevéssé vannak pontosan leírva, hogy mi a feladat. Mindegyik részfeladatba sokmindent belegondolhatok és sokmindent nem. Remélem az osztályzás is ezt figyelembe vevő lesz.