Käytä tätä tekniikkaa soveltaaksesi älykästä matematiikkaa videoihisi ja vähentääksesi tärinää.

Videon stabilointi on tekniikka, joka vähentää ei-toivottua liikettä ja tärinää videomateriaalissa. Kuvaus kädessä, tärinä ja liike voivat kaikki aiheuttaa epävakaa kameran liikkeitä. Videon stabilointi tuottaa tasaisemman näköisen videon.

Videon stabiloinnin ensisijainen tavoite on arvioida kameran liikettä peräkkäisten kuvien välillä. Prosessi voi sitten soveltaa asianmukaisia ​​muunnoksia kehysten kohdistamiseksi. Tämä minimoi havaitun liikkeen.

Ympäristösi luominen

Aloita virtuaalisen ympäristön luominen varmistaaksesi, että ohjelman suorittamista varten asentamasi paketit eivät ole ristiriidassa olemassa olevien pakettien kanssa. Suorita sitten tämä päätekomento asentaaksesi tarvittavat kirjastot:

pip asennus opencv-python numpy

Tämä komento asentaa NumPy- ja OpenCV-kirjastot. NumPy tarjoaa työkaluja numeerisiin tehtäviin kun taas OpenCV käsittelee tietokonenäkötehtäviä.

Täysi lähdekoodi on saatavilla a GitHub-arkisto.

instagram viewer

Vaadittujen kirjastojen tuonti ja kolmen tärkeän funktion määrittäminen

Luo uusi Python-tiedosto ja anna sille haluamasi nimi. Tuo NumPy- ja OpenCV-kirjastot skriptin alussa.

tuonti nuhjuinen kuten np
tuonti cv2

Näiden kirjastojen tuominen antaa sinun käyttää niiden toimintoja koodissasi.

Määritä seuraavaksi kolme toimintoa, jotka ovat ratkaisevia stabilointiprosessin kannalta.

Laske_liikkuva_keskiarvo-funktio

Luo funktio ja nimeä se laske_liikkuva_keskiarvo. Tämä funktio laskee tietyn käyrän liukuvan keskiarvon määrittämääsi säteen avulla. Se käyttää konvoluutiooperaatiota tietyllä ikkunakoolla ja yhtenäisellä ytimellä. Tämä liukuva keskiarvo auttaa tasoittamaan liikeradan vaihteluita.

deflaske_liikkuva_keskiarvo(käyrä, säde):
# Laske käyrän liukuva keskiarvo käyttämällä annettua sädettä
ikkunan_koko = 2 * säde + 1
kernel = np.ones (ikkunan_koko) / ikkunan_koko
curve_padded = np.lib.pad (käyrä, (säde, säde), 'reuna')
smoothed_curve = np.convolve (curve_padded, kernel, mode='sama')
tasoitettu_käyrä = tasoitettu_käyrä[säde:-säde]
palata tasoitettu_käyrä

Funktio palauttaa tasaisen käyrän. Se auttaa vähentämään melua ja käyrän heilahteluja. Se tekee tämän laskemalla liukuvan ikkunan arvojen keskiarvon.

Tasainen_rata-funktio

Luo toinen funktio ja nimeä se sileä_rata. Tämä toiminto käyttää liikkuvaa keskiarvoa liikeradan jokaisessa ulottuvuudessa. Se saavuttaa tämän luomalla tasoitetun kopion alkuperäisestä liikeradalta. Tämä parantaa videon vakautta entisestään.

defsileä_rata(rata):
# Tasoita lentorata käyttämällä liukuvaa keskiarvoa kussakin ulottuvuudessa
smoothed_trajectory = np.copy (rata)

varten i sisään range(3):
tasoitettu_rata[:, i] = laske_liikkuva_keskiarvo(
lentorata[:, i],
säde=SMOOTHING_RADIUS
)

palata tasoitettu_rata

The sileä_rata funktio palauttaa tasoitetun lentoradan.

Fix_border-funktio

Luo lopullinen funktio ja nimeä se fix_border. Tämä toiminto korjaa kehyksen reunan käyttämällä kierto- ja skaalausmuunnoksia. Se ottaa syötekehyksen, laskee sen muodon, muodostaa muunnosmatriisin ja soveltaa muunnoksen kehykseen. Lopuksi se palauttaa kiinteän kehyksen.

deffix_border(kehys):
# Korjaa kehyksen reuna käyttämällä kierto- ja skaalausmuunnoksia
frame_shape = kehys.muoto

