Користите ову технику да примените неку паметну математику на своје видео снимке и смањите подрхтавање.

Видео стабилизација је техника која смањује нежељено кретање и подрхтавање у видео снимку. Снимање из руке, вибрације и покрети могу узроковати нестабилне покрете фотоапарата. Видео стабилизација даје глаткији видео.

Примарни циљ стабилизације видеа је да процени кретање камере између узастопних кадрова. Процес затим може применити одговарајуће трансформације за поравнање оквира. Ово минимизира уочени покрет.

Подешавање вашег окружења

Старт би стварање виртуелног окружења како бисте осигурали да пакети које инсталирате да бисте покренули програм нису у сукобу са постојећим. Затим покрените ову наредбу терминала да бисте инсталирали потребне библиотеке:

пип инсталл опенцв-питхон нумпи

Ова команда инсталира НумПи и ОпенЦВ библиотеке. НумПи пружа алате за нумеричке задатке док се ОпенЦВ бави задацима компјутерског вида.

Комплетан изворни код је доступан у а ГитХуб спремиште.

Увоз потребних библиотека и дефинисање три кључне функције

Направите нову Питхон датотеку и дајте јој име по свом укусу. Увезите НумПи и ОпенЦВ библиотеке на почетку скрипте.

увоз нумпи као нп
увоз цв2

Увоз ових библиотека ће вам омогућити да користите њихове функције у свом коду.

Затим дефинишите три функције које ће бити кључне за процес стабилизације.

Функција Цалцулате_мовинг_авераге

Направите функцију и именујте је израчунај покретни просек. Ова функција ће израчунати покретни просек дате криве користећи радијус који одредите. Користи операцију конволуције са одређеном величином прозора и униформним језгром. Овај покретни просек помаже да се изгладе флуктуације у путањи.

дефизрачунај покретни просек(крива, радијус):
# Израчунајте покретни просек криве користећи дати радијус
величина_прозора = 2 * радијус + 1
кернел = нп.онес (величина_прозора) / величина_прозора
цурве_паддед = нп.либ.пад (крива, (радијус, радијус), 'Ивица')
смоотхед_цурве = нп.цонволве (цурве_паддед, кернел, моде='исти')
заглађена_крива = изглађена_крива[радијус:-радијус]
повратак смоотхед_цурве

Функција враћа глатку криву. Помаже у смањењу буке и флуктуација у кривини. То ради усредњавањем вредности унутар клизног прозора.

Функција смоотх_трајецтори

Направите другу функцију и дајте јој име смоотх_трајецтори. Ова функција ће применити покретни просек на сваку димензију путање. То ће постићи стварањем изглађене копије оригиналне путање. Ово ће додатно побољшати стабилност видео записа.

дефсмоотх_трајецтори(путања):
# Изгладите путању користећи покретни просек на свакој димензији
изглађена_трајекторија = нп.цопи (пута)

за и ин домет(3):
изглађена_трајекторија[:, и] = израчунати_просек_померања(
путања[:, и],
радиус=СМООТХИНГ_РАДИУС
)

повратак изглађена_трајекторија

Тхе смоотх_трајецтори функција враћа углађену путању.

Функција фик_бордер

Направите коначну функцију и именујте је фик_бордер. Ова функција ће поправити ивицу оквира применом трансформације ротације и скалирања. Узима улазни оквир, израчунава његов облик, конструише матрицу трансформације и примењује трансформацију на оквир. Коначно, враћа фиксни оквир.

деффик_бордер(Рам):
# Поправите ивицу оквира применом трансформације ротације и скалирања
оквир_облик = оквир.облик

матрик = цв2.гетРотатионМатрик2Д(
(облик_оквира[1] / 2, фраме_схапе[0] / 2),
0,
1.04
)

оквир = цв2.варпАффине (оквир, матрица, (фраме_схапе[1], фраме_схапе[0]))
повратак Рам

Тхе фик_бордер функција осигурава да стабилизовани рамови немају никакве граничне артефакте узроковане процесом стабилизације.

