Re: Замена выпавших кадров (drop'ов) и SVP
MAG79
Спасибо большое. Как раз то, что нужно. Только подправил Trim(1,173544) потому что на файле с полным фильмом на дубль не попадало сразу. Это вы хорошо придумали.
You are not logged in. Please login or register.
SmoothVideo Project → Эксплуатация SVP → Замена выпавших кадров (drop'ов) и SVP
MAG79
Спасибо большое. Как раз то, что нужно. Только подправил Trim(1,173544) потому что на файле с полным фильмом на дубль не попадало сразу. Это вы хорошо придумали.
MAG79
Добрый вечер.
Ваш прекрасный код в этом комментарии (отдельное за него спасибо!) очень интересный и полезный, он вдохновил меня на эксперименты с теми видео, которые раньше я считал не подлежащими нормальному восстановлению плавности.
Но тут мне попался фильм с крайне необычным и сложным случаем сочетания дропов и скачков (хоть всё это и имеет чёткую последовательность!), который полностью "восстановить" мне не удалось.
Семпл (видео 25fps, продолжительность 5 минут): http://sendfile.su/1274221
В этом видео 4 проблемы (из них я понял как решать только первые 3 проблемы):
1) 1 дубль - 1 раз каждые 25 кадров
2) 1 скачок (пропуск кадра) - 1 раз каждые 25 кадров
Эти первые 2 проблемы прекрасно решаются по аналогии с тем способом из Вашего комментария чуть выше.
3) 1 дубль - 1 раз каждые 24 кадра
Если бы не существовало 4-й проблемы, то эту проблему можно было бы решить, применив (после предыдущего этапа) выкидывание каждого 24-го кадра (к примеру начиная с 20 кадра) при помощи SelectEvery. Как-то так:
SelectEvery(24,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23)
4) 1 скачок - 1 раз каждые 24 кадра.
Вот здесь я и не знаю как реализовать смещение на 1 кадр каждую секунду, т.е. необходимый сдвиг для вставки в нужное место рассчитанного промежуточного кадра.
MAG79
Пытался после первого этапа (решение 1-2 проблем), оставшиеся 3-4 проблемы решить (на втором этапе) абсолютно тем же самым способом, только уже со значением clip'а равным не 25, а 24 (ведь тут же нет привязки в исходному fps видео), поначалу даже подумал что всё получилось, но я ошибся, после того как Fix24 пересекается с Fix25 всё идет на так как должно.
P.S. И ещё вопрос, сейчас используется:
f0 = SelectEvery(orig, 4, 0)
и последующие 25 аналогичных строчек.
Но я очень хотел вместо SelectEvery задействовать SelectRangeEvery (всего 2 строчки с SelectRangeEvery заменили бы 24-25 строк с SelectEvery), но для такого варианта я так и не смог найти на что можно заменить функцию вывода Interleave, т.к. чередование тут уже не подходит. А может всё-таки есть способ использовать SelectRangeEvery?
Это здорово, что удалось разобраться самостоятельно.
Решение в лоб - это действительно довольно много строчек кода скрипта. Можно ли их сократить? Да. Возможен, например, такой вариант: удвоение с прореживанием.
setMtMode(5,4)
AviSource("sample.avi")
setMtMode(2)
myGPU = true
threads=4
super_params = (myGPU==true) ? "{gpu:1}" : "{gpu:0}"
analyse_params="{main:{search:{coarse:{distance:4,bad:{sad:2000}},type:2,distance:4},penalty:{lambda:1,pglobal:10000}},refine:[{thsad:65000}]}"
smoothfps_params="{rate:{num:2,den:1},algo:13,scene:{blend:true}}"
super=SVSuper(super_params)
vectors=SVAnalyse(super, analyse_params)
fix_all = SVSmoothFps(super, vectors, smoothfps_params, mt=threads, url="www.svp-team.com")
SelectEvery(fix_all, 48, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 47)
Distributor()
Тут все просто. После удвоения кадров из 24 исходных получится 48 кадров, где каждый четный кадр - исходный, а нечетный - промежуточный. Поэтому нужно при помощи SelectEvery выбрать четные, добавив к ним в месте скачка нечетный кадр, соответствующий промежуточному положению объектов в кадре ровно из середины этого скачка. В скрипте предполагается, что скачок после 23-го кадра (46-ой после удвоения). После работы скрипта видео с частотой 24 к/сек станет иметь скорость 25 к/сек, т.к. к исходным 24-ем кадрам добавлен еще один.
Можно ли их сократить? Да. Возможен, например, такой вариант: удвоение с прореживанием.
Благодарю! С упрощением теперь понятно.
А всё-таки, насчет упрощения с использованием SelectRangeEvery - его совсем никак не получится применить?
После удвоения кадров из 24 исходных получится 48 кадров, где каждый четный кадр - исходный, а нечетный - промежуточный.
Я правильно понимаю, что по сути тратятся ресурсы на удвоение кадров для всего видео, а потом выбираются только нужные кадры?
А нельзя делать рассчитывание промежуточных кадров только между двумя необходимыми кадрами? (для увеличения быстродействия)
Это здорово, что удалось разобраться самостоятельно.
К сожалению, не удалось.
Сегодня 19:11:14 (изменено: Bars, Сегодня 20:09:45)
Сегодня 20:15:13
Так что большая просьба ознакомиться с моим сэмплом (4 имеющиеся проблемы я описал в своем первом комментарии), а то у меня уже закончились идеи, где именно искать ошибку.
Примечание: В моем семпле дубли совсем не в тех местах, где скачки, т.е. нужна не простая замена дубля на рассчитанный кадр, а 2 разных действия (выкидывание кадра в нужном месте и добавление кадра в нужном месте).
А целом необходимо выбросить 2 дубля и добавить 2 рассчитанных кадра.
P.S. Очень хочется разобраться где именно ошибка, чтобы научиться нормально "восстанавливать" не только это видео, но и любые другие, имеющие какую-либо четкую последовательность скачков/дублей.
Bars
К последнему скрипту SelectRangeEvery не применить, т.к. выбирать кадры из последовательности нужно через один и шаблон выбора сложнее, чем пачка последовательных кадров со смещением.
Ресурсы на удвоение в скрипте тратятся только при запросе кадра на вывод. В этом и заключается прелесть Avisynth-скрипта: кадры, которым не суждено попасть на вывод даже не рассчитываются. И вектора движения реально рассчитываются только в тех местах, где они нужны. В скрипте из предыдущего сообщения на все 24 исходных кадра будер рассчитан только один кадр (между кадрами 23 и 24), и вектора движения будут расчитаны только между этими кадрами.
Сэмпл скачаю, погляжу.
MAG79
Спасибо за ответы.
Ещё маленький вопрос по первому Вашему коду, а для чего там вводилась дополнительная переменная: "orig = last", почему там сразу не использовалась "last"?
Сэмпл скачаю, погляжу.
Отлично!
P.S. Ещё день спустя как-то само собой пришло понимание почему в своей последней попытке я потерпел неудачу: если бы у меня были дубли в местах скачков (и требовалось бы заменить эти дубли на рассчитанные кадры), то у меня бы все получилось (т.к. не было бы никаких сдвигов по кадрам). Но у меня дубли в одних местах, а скачки в других и если сделать первый этап, т.е. выбросить ненужный каждый 25-й дубль и добавить в нужном месте дополнительный кадр в месте скачка (также с интервалом 25), то это нарушает периодичность второго дубля (который идет с интервалом 24 кадра) в том промежутке между выброшенным дублем25 и добавленным кадром Fix25. Т.е. когда 24 дубль попадает в этот интервал, то там есть сдвиг на один кадр и из-за этого всё нарушается.
С одной стороны хорошо, что я понял из-за чего был сбой в моем варианте, а с другой - вот теперь у меня даже нет никаких идей и предположений каким образом может решаться эта задача. Теперь узнать решение мне ещё интереснее и важнее прежнего.
Bars
Поглядел видео по ссылке. Взял отрезок с панорамированием. На мотоцикле. Шаблон и правда подтвердился. Есть дубли, есть скачки. Причем парные. Периодичность каждые 24 и каждые 25 кадров. Ниже приложил график опережения кадров своего родного положения. +1 - кадр отображается раньше своей позиции, -1 - позже.
На выбранном отрезке дубли (d - double) и скачки (j - jump). 3d, 8j, 13j, 22d, 27d, 33j, 37j, 47d, 51d
Приложил архив из 52 кадров и график.
Шаблон и правда подтвердился. Есть дубли, есть скачки. Причем парные. Периодичность каждые 24 и каждые 25 кадров.
Спасибо. Это, конечно, замечательно, что я не ошибся с анализом этого видео и подтвердились все найденные мной проблемы в этом видео (хотя было бы и очень странно, если бы не подтвердились, потому что за время многочисленных экспериментов и попыток по его восстановлению я это видео изучил очень хорошо).
Так а не подскажете, что теперь тут можно сделать? Как я написал в предыдущем комментарии, хотя я нашел и понял все ошибки, но идей как работать с такой периодичностью у меня больше нет.
Теперь нужно составить файл команд, куда сдвигать кадры в соответствии с их номерами.
В данном случае файл такой:
Type int
Default 0R 3 6 100
7 50
13 -50
R 14 21 -100
R 27 31 100
32 50
37 -50
R 38 46 -100
R 51 52 100
читается так: для кадров 3 - 6 берем кадр из будущего (смещение +100)
для кадра 7 - берем кадр со смещением +50, т.е. интерполяцией между текущим и следующим.
и так далее. Формат файла см. там: ConditionalReader
Ну и сам скрипт с применением функции ConditionalReader.
ImageSource("img%02d.jpg", start=00, end=52)
ConvertToYV12()
myGPU = true
myErrSize = 20
super_params = (myGPU==true) ? "{gpu:1}" : "{gpu:0}"
analyse_params="{main:{search:{coarse:{distance:4,bad:{sad:2000}},type:2,distance:4},penalty:{lambda:1,pglobal:10000}},refine:[{thsad:65000}]}"
smoothfps_params="{rate:{num:2,den:1},algo:13,scene:{blend:true}}"
super=SVSuper(super_params)
vectors=SVAnalyse(super, analyse_params)
fix_all = SVSmoothFps(super, vectors, smoothfps_params, mt=GetMTMode(true), url="www.svp-team.com")
global fix50 = fix_all.SelectEvery(2,1).Subtitle("fix50", align=3, size=myErrSize)
global fix50n = fix_all.SelectEvery(2,1).Subtitle("-fix50", align=3, size=myErrSize)
ScriptClip("ReplaceFrames(last,delta)")
ScriptClip("Subtitle(String(delta))")
ConditionalReader("delta.txt", "delta", false)
function ReplaceFrames(clip input, int delta)
{
(delta==-100) ? input.trim(1,1)+input : \
(delta==-50) ? fix50n.trim(1,1)+fix50n : \
(delta==50) ? fix50 : \
(delta==100) ? input.trim(1,0) : \
input
return last
}
Результат приложил. Это 52 кадра в архиве.
Анимация (уменьшенный предпросмотр) результата.
В верхнем левом углу значение переменной delta.
В нижнем правом - метка интерполированных кадров (fix50 / -fix50).
MAG79
Большое спасибо за скрипт! Только я не очень понимаю, как это применять на практике не для нескольких десятков кадров, а для нескольких сотен тысяч кадров, т.е. каким образом можно задавать необходимую периодичность в delta.txt?
Ведь в вашем примере delta.txt, насколько я разобрался после экспериментов с ним, периодичность не задана вообще, а просто покадрово, вручную по номерам кадров (с предварительным анализом) расписано с какими кадрами, что делать (без учёта последующих многих тысяч кадров):
В данном случае файл такой:
delta.txt wrote:Type int
Default 0R 3 6 100
7 50
13 -50
R 14 21 -100
R 27 31 100
32 50
37 -50
R 38 46 -100
R 51 52 100
P.S. Кстати, на вашем примере прыжок между 8 и 9 кадрами, а в delta.txt указывать надо 7 кадр: "7 50" т.е. там ещё кое-где получается надо учитывать смещение на один кадр (видимо, из-за выкидывание ранее идущего дубля). В общем этот формат значительно сложнее для восприятия и сложнее для редактирования, чем предыдущий вариант с SelectEvery и Interleave (жаль, что его тут никак не использовать).
Bars
Для бОльшего количества кадров надо как-то автоматизировать создание файла delta.txt. Например, можно использовать MS Excel. Плюс надо еще подумать как разруливать места двойных дропов, где пересекаются 25-ти и 24-ех кадровые шаблоны.
Если самостоятельно не получится разобраться, то помогу с файлом.
Насчет прыжка. Он не между 8-ым и 9-ым, а между 7-ым и 8-ым. Вот приготовил анимацию, схематически показывающую смещение кадров обратно к их правильному положению. Может так станет понятней?
Если самостоятельно не получится разобраться, то помогу с файлом.
Да-да, очень нужна помощь! Я уже прикидывал возможность такой реализации, но поскольку там идет смещение на кадр каждую секунду (для той пары, которая с интервалом 24 кадра), то через X секунд ещё и порядок строк нужно будет менять, т.к. последовательность выделяемых диапазонов кадров тоже будет меняться с течением времени. У этого delta.txt не очень простая структура. Мне вообще кажется, что это нереализуемая задача, а если даже ВДРУГ такое и возможно реализовать, то это скорее всего получится какая-то дико сверхсложная формула в Экселе.
Насчет прыжка. Он не между 8-ым и 9-ым, а между 7-ым и 8-ым. Вот приготовил анимацию, схематически показывающую смещение кадров обратно к их правильному положению. Может так станет понятней?
В анимациях нет нужды, я предпочитаю статичный набор картинок (это удобнее, нагляднее и главное точнее).
Да и я вообще не жалуюсь на проблемы с пониманием... вот у вас же в предыдущих сообщениях было:
На выбранном отрезке дубли (d - double) и скачки (j - jump). 3d, 8j, 13j, 22d, 27d, 33j, 37j, 47d, 51d
Приложил архив из 52 кадров и график.
В вашем архиве (panoram_move) выбранного фрагмента видео из 52 кадров указано:
3d, 8j, 13j... [т.е. 3-4 дубли, между 8-9 - скачок, и между 13 и 14 тоже скачок]
Относительно исходных физических кадров (т.е. исходного видео) скачок именно между 8-9, поэтому и возник вопрос, что получается в delta.txt надо учитывать выброшенный ранее (на 3-4) дубль и смещение на кадр, вот тогда с учетом ранее выброшенного кадра уже получится скачок между 7-8.
Скачок наблюдается на 8-м кадре. Это значит, что при выводе 7-го кадра он отличается от 6-го на прогнозируемую величину, а вот 8-ой кадр от 7-го отличается сильнее, чем ожидалось. Т.е. скачок. Я вкладывал именно этот смысл. Посмотрите архив panoram_move.zip, приложенный к сообщению. Нумерация кадров начинается с 0. Может в этом причина разного понимания записи 8j?
Таблица Excel готова наполовину. Как доделаю - выложу.
Скачок наблюдается на 8-м кадре. Это значит, что при выводе 7-го кадра он отличается от 6-го на прогнозируемую величину, а вот 8-ой кадр от 7-го отличается сильнее, чем ожидалось. Т.е. скачок. Я вкладывал именно этот смысл. Посмотрите архив panoram_move.zip, приложенный к сообщению. Нумерация кадров начинается с 0. Может в этом причина разного понимания записи 8j?
Спасибо, да, похоже именно из-за этого.
Таблица Excel готова наполовину. Как доделаю - выложу.
Прекрасно, буду ждать!
Таблица Excel готова наполовину. Как доделаю - выложу.
Доброе утро. Никаких новостей пока нет?
Прошу прощения, ноябрь был насыщенным
Спасибо за напоминание. Очень хотел вернуться к этой теме. А раз интерес есть, то и мне вдвойне интересней будет.
Причешу и выложу эту таблицу.
Очень хотел вернуться к этой теме. А раз интерес есть, то и мне вдвойне интересней будет.
Причешу и выложу эту таблицу.
Как там дела?..
MAG79, всё ещё есть шанс увидеть заветную таблицу?..
Извините что вклиниваюсь, насчет замечательного плагина GameDropFix, есть вероятность увидеть его адаптацию под VapourSynth или хотя бы AviSynth+?
Дело в том что в оригинале он не загружает ни видеокарту ни процессор на 100% а я пытаюсь улучшить большое игровое видео формата 1080p60 да еще и под 50Мбит/с.
Связка FFMpeg+AviSynth 2.6MT при SetMTMode(x,8) выдает около 20fps, это самое стабильно чего я добился но загрузка процессора неполная. SetMTMode(x,10) живет рандомное количество фреймов а потом падает.
Попробовал сам переписать .avsi скрипт плагина под AviSynth+ хоть и опыта мало, оно даже запускалось в 6 потоков и при этом даже нагружало процессор как надо, выдавало 27-32fps и рандомно падало независимо от настроек и стараний. А еще на обработанном видео сверху присутствует непонятное и не гуглящееся "AveragePlane: This filter can only be used within run-time filters ([ScriptClip], line 1)".
Вообщем я пытался
Скажем так "Доказательство Работы" у меня получилось, теперь прошу помощи у профессионалов.
Вообще в мечтах хотелось бы избавиться от синта в цепочке преобразований моих видео но все альтернативные способы поиска и интерполяции отдельных фрейм дублей либо очень медленные (butterflow) либо очень медленные и не обладают нужными механизмами определения дублей (ffmpeg mpdecimate + minterpolate). Пока веду изучение ffmpeg фильтров чтобы написать свою логику.
улучшить большое игровое видео формата 1080p60
Если на видео присутствуют только настоящие дропы (дубли предыдущего кадра на месте пропущенного), то скрипт можно сильно упростить, увеличив вероятность успешного переписывания его под Vaporsynth и Avisynth+.
Можно получить небольшой кусочек Вашего видео для экспериментов?
Таблицу так и не нашел. Видимо, безвозвратно потерялась при очередной переустановке Windows. Теперь только с нуля по памяти воспроизводить.
Еще актуально?
SmoothVideo Project → Эксплуатация SVP → Замена выпавших кадров (drop'ов) и SVP
Powered by PunBB, supported by Informer Technologies, Inc.