Skip navigation

Numpy tömb szeletelés

Numpy részkép kivágása és visszamásolása

A Numpy lehetőséget ad a mátrixok szeletelésére, vagyis indextartományokkal megadott részeinek elérésére. A szeletelés eredménye közvetlenül felhasználható, vagy új változóban eltárolható.

Fontos, hogy ez a részmátrix továbbra is az eredeti mátrixra hivatkozik, változtatása az eredetin is megjelenik! Ha tényleges másolatot szeretnék, akkor használjuk a copy() függvényt!

Az indextartományok megadásánál az adott dimenzióra vonatkozó kezdő és záró koordinátát kell megadni, kettősponttal elválasztva. Fontos! A záró koordináta érték már nem vesz részt a kivágásban! A következő példa egy 90x90 méretű eredményt ad.

cropped = image[82:172, 396:486]

cropped_copy = image[82:172, 396:486].copy()

Az intervallum megadásakor (a kettőspont előtt/után) a kezdő és/vagy a záró koordináta érték elhagyható. Ekkor az adott dimenzió szerinti minimális, illetve maximális koordináta értéket veszi a rendszer. Például az alábbi értékadással ki tudjuk nullázni a cropped mátrix minden elemét.

cropped[:, :, :] = 0

Jobbról balra haladva a teljes dimenziót felhasználó indexeket elhagyhatjuk, az első kivételével. Vagyis:

  • A cropped[:, :] = 0 ugyanezt csinálja.
  • A cropped[:] = 0 is.
  • A cropped[] = 0 szintaktikai hiba.
  • A cropped = 0 pedig 0 skalár értéket adja a változónak, vagyis megszűnik a képmátrix!

Egy kisebb mátrixot be tudunk másolni egy nagyobba. A nagyobbnál indextartományokat kell megadni. (A kisebbnél is lehet.) A két (rész)mátrix méretnek meg kell egyeznie egymással! Ez a másolás ténylegesen megtörténik, ekkor nincs referencia szintű hivatkozás ugyanarra a területre, nincs szükség a copy() függvény hívására.

image[10:100, 20:110] = cropped

02_02_crop.py

import cv2

image = cv2.imread('GolyoAlszik_rs.jpg')
# Képkivágás; sor és oszlop tartomány megadása
cropped = image[82:172, 396:486]

# Kivágott rész képbe másolása, új helyre
image[10:100, 20:110] = cropped


cv2.imshow('image', image)
cv2.imshow('cropped', cropped)

cv2.waitKey(0)

Futási eredmények:

cropped:

image a képrészlet bemásolás után:

További szeletelési példák

Az előző példaprogramot felhasználva vizsgáljuk meg, mit okoznak az alábbi utasítások!

A >> operátor a bitminta léptetést végzi megadott számmal jobbra, ami az esetünkben a 2-val való osztást jelenti.

image[200:, :] = [0, 255, 255]
image[:, 300:, 2] = 0
image[100:120] = 255
image[:(image.shape[1] >> 1) - 50:(image.shape[1] >> 1) + 50] = 220

Másoljuk az utasításokat közvetlenül a cv2.imshow() függvények elé, megtartva a korábbi utasításokat!

Figyeljük meg a kivágott cropped képmátrix tartalmát is! Miért így jelenik meg? Miért különbözik az image képmátrixba előzőleg bemásolt tartalmától?

A megoldások leírása a jegyzet végén olvasható. (Ellenőrzésre, vagy végső elkeseredésben olvassuk el.)


Feladatok

Vonalrajzolás a for ciklus kiváltásával

Az előző alfejezet példáját módosítsuk úgy, hogy a kattintás helyének sorában ne for ciklussal, hanem mátrix szeleteléssel módosítsuk a színértékeket!

Rajzoljunk függőleges vonalat is!

Oldjuk meg, hogy az egér mozgására reagálva mindig az aktuális pozícióhoz rajzolódjon vízszintes és függőleges vonal! (Szálkereszt rajzolás.) Ne felejtsük el az eredeti képet eltárolni, és minden új rajzolás előtt visszamásolni.

Téglalap alakú interaktív területkijelölés

Készítsünk olyan programot, amely két bal egérgomb kattintással (első kattintás: első sarok, második kattintás: átellenes sarok, harmadik kattintás: előző törlése, új kijelölés első sarokpontja, stb.) egy téglalapot határoz meg a képen, kivágja a képtartalmat, és új ablakban megjeleníti!

Az eredeti képre zöld színnel rajzoljuk be a kijelölt téglalapot!

Színértékek módosítása egy területen belül

Színes kép esetén egy megadott téglalap alakú képtartományban a vörös csatorna értékeit állítsuk 192-re! Utána a másik két csatorna értékét nullázzuk ki ugyanezen a területen!