Показать сообщение отдельно
Старый 30.07.2008, 15:09   #14
Polad
ВИП
Медаль пользователю. ЗОЛОТО Любитель
Аватар для Polad
Регистрация: 30.03.2007
Адрес: Тридевятое царство
Сообщения: 267
Репутация: 42
14. Подавление ореолов

Близкой задачей к ограниченному повышению резкости является подавление имеющихся ореолов, которые и происходят из предшествующего "тупого" повышения резкости, и часто имеются на VHS и некоторых других источниках.
Существует специальный плагин FixVHSOversharp (разработчик "MrTibs"), состоящий из двух функций (для левого и правого края), работающих отдельно для каждой строки, то есть только в горизонтальном направлении, ищущих области с яркостью, отличающейся от яркости соседних областей. Параметрами являются: порог изменения яркости в ореоле, ширина области детектирования, и смещение рабочего пикселя от контрольного.
#Пример скрипта 14.1
# Подавление ореолов VHS
LoadPlugin("FixVHSOverSharp2_5.dll") # загружаем плагин
AviSource("d:videoVHS.avi") # видеофайл формата YUY2
FixVHSOversharpL(30,12,8) # левый край
FixVHSOversharp(30,14,10) # правый край
Фильтр работает по довольно простому алгоритму, предназначен для сильных ореолов, и может в ряде случаев произвести артефакты, в частности на контрастных титрах.
Делался ряд попыток составить специальные скрипты для более эффективного удаления ореолов, из которых, пожалуй, наиболее удачным (и последним), является Dehalo_alpha (составитель "Didee"), несмотря на статус версии "альфа". Скрипт использует плагин MaskTools (разработчики "Kurosu", "Manao") и плагин Repair из пакета RemoveGrain (разработчик "Kassandro").
# Пример скрипта 14.2
# Определение функции DeHalo_alpha (составитель Didee)
function DeHalo_alpha(clip clp, float "rx", float "ry", float "darkstr", float "brightstr", float "lowsens", float "highsens", float "ss")
{
rx = default( rx, 2.0 )
ry = default( ry, 2.0 )
darkstr = default( darkstr, 1.0 )
brightstr = default( brightstr, 1.0 )
lowsens = default( lowsens, 50 )
highsens = default( highsens, 50 )
ss = default( ss, 1.5 )
#
LOS = string(lowsens)
HIS = string(highsens/100.0)
DRK = string(darkstr)
BRT = string(brightstr)
ox = clp.width()
oy = clp.height()
uv = 1
uv2 = (uv==3) ? 3 : 2
#
halos = clp.bicubicresize(m4(ox/rx),m4(oy/ry))
.bicubicresize(ox,oy,1,0)
are = yv12lutxy(clp.expand(U=uv,V=uv),
clp.inpand(U=uv,V=uv),"x y -","x y -","x y -",U=uv,V=uv)
ugly = yv12lutxy(halos.expand(U=uv,V=uv),
halos.inpand(U=uv,V=uv),"x y -","x y -","x y -",U=uv,V=uv)
so = yv12lutxy( ugly, are,
"y x — y 0.001 + / 255 * "+LOS+" — y 256 + 512 / "+HIS+" + *")
lets = maskedmerge(halos,clp,so,U=uv,V=uv)
remove = (ss==1.0) ? clp.repair(lets,1,0)
: clp.lanczosresize(m4(ox*ss),m4(oy*ss))
.logic(lets.expand(U=uv,V=uv)
.bicubicresize(m4(ox*ss),m4(oy*ss)),"min",U=uv2,V= uv2)
.logic(lets.inpand(U=uv,V=uv)
.bicubicresize(m4(ox*ss),m4(oy*ss)),"max",U=uv2,V= uv2)
.lanczosresize(ox,oy)
them = yv12lutxy(clp,remove,
"x y < x x y — "+DRK+" * — x x y — "+BRT+" * — ?",U=2,V=2)
#
return( them )
}
# вспомогательная функция
function m4(float x) {return(x<16?16:int(round(x/4.0)*4))}
Функция находит области ореолов путем сравнения результата расширения и сужения масок цветовых каналов в оригинальном и сглаженном путем изменения размера кадров, и так далее... Новичкам необходимо знать, что в этом и других сложных скриптах часто используют полезную функцию YV12LUTxy из плагина MaskTools, которая производит попиксельные вычисления результата, исходя из значений пикселей в кадрах двух клипов-аргументов (х и y), при этом формула вычисления задается строкой в обратной записи (например, "x y -" означает из пикселей первого клипа X вычесть значения второго Y).
Можно иметь функцию DeHalo_alpha в отдельном файле DeHalo_alpha.avs, и затем импортировать в основной скрипт. Функция имеет следующие параметры:
  • "rx" , "ry" — радиусы по горизонтали и вертикали для удаления ореолов (от 1 до 3, по умолчанию 2);
  • "darkstr", "brightstr" — факторы степени для темных и светлых ореолов (от 0 до 1.0 нестрого, по умолчанию 1.0);
  • "lowsens" — чувствительность к слабым изменениям, полностью принимаемым (от 0 до 100, по умолчанию 50);
  • "highsens" -чувствительность к сильным изменениям, полностью отвергаемым (от 0 до 100, по умолчанию 50);
  • "ss" — фактор промежуточного сверхразрешения для избегания ступенек (по умолчанию 1.5)
Функция DeHalo_alpha разрабатывалась для прогрессивного видео цветового формата YV12. Чересстрочное видео необходимо предварительно разделить на поля, и целесообразно уменьшить вертикальный радиус ореола вдвое.
# Пример скрипта 14.4
# Удаление ореолов с функцией Dehalo_alpha
LoadPlugin("MaskTools.dll")
LoadPlugin("RepairS.dll")
Import("Dehalo_alpha.avs") # импортируем функцию в скрипт
AviSource("d:videoVHS.avi") # видеофайл (VHS) формата YUY2
ConvertToYV12(interlaced=true)
SeparateFields() # делим на поля
Dehalo_alpha(rx=2.0, ry=1.0) # уменьшаем вертикальный радиус,
# так как поля половинной высоты
Weave()
По всей видимости, подавление шума лучше делать до удаления ореолов, для более четкого их нахождения. Применение функции подавления ореолов может смазать некоторые детали изображения. Попробуйте подобрать оптимальные параметры.
Отметим, что возможны и другие решения проблемы, например, в частотной области с плагином FFT3DFilter. Пока они не отработаны, но как предварительный вариант попробуйте вместо DeHalo_alpha следующую команду, использующую повышение резкости с обратным знаком для понижения высоких частот с большой амплитудой:
fft3dfilter(bt=-1,sharpen=-1.5,smin=200,smax=90000,scutoff=0.45,interlaced=tr ue).
Снижение резкости и ореолов более плавное, чем в Dehalo_alpha. В новых версиях FFT3DFilter появилась специальная опция "dehalo", что может позволить чистить шумы, повышать резкость и подавлять ореолы одной командой.