Numpy vs OpenCV aritmetika
Mind a Numpy, mind az OpenCV lehetőséget biztosít képek közötti aritmetikai és logikai műveletekre, mint például az összeadás, kivonás, szorzás. Ha az egyik kép helyett skalár értéket adunk meg, akkor minden képpontra egyenként fogja a skalárral való műveletet elvégezni.
Fontos! Nagy különbség van a Numpy és az OpenCV aritmetika között!
- Numpy esetén alul- vagy túlcsorduláskor körkörös az értékváltás az értéktartományon belül. Például np.uint8 típus esetén 255 + 1 = 0.
- Az OpenCV úgynevezett szaturált aritmetikát használ: túlcsorduláskor a maximális, alulcsorduláskor a minimális értéket adja! Az előző példa szerint itt 255 + 1 = 255.
Képmátrixok esetén ez utóbbi természetesebb látványt ad, emiatt célszerűbb az OpenCV függvények használata, még ha a Numpy szintaktikailag egyszerűbb is lenne.
Próbáljuk ki az alábbiakat:
nparr = np.array([0, 50, 100, 150, 200, 250], dtype=np.uint8)
print(nparr)
print(nparr + 100)
print(nparr - 100)
print(cv2.add(nparr, 100))
print(cv2.add(nparr, -100))
Az eredmények:
[ 0 50 100 150 200 250]
[100 150 200 250 44 94]
[156 206 0 50 100 150]
[[100]
[150]
[200]
[250]
[255]
[255]]
[[ 0]
[ 0]
[ 0]
[ 50]
[100]
[150]]
Megállapítások:
- A Numpy a túlcsordulást és az alulcsordulást másként kezeli, mint az OpenCV!
- Az OpenCV aritmetika Numpy-ban elérhető eredménye más felépítésű (shape), mint a Numpy összeadásé.
Megjegyzések:
- A Numpy esetén is van lehetőség az alul- és túlcsordulások OpenCV-hez hasonló kezelésére az np.clip(arr, min, max) függvény használatával. Az arr tömb min értéknél kisebb elemei min-t, max-nál nagyobb értékű elemei pedig a max értékét kapják. Ez viszont csak akkor működik megfelelően, ha a képünk típusa tudja reprezentálni az alul- és túlcsorduló értékeket, vagyis leginkább egy kisebb értékkészletű típusba történő visszaalakítás előtt lehet érdemes használni.
- Ehhez viszont olyan típus reprezentáció kell, amely képes a nagyobb értékkészlet tárolására, vagyis használata nehézkes, előzetes és utólagos típuskonverziókat igényel.