Иницијализација стабилизације видеа и узимање улаза

Почните тако што ћете подесити радијус који ће користити функција за изравнавање трајекторије.

СМООТХИНГ_РАДИУС = 50

Затим унесите видео путању климавог видеа који желите да стабилизујете.

# Отворите улазну видео датотеку
# Замените путању са 0 да бисте користили своју веб камеру
цап = цв2.ВидеоЦаптуре('инпутвид.мп4')

Преузмите својства климавог видеа:

нум_фрамес = инт (цап.гет (цв2.ЦАП_ПРОП_ФРАМЕ_ЦОУНТ))
ширина = инт (цап.гет (цв2.ЦАП_ПРОП_ФРАМЕ_ВИДТХ))
висина = инт (цап.гет (цв2.ЦАП_ПРОП_ФРАМЕ_ХЕИГХТ))
фпс = цап.гет (цв2.ЦАП_ПРОП_ФПС)

Подесите излазни формат. Ово је формат у којем ће програм сачувати стабилизовани видео. Можете користити било које уобичајени видео формат Волиш.

фоурцц = цв2.ВидеоВритер_фоурцц(*'мп4в')

На крају, иницијализујте видео писач:

оут = цв2.ВидеоВритер('видео_оут.мп4', фоурцц, фпс, (2 * ширина Висина))

Екстензија имена датотеке коју проследите програму за писање видео записа треба да буде иста као она коју сте поставили у излазном формату.

Оквири за читање и обраду

Први корак обраде климавог видеа почиње овде. Укључује читање оквира из улазног видеа, израчунавање трансформација и попуњавање низа трансформација.

Почните читањем првог кадра.

_, прев_фраме = цап.реад()
прев_граи = цв2.цвтЦолор (прет_фраме, цв2.ЦОЛОР_БГР2ГРЕИ)

Затим иницијализујте трансформациони низ. Чуваће информације за сваки оквир.

трансформс = нп.зерос((број_оквирова - 1, 3), нп.флоат32)

На крају, потребно је да израчунате оптички проток између узастопних оквира. Затим процените афину трансформацију између тачака.

за и ин опсег (број_оквирова - 2):
# Израчунајте оптички проток између узастопних кадрова
прев_поинтс = цв2.гоодФеатуресТоТрацк(
прев_граи,
макЦорнерс=200,
куалитиЛевел=0.01,
минДистанце=30,
блоцкСизе=3
)

успех, цурр_фраме = цап.реад()

аконе успех:
пауза

цурр_граи = цв2.цвтЦолор (цурр_фраме, цв2.ЦОЛОР_БГР2ГРЕИ)

цурр_поинтс, статус, ерр = цв2.цалцОптицалФловПирЛК(
прев_граи,
цурр_граи,
прев_поинтс,
Ниједан
)

тврдити прев_поинтс.схапе == цурр_поинтс.схапе
идк = нп.где (статус == 1)[0]
прев_поинтс = прев_поинтс[идк]
цурр_поинтс = цурр_поинтс[идк]

# Процена афине трансформације између тачака
матрица, _ = цв2.естиматеАффине2Д(претходни_поени, текући_поени)
превод_к = матрица[0, 2]
превод_и = матрица[1, 2]
угао_ротације = нп.арцтан2(матрица[1, 0], матрица[0, 0])
трансформс[и] = [транслатион_к, транслатион_и, ротатион_англе]
прев_граи = цурр_граи

Петља се понавља преко сваког оквира (осим последњег оквира) да би израчунала трансформације. Он израчунава оптички проток између узастопних кадрова користећи Луцас-Канаде метод. цв2.гоодФеатуресТоТрацк детектује тачке обележја у претходном оквиру прев_граи. Онда, цв2.цалцОптицалФловПирЛК прати ове тачке у тренутном оквиру цурр_граи.

Само тачке са статусом 1 (што указује на успешно праћење) помажу у процени матрице афине трансформације. Код ажурира прев_граи променљива са тренутним оквиром сивих тонова за следећу итерацију.

