Használja ezt a technikát, hogy okos matematikát alkalmazzon videóira, és csökkentse a remegést.
A videostabilizálás egy olyan technika, amely csökkenti a nem kívánt mozgást és remegést a videofelvételeken. A kézi fényképezés, a vibráció és a mozgás bizonytalan kameramozgást okozhat. A videostabilizálás simább megjelenésű videót eredményez.
A videostabilizálás elsődleges célja a kamera mozgásának becslése az egymást követő képkockák között. A folyamat ezután megfelelő átalakításokat alkalmazhat a keretek igazításához. Ez minimálisra csökkenti az észlelt mozgást.
Környezetének beállítása
Kezdje ezzel virtuális környezet létrehozása hogy a program futtatásához telepített csomagok ne ütközzenek a meglévőkkel. Ezután futtassa ezt a terminálparancsot a szükséges könyvtárak telepítéséhez:
pip install opencv-python numpy
Ez a parancs telepíti a NumPy és az OpenCV könyvtárakat. A NumPy eszközöket biztosít a numerikus feladatokhoz míg az OpenCV számítógépes látási feladatokkal foglalkozik.
A teljes forráskód elérhető a GitHub adattár.
A szükséges könyvtárak importálása és három kulcsfontosságú funkció meghatározása
Hozzon létre egy új Python-fájlt, és adjon neki egy tetszőleges nevet. Importálja a NumPy és OpenCV könyvtárakat a szkript elejére.
import zsibbadt mint np
import cv2
Ezen könyvtárak importálása lehetővé teszi a funkcióik használatát a kódban.
Ezután határozzon meg három olyan funkciót, amelyek kulcsfontosságúak lesznek a stabilizációs folyamat szempontjából.
A számítási_mozgó_átlag függvény
Hozzon létre egy függvényt, és nevezze el számolja ki a mozgóátlagot. Ez a függvény kiszámítja egy adott görbe mozgóátlagát az Ön által megadott sugár segítségével. Konvolúciós műveletet alkalmaz meghatározott ablakmérettel és egységes kernellel. Ez a mozgóátlag segít kisimítani a pálya ingadozásait.
defszámolja ki a mozgóátlagot(görbe, sugár):
# Számítsa ki egy görbe mozgóátlagát egy adott sugár használatával
window_size = 2 * sugár + 1
kernel = np.ones (ablakméret) / ablakméret
curve_padded = np.lib.pad (görbe, (sugár, sugár), 'él')
smoothed_curve = np.convolve (curve_padded, kernel, mode='azonos')
simított_görbe = simított_görbe[sugár:-sugár]
Visszatérés simított_görbe
A függvény sima görbét ad vissza. Segít csökkenteni a zajt és a görbe ingadozásait. Ezt a csúszó ablakon belüli értékek átlagolásával teszi.
A smooth_trajectory függvény
Hozzon létre egy másik függvényt, és nevezze el sima_pálya. Ez a funkció a mozgóátlagot alkalmazza a pálya minden dimenziójára. Ezt úgy éri el, hogy elkészíti az eredeti pálya simított másolatát. Ez tovább javítja a videó stabilitását.
defsima_pálya(röppálya):
# Simítsa a pályát a mozgóátlag segítségével minden dimenzióban
kisimított_pálya = np.copy (pálya)számára én ban ben hatótávolság(3):
simított_trajektória[:, i] = számolja_mozgó_átlag(
pálya[:, i],
sugár=SMOOTHING_RADIUS
)
Visszatérés simított_pálya
A sima_pálya függvény simított pályát ad vissza.
A fix_border függvény
Hozzon létre egy végső függvényt, és nevezze el fix_border. Ez a funkció rögzíti a keret szegélyét elforgatás és méretezési transzformáció alkalmazásával. Felveszi a bemeneti keretet, kiszámítja az alakját, összeállít egy transzformációs mátrixot, és alkalmazza a transzformációt a keretre. Végül visszaadja a rögzített keretet.
deffix_border(keret):
# Rögzítse a keret szegélyét elforgatás és méretezési transzformáció alkalmazásával
frame_shape = keret.alak
mátrix = cv2.getRotationMatrix2D(
(keret_alak[1] / 2, frame_shape[0] / 2),
0,
1.04
)
frame = cv2.warpAffine (keret, mátrix, (frame_shape[1], frame_shape[0]))
Visszatérés keret
A fix_border A funkció biztosítja, hogy a stabilizált kereteken ne legyen a stabilizációs folyamat által okozott szegélymű.
A videostabilizálás inicializálása és a bemenet felvétele
Kezdje a sugár beállításával, amelyet a pályasimító funkció használni fog.
SMOOTHING_RADIUS = 50
Ezután adja meg a stabilizálni kívánt remegő videó videoútját.
# Nyissa meg a bemeneti videofájlt
# Cserélje ki az elérési utat 0-ra a webkamera használatához
cap = cv2.VideoCapture("inputvid.mp4")
Szerezze meg a remegő videó tulajdonságait:
num_frames = int (cap.get (cv2.CAP_PROP_FRAME_COUNT))
szélesség = int (cap.get (cv2.CAP_PROP_FRAME_WIDTH))
magasság = int (cap.get (cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get (cv2.CAP_PROP_FPS)
Állítsa be a kimeneti formátumot. Ez az a formátum, amellyel a program elmenti a stabilizált videót. Bármelyiket használhatod általános videóformátum kedveled.
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
Végül inicializálja a videó íróját:
out = cv2.VideoWriter("video_out.mp4", négycc, fps, (2 * szélesség magasság))
A videóírónak átadott fájlnév kiterjesztésének meg kell egyeznie a kimeneti formátumban megadott kiterjesztéssel.
Keretek olvasása és feldolgozása
A remegő videó feldolgozásának első lépése itt kezdődik. Ez magában foglalja a képkockák beolvasását a bemeneti videóból, a transzformációk kiszámítását és a transzformációs tömb feltöltését.
Kezdje az első képkocka elolvasásával.
_, prev_frame = cap.read()
prev_gray = cv2.cvtColor (prev_frame, cv2.COLOR_BGR2GRAY)
Ezután inicializálja a transzformációs tömböt. Minden egyes képkockához tárolja az információkat.
transzformációk = np.zeros((kockák_száma - 1, 3), np.float32)
Végül ki kell számítania az egymást követő képkockák közötti optikai áramlást. Ezután becsülje meg a pontok közötti affin transzformációt.
számára én ban ben tartomány (kockák_száma - 2):
# Számítsa ki az egymást követő képkockák közötti optikai áramlást
prev_points = cv2.goodFeaturesToTrack(
prev_grey,
maxCorners=200,
minőségi szint=0.01,
minDistance=30,
blockSize=3
)siker, curr_frame = cap.read()
hanem siker:
szünetcurr_gray = cv2.cvtColor (curr_frame, cv2.COLOR_BGR2GRAY)
curr_points, status, err = cv2.calcOpticalFlowPyrLK(
prev_grey,
curr_grey,
prev_points,
Egyik sem
)állítja prev_points.shape == curr_points.shape
idx = np.where (állapot == 1)[0]
előző_pontok = előző_pontok[idx]
curr_points = curr_points[idx]
# A pontok közötti affin transzformáció becslése
mátrix, _ = cv2.estimateAffine2D(előző_pontok, aktuális_pontok)
fordítás_x = mátrix[0, 2]
fordítás_y = mátrix[1, 2]
forgásszög = np.arctan2(mátrix[1, 0], mátrix[0, 0])
transzformációk[i] = [fordítás_x, fordítás_y, elforgatási_szög]
prev_gray = curr_gray
A ciklus minden egyes kereten keresztül iterál (kivéve az utolsó képkockát) a transzformációk kiszámításához. Az egymást követő képkockák közötti optikai áramlást a Lucas-Kanade módszerrel számítja ki. cv2.goodFeaturesToTrack észleli az előző képkocka jellemzőpontjait prev_grey. Akkor, cv2.calcOpticalFlowPyrLK követi ezeket a pontokat az aktuális keretben curr_grey.
Az affin transzformációs mátrix becslésében csak az 1-es státuszú (a sikeres követést jelző) pontok segítenek. A kód frissíti a prev_grey változó az aktuális szürkeárnyalatos kerettel a következő iterációhoz.
A pálya simítása
Egyeníteni kell az átalakításokból kapott pályát a stabil eredmény eléréséhez.
# Számítsa ki a trajektóriát a transzformációk kumulatív összegzésével
pálya = np.cumsum (transzformálja, tengely=0)# Simítsa a pályát mozgóátlag segítségével
kisimított_pálya = sima_pálya (pálya)# Számítsa ki a különbséget a simított és az eredeti pálya között
különbség = simított_pálya - pálya
# Adja hozzá a különbséget az eredeti átalakításokhoz, hogy egyenletes legyen
# átalakítások
transforms_smooth = átalakul + különbség
A fenti kód kiszámítja a kamera mozgásának pályáját és simítja azt.
Stabilizáló és írókeretek
Az utolsó lépés a képkockák stabilizálása és a stabilizált videó kimeneti fájlba írása.
Kezdje a videórögzítés alaphelyzetbe állításával. Ez biztosítja, hogy a jövőbeni műveletek a videó elejétől olvashatók legyenek.
cap.set (cv2.CAP_PROP_POS_FRAMES, 0)
Ezután stabilizálja a videót az egyes képkockák feldolgozásával.
# Minden képkockát dolgozzon fel, és stabilizálja a videót
számára én ban ben tartomány (kockák_száma - 2):
siker, keret = cap.read()hanem siker:
szünetfordítás_x = átalakul_smooth[i, 0]
fordítás_y = átalakul_smooth[i, 1]
rotation_angle = átalakíts_smooth[i, 2]# Hozzon létre egy transzformációs mátrixot a stabilizáláshoz
transzformációs_mátrix = np.zeros((2, 3), np.float32)
transzformációs_mátrix[0, 0] = np.cos (elforgatási_szög)
transzformációs_mátrix[0, 1] = -np.sin (forgási_szög)
transzformációs_mátrix[1, 0] = np.sin (forgási_szög)
transzformációs_mátrix[1, 1] = np.cos (elforgatási_szög)
transzformációs_mátrix[0, 2] = fordítás_x
transzformációs_mátrix[1, 2] = fordítás_y# Alkalmazza az átalakítást a keret stabilizálásához
frame_stabilized = cv2.warpAffine(
keret,
transzformációs_mátrix,
(szélesség magasság)
)# Rögzítse a stabilizált keret szegélyét
frame_stabilized = fix_border (frame_stabilized)# Kösse össze az eredeti és a stabilizált kereteket egymás mellé
frame_out = cv2.hconcat([frame, frame_stabilized])# Méretezze át a keretet, ha a szélessége meghaladja az 1920 képpontot
ha frame_out.shape[1] > 1920:
frame_out = cv2.resize(
frame_out,
(frame_out.shape[1] // 2, frame_out.shape[0] // 2)
)# Az előtti és utáni keret megjelenítése
cv2.imshow("Előtt és után", frame_out)
cv2.waitKey(10)
# Írja be a keretet a kimeneti videofájlba
out.write (frame_out)
A fenti kód stabilizálja az egyes képkockákat a kiszámított transzformációk segítségével, beleértve a fordítási és elforgatási beállításokat. Ezután egyesíti a stabilizált kereteket az eredetivel, hogy összehasonlítást nyújtson.
A Video Capture és Writer kiadása
Végezze el a programot a videorögzítő és -író objektumok felszabadításával.
# Engedje el a videórögzítést és -írót, és zárjon be minden nyitott ablakot
cap.release()
out.release()
cv2.destroyAllWindows()
Ez a kód bezár minden nyitott ablakot is.
Végső programkimenet
A program kimenete valahogy így fog kinézni:
És itt van egy példa a stabilizált videóra:
A kimenet a remegő és a stabilizált videó összehasonlítását mutatja.
Fedezze fel az OpenCV képességeit
Az OpenCV-t számos olyan területen alkalmazhatja, amely számítógépes látással jár. Ennek az az oka, hogy a funkciók széles skáláját kínálja. Fedezze fel a képességeit, ha több olyan projekten dolgozik, amelyek számítógépes látást foglalnak magukban. Ez új fogalmakat vezet be, és új kutatási területeket kínál.