matriisi = cv2.getRotationMatrix2D(
(frame_shape[1] / 2, frame_shape[0] / 2),
0,
1.04
)

frame = cv2.warpAffine (kehys, matriisi, (frame_shape[1], frame_shape[0]))
palata kehys

The fix_border toiminto varmistaa, että stabiloiduissa kehyksissä ei ole stabilointiprosessin aiheuttamia reunusartefakteja.

Videon stabiloinnin alustaminen ja tulon ottaminen

Aloita asettamalla säde, jota liikeradan tasoitustoiminto käyttää.

SMOOTHING_RADIUS = 50

Ohita sitten tärisevän videon videopolku, jonka haluat vakauttaa.

# Avaa syöttövideotiedosto
# Käytä verkkokameraasi korvaamalla polun numerolla 0
cap = cv2.VideoCapture("inputvid.mp4")

Hanki tärisevän videon ominaisuudet:

num_frames = int (cap.get (cv2.CAP_PROP_FRAME_COUNT))
leveys = int (cap.get (cv2.CAP_PROP_FRAME_WIDTH))
korkeus = int (cap.get (cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get (cv2.CAP_PROP_FPS)

Aseta tulostusmuoto. Tämä on muoto, jolla ohjelma tallentaa stabiloidun videon. Voit käyttää mitä tahansa yleinen videomuoto pidät.

fourcc = cv2.VideoWriter_fourcc(*"mp4v")

Alusta lopuksi videon kirjoittaja:

out = cv2.VideoWriter("video_out.mp4", fourcc, fps, (2 * leveys korkeus))

Videon kirjoittajalle välitettävän tiedostonimen laajennuksen tulee olla sama kuin tulostusmuodossa määrittämäsi tunniste.

Kehysten lukeminen ja käsittely

Ensimmäinen vaihe tärisevän videon käsittelyssä alkaa tästä. Se sisältää kehysten lukemisen syötevideosta, muunnosten laskemisen ja muunnostaulukon täyttämisen.

Aloita lukemalla ensimmäinen kehys.

_, prev_frame = cap.read()
prev_grey = cv2.cvtColor (prev_frame, cv2.COLOR_BGR2GRAY)

Alusta sitten muunnostaulukko. Se tallentaa tiedot jokaisesta kehyksestä.

muunnokset = np.zeros((kehysten_määrä - 1, 3), np.float32)

Lopuksi sinun on laskettava optinen virtaus peräkkäisten kehysten välillä. Arvioi sitten pisteiden välinen affiinimuunnos.

varten i sisään alue (kehysten_määrä - 2):
# Laske optinen virtaus peräkkäisten kehysten välillä
prev_points = cv2.goodFeaturesToTrack(
prev_grey,
maxCorners=200,
laatutaso=0.01,
minDistance=30,
blockSize=3
)

menestys, curr_frame = cap.read()

josei menestys:
tauko

curr_grey = cv2.cvtColor (curr_frame, cv2.COLOR_BGR2GRAY)

curr_points, status, err = cv2.calcOpticalFlowPyrLK(
prev_grey,
curr_grey,
prev_points,
Ei mitään
)

väittää prev_points.shape == curr_points.shape
idx = np.where (tila == 1)[0]
aiemmat_pisteet = edelliset_pisteet[idx]
curr_points = curr_points[idx]

# Arvioi affiinimuunnos pisteiden välillä
matriisi, _ = cv2.estimateAffine2D(ed._pisteet, curr_points)
käännös_x = matriisi[0, 2]
käännös_y = matriisi[1, 2]
rotation_angle = np.arctan2(matriisi[1, 0], matriisi[0, 0])
transforms[i] = [käännös_x, käännös_y, kiertokulma]
prev_grey = curr_grey

Silmukka iteroi jokaisen kehyksen yli (lukuun ottamatta viimeistä kehystä) muunnosten laskemiseksi. Se laskee optisen virtauksen peräkkäisten kehysten välillä Lucas-Kanaden menetelmällä. cv2.goodFeaturesToTrack havaitsee piirrepisteet edellisestä kehyksestä edellinen_harmaa. Sitten, cv2.calcOpticalFlowPyrLK seuraa näitä pisteitä nykyisessä kehyksessä curr_grey.

Vain pisteet, joiden tila on 1 (osoittaa onnistuneen seurannan), auttavat arvioimaan affinista muunnosmatriisia. Koodi päivittää edellinen_harmaa muuttuja nykyisen harmaasävykehyksen kanssa seuraavaa iteraatiota varten.

Lentoradan tasoitus

Sinun on tasoitettava muunnoksista saatua lentorataa vakaan tuloksen saavuttamiseksi.

# Laske liikerata summaamalla muunnokset kumulatiivisesti
liikerata = np.cumsum (muuntuu, akseli=0)

# Tasoita lentorata liukuvalla keskiarvolla
tasoitettu_rata = sileä_rata (rata)

# Laske tasoitetun ja alkuperäisen lentoradan välinen ero
ero = tasoitettu_rata - liikerata

# Lisää ero takaisin alkuperäisiin muunnoksiin saadaksesi tasaisen
#muutoksia
transforms_smooth = muunnos + erotus

Yllä oleva koodi laskee kameran liikkeen liikeradan ja tasoittaa sitä.

Vakautus- ja kirjoituskehykset

Viimeinen vaihe on vakauttaa kehykset ja kirjoittaa stabiloitu video ulostulotiedostoon.

Aloita nollaamalla videokaappaus. Tämä varmistaa, että tulevat toiminnot luetaan videon alusta alkaen.

cap.set (cv2.CAP_PROP_POS_FRAMES, 0)

Stabilisoi sitten video käsittelemällä jokainen kuva.

# Käsittele jokainen kuva ja stabiloi video
varten i sisään alue (kehysten_määrä - 2):
menestys, kehys = cap.read()

josei menestys:
tauko

käännös_x = transforms_smooth[i, 0]
käännös_y = transforms_smooth[i, 1]
rotation_angle = transforms_smooth[i, 2]

# Luo muunnosmatriisi stabilointia varten
transformation_matrix = np.zeros((2, 3), np.float32)
muunnosmatriisi[0, 0] = np.cos (kiertokulma)
muunnosmatriisi[0, 1] = -np.sin (kiertokulma)
muunnosmatriisi[1, 0] = np.sin (kiertokulma)
muunnosmatriisi[1, 1] = np.cos (kiertokulma)
muunnosmatriisi[0, 2] = käännös_x
muunnosmatriisi[1, 2] = käännös_y

# Käytä muunnosta kehyksen vakauttamiseksi
frame_stabilized = cv2.warpAffine(
kehys,
transformation_matrix,
(leveys korkeus)
)

# Kiinnitä stabiloidun kehyksen reuna
kehys_stabiloitu = fix_border (kehys_vakaistu)

# Liitä alkuperäiset ja vakautetut kehykset vierekkäin
frame_out = cv2.hconcat([kehys, kehys_stabiloitu])

# Muuta kehyksen kokoa, jos sen leveys ylittää 1920 pikseliä
jos frame_out.shape[1] > 1920:
frame_out = cv2.resize(
frame_out,
(frame_out.shape[1] // 2, frame_out.shape[0] // 2)
)

# Näytä ennen ja jälkeen kehykset
cv2.imshow("Ennen ja jälkeen", frame_out)
cv2.waitKey(10)

# Kirjoita kehys ulostulovideotiedostoon
out.write (frame_out)

Yllä oleva koodi stabiloi jokaisen kehyksen käyttämällä laskettuja muunnoksia, mukaan lukien translaatio- ja kiertosäädöt. Sitten se yhdistää stabiloidut kehykset alkuperäisiin vertailun tarjoamiseksi.

Video Capture and Writer -ohjelman julkaisu

Viimeistele ohjelma vapauttamalla videokaappaus- ja kirjoitusobjektit.

# Vapauta videokaappaus ja kirjoitusohjelma ja sulje kaikki avoimet ikkunat
cap.release()
out.release()
cv2.destroyAllWindows()

Tämä koodi sulkee myös kaikki avoimet ikkunat.

Ohjelman lopullinen tulos

Ohjelman tulos näyttää suunnilleen tältä:

Ja tässä on esimerkki stabiloidusta videosta:

Tulos näyttää vertailun tärisevän ja stabiloidun videon välillä.

Tutustu OpenCV-ominaisuuksiin

Voit soveltaa OpenCV: tä monilla tietokonenäköön liittyvillä aloilla. Tämä johtuu siitä, että se tarjoaa laajan valikoiman toimintoja. Sinun tulisi tutkia sen ominaisuuksia työskentelemällä useammissa projekteissa, joihin liittyy tietokonenäköä. Tämä tutustuttaa sinut uusiin käsitteisiin ja antaa sinulle uusia tutkimusalueita.