Nanu!? Offensichtlich ist meine letzte Nachricht aufgrund der Umstellung ins Nirwana verschwunden. :motz:
Große Unterschiede in den Pixelwerten verursachen offensichtlich diese Art von „Schwingungen“. Man muss also nur dafür Sorge tragen, dass diese Unterschiede nicht so groß werden. Eine limitierte Anwendung von FFT3DFilter könnte hier Milderung verschaffen.
Ich habe in der Zwischenzeit festgestellt, dass die bisher verwendete Methode Probleme beim Entfernen von Farbrauschen hat. Das hat jetzt aber nichts mit dem verwendeten Filter (FFT3DFilter) zu tun, sondern mit der Tatsache, dass die Farbkanäle aufgedröselt und getrennt – unter dem Etikett „Y-Kanal“ - verarbeitet werden. Das kann auch Nachteile mit sich bringen.
Es muss doch eine Möglichkeit geben, den RGB-Farbraum so in einen YUV-Farbraum umzuwandeln, und sei es in einer anderen Struktur, ohne dass man einen Verlust von Chrominanzinformationen hinnehmen muss. Ein ConvertToYV24() wäre hilfreich, steht aber erst in der Version 2.6 zur Verfügung.
Nach einiger Überlegung habe ich dann eine recht einfache Lösung gefunden. Im planaren YV12-Farbraum teilen sich doch 4 Pixel (Y-Pixel) die Farbinformationen. Diese Farbinformationen bestehen aus zwei Pixeln für die Werte U und V. Auf Bitmap-Ebene sind diese 4 Helligkeitspixel quadratisch, in einem 2x2 großen Fenster angeordnet.
Normalerweise verliert man 75 % der Chrominanzinformationen, wenn man vom RGB-Farbraum in den YV12-Farbraum wandelt – normalerweise. Was aber, wenn ich das Bild mit den RGB-Informationen vorher auf die doppelte Größe bringe, so dass ein und derselbe Pixel 4 mal vorkommt und ich anschließend erst die Farbraumkonvertierung nach YV12 vornehme? Mit PointResize() als „Pixelvervielfältiger“ dürfte das kein Problem sein. Nach der Farbraumumwandlung stehen alle Chrominanzinformationen des ursprünglichen Bildes zur Verfügung. Einzig der Luminanzkanal liegt in vierfacher Größe vor (das Bild ist doppelt so groß). Bei der Filterung des Luminanzkanals muss man nur dafür Sorge tragen, dass das Bild wieder in seiner ursprünglichen Größe vorliegt.
Aussehen würde das in etwa so:
ImageSource("$FileName", end=0, use_DevIL=False, pixel_type="RGB32")PointResize(last.Width * 2, last.Height * 2)ConvertToYV12(matrix="pc.601")# Filterlsf(strength_luma, strength_chroma)ConvertToRGB32(matrix="pc.601")PointResize(last.Width / 2, last.Height / 2)
Ein Script zum Nachschärfen würde dann wie folgt aussehen:
LoadPlugin("plugins\MaskTools 1.5.8\MaskTools.dll")LoadPlugin("plugins\MaskTools 2\mt_masktools.dll")LoadPlugin("plugins\RemoveGrain 1.0\RemoveGrain.dll")LoadPlugin("plugins\WarpSharp\warpsharp.dll")Import("lib\LimitedSharpen\LimitedSharpenFaster.avs")# ------------------strength_luma = 0strength_chroma = 0# ------------------ImageSource("$FileName", end=0, use_DevIL=False, pixel_type="RGB32")PointResize(last.Width * 2, last.Height * 2)ConvertToYV12(matrix="pc.601")lsf(strength_luma, strength_chroma)ConvertToRGB32(matrix="pc.601")PointResize(last.Width / 2, last.Height / 2)$Clip = lastReturn $Clipfunction lsf(clip input, int strength_luma, int strength_chroma) { luma = strength_luma == 0 ? input.YV12LUT(Y=2, U=0, V=0) : input.YV12LUT(Y=2, U=0, V=0).PointResize(input.Width / 2, input.Height / 2).\ LimitedSharpenFaster( \ ss_x = 1.0, \ ss_y = 1.0, \ Smode = 3, \ strength = strength_luma, \ radius = 2, \ Lmode = 1, \ wide = false, \ overshoot = 0, \ undershoot = 0, \ soft = 0, \ edgemode = 0, \ special = false, \ exborder = 0 \ ).\ PointResize(input.Width, input.Height) chroma = strength_chroma == 0 ? input.YV12LUT(Y=0, U=2, V=2) : input.YV12LUT(Y=0, U=2, V=2).\ LimitedSharpenFaster( \ ss_x = 1.0, \ ss_y = 1.0, \ Smode = 3, \ strength = strength_chroma, \ radius = 2, \ Lmode = 1, \ wide = false, \ overshoot = 0, \ undershoot = 0, \ soft = 0, \ edgemode = 0, \ special = false, \ exborder = 0 \ ) MergeChroma(luma, chroma, 1)}
Die einzigen Verluste, die man hinnehmen muss, sind Rundungsfehler bei den Farbraumumwandlungen.
Und hier, das noch nicht ausgiebig getestete Script zum Entrauschen. Die wichtigsten Parameter habe ich der Übersichtlichkeit halber in einem Block zusammengefasst. Y-, U- und V-Kanal können einzeln entrauscht werden. Mit den Parametern limit_y, limit_u und limit_v kann bestimmt werden, um wieviel sich ein Pixel ändern darf. In den Standardeinstellungen wird nur der Y-Kanal entrauscht, eine Limitierung und Nachschärfung findet nicht statt.
LoadPlugin("plugins\FFT3DFilter\FFT3DFilter.dll")
LoadPlugin("plugins\MaskTools 1.5.8\MaskTools.dll")
LoadPlugin("plugins\MaskTools 2\mt_masktools.dll")
LoadPlugin("plugins\RemoveGrain 1.0\RemoveGrain.dll")
LoadPlugin("plugins\WarpSharp\warpsharp.dll")
Import("lib\LimitedSharpen\LimitedSharpenFaster.avs")
# -------------------
sigma_y = 2.0
bw_y = 32
bh_y = 32
limit_y = 0
sigma_u = 0.0
bw_u = 32
bh_u = 32
limit_u = 0
sigma_v = 0.0
bw_v = 32
bh_v = 32
limit_v = 0
strength_luma = 0
strength_chroma = 0
# -------------------
ImageSource("$FileName", end=0, use_DevIL=False, pixel_type="RGB32")
PointResize(last.Width * 2, last.Height * 2)
ConvertToYV12(matrix="pc.601")
fft3df(sigma_y, bw_y, bh_y, limit_y, sigma_u, bw_u, bh_u, limit_u, sigma_v, bw_v, bh_v, limit_v)
lsf(strength_luma, strength_chroma)
ConvertToRGB32(matrix="pc.601")
PointResize(last.Width / 2, last.Height / 2)
$Clip = last
Return $Clip
function fft3df(clip input, float sigma_y, int bw_y, int bh_y, int limit_y, float sigma_u, int bw_u, int bh_u, int limit_u, float sigma_v, int bw_v, int bh_v, int limit_v) {
sigma_y == 0 ? input : input.PointResize(input.Width / 2, input.Height / 2).\
FFT3DFilter(
\ sigma = sigma_y,
\ sigma2 = sigma_y,
\ sigma3 = sigma_y,
\ sigma4 = sigma_y,
\ beta = 1.0,
\ plane = 0,
\ bw = bw_y,
\ bh = bh_y,
\ bt = 1,
\ ow = bw_y/2,
\ oh = bh_y/2,
\ kratio = 2.0,
\ sharpen = 0.0,
\ scutoff = 0.3,
\ svr = 1.0,
\ smin = 4.0,
\ smax = 20.0,
\ measure = true,
\ interlaced = false,
\ wintype = 0,
\ pframe = 0,
\ px = 0,
\ py = 0,
\ pshow = false,
\ pcutoff = 0.1,
\ pfactor = 0.0,
\ degrid = 1.0,
\ dehalo = 0.0,
\ hr = 2.0,
\ ht = 50.0,
\ ncpu = 1
\ ).\
PointResize(input.Width, input.Height).MergeChroma(input, 1)
LL = string(limit_y)
STR = "x "+LL+" + y < y "+LL+" - x "+LL+" - y > y "+LL+" + x ? ?"
limit_y == 0 ? last : yv12lutxy(last, input, yexpr=STR, U=2, V=2)
sigma_u == 0 ? last : last.\
FFT3DFilter(
\ sigma = sigma_u,
\ sigma2 = sigma_u,
\ sigma3 = sigma_u,
\ sigma4 = sigma_u,
\ beta = 1.0,
\ plane = 1,
\ bw = bw_u,
\ bh = bh_u,
\ bt = 1,
\ ow = bw_u/2,
\ oh = bh_u/2,
\ kratio = 2.0,
\ sharpen = 0.0,
\ scutoff = 0.3,
\ svr = 1.0,
\ smin = 4.0,
\ smax = 20.0,
\ measure = true,
\ interlaced = false,
\ wintype = 0,
\ pframe = 0,
\ px = 0,
\ py = 0,
\ pshow = false,
\ pcutoff = 0.1,
\ pfactor = 0.0,
\ degrid = 1.0,
\ dehalo = 0.0,
\ hr = 2.0,
\ ht = 50.0,
\ ncpu = 1
\ )
LL = string(limit_u)
STR = "x "+LL+" + y < y "+LL+" - x "+LL+" - y > y "+LL+" + x ? ?"
limit_u == 0 ? last : yv12lutxy(last, input, Y=2, uexpr=STR, V=2)
sigma_v == 0 ? last : last.\
FFT3DFilter(
\ sigma = sigma_v,
\ sigma2 = sigma_v,
\ sigma3 = sigma_v,
\ sigma4 = sigma_v,
\ beta = 1.0,
\ plane = 2,
\ bw = bw_v,
\ bh = bh_v,
\ bt = 1,
\ ow = bw_v/2,
\ oh = bh_v/2,
\ kratio = 2.0,
\ sharpen = 0.0,
\ scutoff = 0.3,
\ svr = 1.0,
\ smin = 4.0,
\ smax = 20.0,
\ measure = true,
\ interlaced = false,
\ wintype = 0,
\ pframe = 0,
\ px = 0,
\ py = 0,
\ pshow = false,
\ pcutoff = 0.1,
\ pfactor = 0.0,
\ degrid = 1.0,
\ dehalo = 0.0,
\ hr = 2.0,
\ ht = 50.0,
\ ncpu = 1
\ )
LL = string(limit_v)
STR = "x "+LL+" + y < y "+LL+" - x "+LL+" - y > y "+LL+" + x ? ?"
limit_v == 0 ? last : yv12lutxy(last, input, Y=2, U=2, vexpr=STR)
}
function lsf(clip input, int strength_luma, int strength_chroma) {
luma = strength_luma == 0 ? input.YV12LUT(Y=2, U=0, V=0) : input.YV12LUT(Y=2, U=0, V=0).PointResize(input.Width / 2, input.Height / 2).\
LimitedSharpenFaster(
\ ss_x = 1.0,
\ ss_y = 1.0,
\ Smode = 3,
\ strength = strength_luma,
\ radius = 2,
\ Lmode = 1,
\ wide = false,
\ overshoot = 0,
\ undershoot = 0,
\ soft = 0,
\ edgemode = 0,
\ special = false,
\ exborder = 0
\ ).\
PointResize(input.Width, input.Height)
chroma = strength_chroma == 0 ? input.YV12LUT(Y=0, U=2, V=2) : input.YV12LUT(Y=0, U=2, V=2).\
LimitedSharpenFaster(
\ ss_x = 1.0,
\ ss_y = 1.0,
\ Smode = 3,
\ strength = strength_chroma,
\ radius = 2,
\ Lmode = 1,
\ wide = false,
\ overshoot = 0,
\ undershoot = 0,
\ soft = 0,
\ edgemode = 0,
\ special = false,
\ exborder = 0
\ )
MergeChroma(luma, chroma, 1)
}
Alles anzeigen