Използвайте тази техника, за да приложите малко умна математика към вашите видеоклипове и да намалите трептенето.
Видео стабилизацията е техника, която намалява нежеланото движение и трептене във видеозаписи. Снимането от ръка, вибрациите и движението могат да причинят нестабилни движения на камерата. Видео стабилизацията създава по-плавно изглеждащо видео.
Основната цел на видео стабилизацията е да оцени движението на камерата между последователните кадри. След това процесът може да приложи подходящи трансформации за подравняване на рамките. Това минимизира възприеманото движение.
Настройване на вашата среда
Започнете от създаване на виртуална среда за да сте сигурни, че пакетите, които инсталирате, за да стартирате програмата, не са в конфликт със съществуващите. След това изпълнете тази терминална команда, за да инсталирате необходимите библиотеки:
pip инсталирайте opencv-python numpy
Тази команда инсталира библиотеки NumPy и OpenCV. NumPy предоставя инструменти за числени задачи докато OpenCV се занимава със задачи за компютърно зрение.
Пълният изходен код е достъпен в a GitHub хранилище.
Импортиране на необходимите библиотеки и дефиниране на три ключови функции
Създайте нов Python файл и му дайте име по ваш вкус. Импортирайте библиотеки NumPy и OpenCV в началото на скрипта.
импортиране numpy като np
импортиране cv2
Импортирането на тези библиотеки ще ви позволи да използвате техните функции във вашия код.
След това дефинирайте три функции, които ще бъдат от решаващо значение за процеса на стабилизиране.
Функцията Calculate_Moving_Average
Създайте функция и я наименувайте изчисляване_пълзяща_средна. Тази функция ще изчисли пълзящата средна на дадена крива, използвайки радиуса, който сте посочили. Той използва конволюционна операция с определен размер на прозореца и еднообразно ядро. Тази пълзяща средна помага за изглаждане на колебанията в траекторията.
дефизчисляване_пълзяща_средна(крива, радиус):
# Изчислете подвижната средна на крива, като използвате даден радиус
размер на прозореца = 2 * радиус + 1
ядро = np.ones (размер_на_прозорец) / размер_на_прозорец
curve_padded = np.lib.pad (крива, (радиус, радиус), 'ръб, край')
smoothed_curve = np.convolve (curve_padded, kernel, mode='един и същ')
изгладена_крива = изгладена_крива[радиус:-радиус]
връщане изгладена_крива
Функцията връща гладка крива. Помага за намаляване на шума и колебанията в кривата. Той прави това чрез осредняване на стойностите в плъзгащия се прозорец.
Функцията smooth_trajectory
Създайте друга функция и я наименувайте гладка_траектория. Тази функция ще приложи подвижната средна за всяко измерение на траекторията. Той ще постигне това чрез създаване на изгладено копие на оригиналната траектория. Това допълнително ще подобри стабилността на видеото.
дефгладка_траектория(траектория):
# Изгладете траекторията, като използвате подвижна средна за всяко измерение
smoothed_trajectory = np.copy (траектория)за аз в диапазон (3):
изгладена_траектория[:, i] = изчисляване_подвижна_средна(
траектория [:, i],
радиус=SMOOTHING_RADIUS
)
връщане изгладена_траектория
The гладка_траектория функцията връща изгладена траектория.
Функцията fix_border
Създайте крайна функция и я наименувайте fix_border. Тази функция ще фиксира границата на рамката чрез прилагане на трансформация на завъртане и мащабиране. Той взема входния кадър, изчислява неговата форма, конструира трансформационна матрица и прилага трансформацията към кадъра. Накрая връща фиксираната рамка.
дефfix_border(кадър):
# Коригирайте границата на рамката, като приложите трансформация на ротация и мащабиране
рамка_форма = рамка.форма
матрица = cv2.getRotationMatrix2D(
(форма_на_рамка[1] / 2, форма_на_рамка[0] / 2),
0,
1.04
)
рамка = cv2.warpAffine (рамка, матрица, (frame_shape[1], форма_на_рамка[0]))
връщане кадър
The fix_border функция гарантира, че стабилизираните рамки нямат никакви гранични артефакти, причинени от процеса на стабилизиране.
Инициализиране на видео стабилизация и приемане на входа
Започнете, като зададете радиуса, който ще използва функцията за изглаждане на траекторията.
SMOOTHING_RADIUS = 50
След това прекарайте видео пътя на нестабилното видео, което искате да стабилизирате.
# Отворете входния видео файл
# Заменете пътя с 0, за да използвате вашата уеб камера
cap = cv2.VideoCapture('inputvid.mp4')
Вземете свойствата на треперещото видео:
num_frames = int (cap.get (cv2.CAP_PROP_FRAME_COUNT))
ширина = int (cap.get (cv2.CAP_PROP_FRAME_WIDTH))
височина = int (cap.get (cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get (cv2.CAP_PROP_FPS)
Задайте изходния формат. Това е форматът, в който програмата ще запази стабилизираното видео. Можете да използвате всякакви общ видео формат ти харесваш.
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
И накрая, инициализирайте видео записащото устройство:
out = cv2.VideoWriter('video_out.mp4', fourcc, fps, (2 * ширина, височина))
Разширението на името на файла, което предавате на записващото видео, трябва да бъде същото като това, което сте задали в изходния формат.
Кадри за четене и обработка
Първата стъпка от обработката на треперещия видеоклип започва тук. Това включва четене на кадри от входното видео, изчисляване на трансформации и попълване на масива за трансформации.
Започнете с четене на първия кадър.
_, prev_frame = cap.read()
prev_gray = cv2.cvtColor (prev_frame, cv2.COLOR_BGR2GRAY)
След това инициализирайте трансформационния масив. Той ще съхранява информация за всеки кадър.
трансформира = np.zeros((num_frames - 1, 3), np.float32)
И накрая, трябва да изчислите оптичния поток между последователните кадри. След това оценете афинната трансформация между точките.
за аз в диапазон (брой_кадри - 2):
# Изчислете оптичния поток между последователни кадри
prev_points = cv2.goodFeaturesToTrack(
предишен_сив,
maxCorners=200,
ниво на качество=0.01,
minDistance=30,
blockSize=3
)успех, curr_frame = cap.read()
аконе успех:
прекъсвамcurr_gray = cv2.cvtColor (curr_frame, cv2.COLOR_BGR2GRAY)
curr_points, status, err = cv2.calcOpticalFlowPyrLK(
предишен_сив,
curr_gray,
предишни_точки,
Нито един
)твърдят prev_points.shape == curr_points.shape
idx = np.където (състояние == 1)[0]
предишни_точки = предишни_точки[idx]
curr_points = curr_points[idx]
# Оценка на афинна трансформация между точките
матрица, _ = cv2.estimateAffine2D(prev_points, curr_points)
превод_x = матрица[0, 2]
превод_y = матрица[1, 2]
ротационен_ъгъл = np.arctan2(матрица[1, 0], матрица[0, 0])
трансформира[i] = [translation_x, translation_y, rotation_angle]
предишно_сиво = curr_сиво
Цикълът итерира всеки кадър (с изключение на последния кадър), за да изчисли трансформациите. Той изчислява оптичния поток между последователни кадри, използвайки метода на Lucas-Kanade. cv2.goodFeaturesToTrack открива характерни точки в предишния кадър предишен_сив. Тогава, cv2.calcOpticalFlowPyrLK проследява тези точки в текущия кадър curr_gray.
Само точките със статус 1 (указващи успешно проследяване) помагат при оценката на матрица за афинна трансформация. Кодът актуализира предишен_сив променлива с текущата рамка в сивата скала за следващата итерация.
Изглаждане на траекторията
Трябва да изгладите траекторията, получена от трансформациите, за да постигнете стабилен резултат.
# Изчислете траекторията чрез кумулативно сумиране на трансформациите
траектория = np.cumsum (трансформира, ос=0)# Изгладете траекторията с помощта на подвижна средна
smoothed_trajectory = гладка_траектория (траектория)# Изчислете разликата между изгладената и оригиналната траектория
разлика = smoothed_trajectory - траектория
# Добавете разликата обратно към оригиналните трансформации, за да получите гладкост
# трансформации
transforms_smooth = трансформира + разлика
Горният код изчислява траекторията на движението на камерата и я изглажда.
Рамки за стабилизиране и писане
Последната стъпка е стабилизиране на кадрите и запис на стабилизираното видео в изходен файл.
Започнете с нулиране на заснемането на видео. Това гарантира, че бъдещите операции ще четат от началото на видеото.
cap.set (cv2.CAP_PROP_POS_FRAMES, 0)
След това стабилизирайте видеото чрез обработка на всеки кадър.
# Обработвайте всеки кадър и стабилизирайте видеото
за аз в диапазон (брой_кадри - 2):
успех, рамка = cap.read()аконе успех:
прекъсвамtranslation_x = transforms_smooth[i, 0]
translation_y = transforms_smooth[i, 1]
ротация_ъгъл = transforms_smooth[i, 2]# Създайте матрицата на трансформация за стабилизиране
transformation_matrix = np.zeros((2, 3), np.float32)
трансформационна_матрица[0, 0] = np.cos (rotation_angle)
трансформационна_матрица[0, 1] = -np.sin (ъгъл_на_въртене)
трансформационна_матрица[1, 0] = np.sin (ъгъл_на_въртене)
трансформационна_матрица[1, 1] = np.cos (rotation_angle)
трансформационна_матрица[0, 2] = превод_x
трансформационна_матрица[1, 2] = превод_y# Приложете трансформацията, за да стабилизирате рамката
frame_stabilized = cv2.warpAffine(
кадър,
трансформационна_матрица,
(ширина, височина)
)# Фиксирайте границата на стабилизираната рамка
frame_stabilized = fix_border (frame_stabilized)# Свържете оригиналните и стабилизираните рамки един до друг
frame_out = cv2.hconcat([frame, frame_stabilized])# Преоразмерете рамката, ако нейната ширина надвишава 1920 пиксела
ако frame_out.shape[1] > 1920:
frame_out = cv2.resize(
frame_out,
(frame_out.shape[1] // 2, frame_out.shape[0] // 2)
)# Показване на кадрите преди и след
cv2.imshow("Преди и след", frame_out)
cv2.waitKey(10)
# Запишете рамката в изходния видео файл
out.write (frame_out)
Горният код стабилизира всеки кадър с помощта на изчислените трансформации, включително корекции на транслация и ротация. След това комбинира стабилизираните кадри с оригиналните, за да осигури сравнение.
Пускане на Video Capture и Writer
Финализирайте програмата, като освободите обектите за заснемане на видео и запис.
# Освободете заснемането и записването на видео и затворете всички отворени прозорци
cap.release()
out.release()
cv2.destroyAllWindows()
Този код също затваря всички отворени прозорци.
Краен изход на програмата
Резултатът от програмата ще изглежда така:
И ето пример за стабилизирано видео:
Резултатът показва сравнението между треперещото видео и стабилизираното.
Разгледайте възможностите на OpenCV
Можете да приложите OpenCV в много области, които включват компютърно зрение. Това е така, защото предлага широк набор от функции. Трябва да проучите неговите възможности, като работите по повече проекти, които включват компютърно зрение. Това ще ви запознае с нови концепции и ще ви даде нови области за изследване.