Изглађивање путање

Морате да изгладите путању добијену трансформацијама да бисте постигли стабилан резултат.

# Израчунајте путању кумулативним сабирањем трансформација
трајекторија = нп.цумсум (трансформи, оса=0)

# Изгладите путању користећи покретни просек
изглађена_трајекторија = глатка_трајекторија (пута)

# Израчунајте разлику између изглађене и оригиналне путање
разлика = изглађена_трајекторија - путања

# Додајте разлику назад оригиналним трансформацијама да бисте добили глатке
# трансформације
трансформс_смоотх = трансформише + разлика

Горњи код израчунава путању кретања камере и изглађује је.

Оквири за стабилизацију и писање

Последњи корак је стабилизација оквира и писање стабилизованог видеа у излазну датотеку.

Почните тако што ћете ресетовати снимање видео записа. Ово осигурава да ће се будуће операције читати од почетка видеа.

цап.сет (цв2.ЦАП_ПРОП_ПОС_ФРАМЕС, 0)

Затим стабилизујте видео обрадом сваког кадра.

# Обрадите сваки кадар и стабилизујте видео
за и ин опсег (број_оквирова - 2):
успех, оквир = цап.реад()

аконе успех:
пауза

транслатион_к = трансформс_смоотх[и, 0]
транслатион_и = трансформс_смоотх[и, 1]
угао_ротације = глатка_трансформација[и, 2]

# Креирајте матрицу трансформације за стабилизацију
трансформатион_матрик = нп.нуле((2, 3), нп.флоат32)
матрица_трансформације[0, 0] = нп.цос (угао_ротације)
матрица_трансформације[0, 1] = -нп.син (угао_ротације)
матрица_трансформације[1, 0] = нп.син (угао_ротације)
матрица_трансформације[1, 1] = нп.цос (угао_ротације)
матрица_трансформације[0, 2] = превод_к
матрица_трансформације[1, 2] = превод_и

# Примените трансформацију да стабилизујете оквир
фраме_стабилизед = цв2.варпАффине(
Рам,
матрица_трансформације,
(ширина Висина)
)

# Поправите ивицу стабилизованог оквира
фраме_стабилизед = фик_бордер (фраме_стабилизед)

# Спојите оригинални и стабилизовани оквир један поред другог
фраме_оут = цв2.хцонцат([фраме, фраме_стабилизед])

# Промените величину оквира ако његова ширина прелази 1920 пиксела
ако фраме_оут.схапе[1] > 1920:
фраме_оут = цв2.ресизе(
фраме_оут,
(фраме_оут.схапе[1] // 2, фраме_оут.схапе[0] // 2)
)

# Прикажи оквире пре и после
цв2.имсхов("Пре и после", фраме_оут)
цв2.ваитКеи(10)

# Упишите оквир у излазну видео датотеку
оут.врите (фраме_оут)

Горњи код стабилизује сваки оквир користећи израчунате трансформације, укључујући прилагођавања транслације и ротације. Затим комбинује стабилизоване оквире са оригиналним да би обезбедио поређење.

Отпуштање Видео Цаптуре и Вритер-а

Завршите програм тако што ћете пустити објекте за снимање и писање.

# Ослободите видео снимање и снимач и затворите све отворене прозоре
цап.релеасе()
оут.релеасе()
цв2.дестроиАллВиндовс()

Овај код такође затвара све отворене прозоре.

Финални излаз програма

Излаз програма ће изгледати отприлике овако:

А ево примера стабилизованог видеа:

Излаз приказује поређење између климавог и стабилизованог видеа.

Истражите могућности ОпенЦВ

ОпенЦВ можете применити у многим областима које укључују компјутерски вид. То је зато што нуди широк спектар функционалности. Требало би да истражите његове могућности радећи на више пројеката који укључују компјутерски вид. Ово ће вас упознати са новим концептима и дати вам нове области за истраживање.