Log in

View Full Version : ringing free sharpening without median filtering


feisty2
7th August 2016, 16:08
most filters and scripts tend to append a median filter after typical USM to kill ringings, and that's kind of lame and dumb imho, yeah, median filter clamps out ringings, it also clamps out lots of sharpening on high frequencies, and that's unwanted, generally it sharpens low and median frequencies a lot and does pretty much nothing on high frequencies, and the result of that is super ugly, looks kind of like very large radius (radius=40 or something like that) USM, I personally use "xylographed" to describe the result of such sharpening.
and I think an ideal sharpening should filter high frequencies a lot and do little to low and median frequencies to avoid "xylographing"

deconvolution (even if mathematically incorrect, aka blind deconvolution) unlike USM produces no "xylographing", but it does produce tons of ringings, and gotta find a way to eliminate deconvolution ringings without median stuff cuz median filter = xylographing filter

and I find Non Local Error(NLMeans with a zero length similarity window) works fairly nice on this

test pattern for ringing artifacts (https://en.wikipedia.org/wiki/Ringing_artifacts)

source
http://i.imgur.com/1ebZ5T8.png

deconvolution applied (zoomed to 400%, super ringin-ny)

#vaporsynth python script
def cutoff (low, hi, p):
core= vs.get_core ()
Resample = core.fmtc.resample
MakeDiff = core.std.MakeDiff
MergeDiff = core.std.MergeDiff
def inline (src, p):
upsmp = Resample (src, src.width * 2, src.height * 2, kernel="gauss", a1=100, fulls=True,fulld=True)
clip = Resample (upsmp, src.width, src.height, kernel="gauss", a1=p, fulls=True,fulld=True)
return clip
hif = MakeDiff (hi, inline (hi, p))
clip= MergeDiff (inline (low, p), hif)
return clip

def padding (src, left=0, right=0, top=0, bottom=0):
core = vs.get_core ()
Resample = core.fmtc.resample
w = src.width
h = src.height
clip = Resample (src, w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom, kernel="point", fulls=True,fulld=True)
return clip

def deconv (src):
core = vs.get_core()
sharp = core.vcfreq.Sharp(clp, 0, 0.48, 1, 1, 25, 0.28)
return cutoff(src,sharp,1)

clp = padding(clp,32,32,32,32)
clp = deconv(clp)
clp = core.std.CropRel(clp,32,32,32,32)
clp = core.fmtc.resample(clp,240,180,kernel="point")

http://i.imgur.com/I6sgG94.png

deconvolution with Non-local error (zoomed to 400%, no ringing at all)

clp = padding(clp,32,32,32,32)
srp = deconv(clp)
clp = core.knlm.KNLMeansCL(clp, 0, 32, 0, 0.001, rclip=srp)
clp = core.std.CropRel(clp,32,32,32,32)
clp = core.fmtc.resample(clp,240,180,kernel="point")

http://i.imgur.com/xtOUmRG.png

in real life case
source
http://i.imgur.com/IqfejkUg.png

LSFmod (xylographed, because that's just what USM and median filter do)

clp = havsfunc.LSFmod(clp,defaults="slow",strength=164)

http://i.imgur.com/kSjrIysg.png

deconvolution with Non-local error and block matching and stuff (just a proof of concept, not posting the code cuz that's a huge mess, actually a demo from my sharpening suite which is still under development..)
http://i.imgur.com/ytpPOnF.png

sharpening on high frequencies is not magic, but it gives the illusion like, "wow, that looks so cool, definitely not some kind of dumb sharpening" tho it's indeed some kind of dumb sharpening...

edit: typo

feisty2
7th August 2016, 18:06
FineSharp does not give much xylographing, that's what it's designed for

clp = finesharp.sharpen(clp)

http://i.imgur.com/CyY21zj.png
http://forum.doom9.org/showthread.php?p=1569248#post1569248

It's a similar story here. Sharpening and contrast enhancement do introduce "more energy" into the picture. Usually this is observed as being "better", simply because the picture is getting more "BOOM!".
However, the well-trained eye often can see that enhancement is just that: an enhancement. The picture tends to get this "fat" unsharp-masking look. Some say "woot! Rulez!", others say "oh, the poorness".

The operation of fineSharp can be looked at from two different angles. Basically it is a highpass-sharpener - perform sharpening, but don't use the lower frequencies of the obtained difference. Viewed from another angle, the operation is "energy conservation": perform sharpening, sample the introduced energy, and reduce the (blurred) local energy again, to keep local energy more close to the original. This way you don't get the "BOOM!" into the picture. But it avoids the dreaded "fat" unsharp-masking appearance.

"fat" or xylographed, guess didee was talking about the same thing here..
the result looks a bit less delicate than deconvolution judging from that lady's hair, but still pretty good, at least no xylographing like LSFmod

BUT, finesharp makes ringings, such a pain in the ass

clp = padding(clp,32,32,32,32)
clp = finesharp.sharpen(clp)
clp = core.std.CropRel(clp,32,32,32,32)
clp = core.fmtc.resample(clp,240,180,kernel="point")

http://i.imgur.com/BCZSLQ0.png

edit:
and LSFmod is not picture perfect against ringing as well..

clp = padding(clp,32,32,32,32)
clp = havsfunc.LSFmod(clp,defaults="slow")
clp = core.std.CropRel(clp,32,32,32,32)
clp = core.fmtc.resample(clp,240,180,kernel="point")

http://i.imgur.com/LvGjZhb.png
damn

edit2:
clp = havsfunc.LSFmod(clp,defaults="slow",ss_x=1,ss_y=1)
http://i.imgur.com/rEy7ESC.png
a little bit better without supersampling, but a faint dark peripheral ringing is still observable

Motenai Yoda
7th August 2016, 22:02
so IINW you're trying to remove all the low frequency halos and mantain mainly the high freq one?
can't dfttest or the old fft3dfilter/gpu be used too to do the same?

ie using dfttest
ImageReader("IqfejkUg.png")
wpad=width%32+32
hpad=height%32+32
bilinearresize(width+wpad,height+hpad,-32,-32,width+wpad,height+hpad)
converttoyv12()
b=averageblur(3)
diff1=mt_makediff(b)
diff2=diff1.dfttest(sigma=100)
diff3=mt_makediff(diff1,diff2)
mt_adddiff(diff3)
converttorgb32()
crop(32,32,-wpad+32,-hpad+32)

http://i.imgbox.com/nN0acghd.png (http://imgbox.com/nN0acghd)

http://i.imgbox.com/kC8vUvCQ.png (http://imgbox.com/kC8vUvCQ)

ImageReader("C:\Users\Casa\Desktop\IqfejkUg.png")
wpad=width%32+32
hpad=height%32+32
bilinearresize(width+wpad,height+hpad,-32,-32,width+wpad,height+hpad)converttoyv12()
#~ addgrain(50)
b=averageblur(3)
diff1=mt_makediff(b)
diff2=diff1.fft3dfilter(sigma=2.0,sigma2=1.5,sigma3=.5,sigma4=0.01)
diff3=mt_makediff(diff1,diff2)
mt_adddiff(diff3)
converttorgb32()
crop(32,32,-wpad+32,-hpad+32)
http://i.imgbox.com/5BKkW5JK.png (http://imgbox.com/5BKkW5JK)
http://i.imgbox.com/pl0RPUkn.png (http://imgbox.com/pl0RPUkn)

feisty2
8th August 2016, 01:12
unfortunately, you're wrong

so IINW you're trying to remove all the low frequency halos and mantain mainly the high freq one?

not trying to "remove" any halo/ringing after it's already there, what I did simply prevented ringing from even happening
mantain mainly the high freq one
what? I'm not maintaining any ringing, like any kind, non local error kills ringings, simple like that,
it does not kill low frequency halo/ringing, and there's no such thing as low frequency ringing
ringing happens because finite Fourier series expansion fails at discontinuities, and by "discontinuities", it goes like sharp transitions in time domain, or high frequencies in transformed domain
low frequencies are continuous, and finite Fourier series expansion works expectedly on continuous functions, which means ringing will not happen

feisty2
8th August 2016, 01:38
can't dfttest or the old fft3dfilter/gpu be used too to do the same?
no, you need a time domain filter to kill ringings completely like 100%

diff2=diff1.dfttest(sigma=100)
???I don't get this, this does not kill any ringing, the sigma parameter in DFTTest was designed for white noise which is something featuring a constant power density among ALL frequencies, that's why it's like this, simple one parameter is enough to white noise, go "sstring" instead if you're dealing with stuff with variable power spectral densities like ringing, and it won't work, cuz I've tried that like last year or so

and your approach does produce ringings.
http://i.imgur.com/1P7znb9.png

and it also sharpens pretty much nothing but noise, which is also unwanted and totally makes sense since DFTTest is a denoiser


and no, KNLMeansCL is not a denoiser here, no one does denoising with h=0.001, it connects the source clip and the sharpened clip by the non-local error of the sharpened clip, which shifts high frequencies from the sharpened clip to source clip without ringing

Nevilne
8th August 2016, 01:48
blur/ringing/aliasing

you can only avoid 2. (with non-warping sharpeners obviously)

other sharpeners just don't place as much emphasis on ringing.

feisty2
8th August 2016, 02:23
blur/ringing/aliasing

you can only avoid 2. (with non-warping sharpeners obviously)

other sharpeners just don't place as much emphasis on ringing.

I chose to avoid blurring and ringing obviously
and I did it for 2 reasons:
1. sharpening does not produce pointresize kind of intolerable aliasing, and sharpening aliasing looks acceptable on photographic videos most of the time
2. aliasing could be further reduced or removed by other non-sharpening filters, it tends to disappear along with noise after block matching based averaging and non-linear amplifying

feisty2
8th August 2016, 09:06
sharpening has never produced any obvious aliasing from my experience, yeah there's this ringing - aliasing tradeoff just like sinc and nearest neighbor and all that resampling stuff, but I have never seen any not neglectable aliasing caused by sharpening, apparent aliasings come from point resize, cheap deinterlacing or whatever, but not sharpening, so I was wondering why would someone even bother to bring up the aliasing topic here.
and I found the answer, there's this ancient XSharpen filter, which belongs to reordering filters category just like median filter, it was once widely used like eons ago, and it indeed produces tons of severe and unacceptable aliasings, but it's because of its nature, being a reordering filter gives shit like that.

both deconvolution and non-local error are not reordering filters, they might produce fairly subtle aliasings, but never the XSharpen kind of aliasing

blur/ringing/aliasing

you can only avoid 2. (with non-warping sharpeners obviously)

other sharpeners just don't place as much emphasis on ringing.

warpsharp produces aliasings, just for the record

BakaProxy
9th August 2016, 00:25
Just for the record, this in practice being a fancy Xsharpen, how many magnitudes is it slower?

Verstuurd vanaf mijn SM-A500FU met Tapatalk

feisty2
9th August 2016, 02:34
Just for the record, this in practice being a fancy Xsharpen, how many magnitudes is it slower?

Verstuurd vanaf mijn SM-A500FU met Tapatalk

The mechanism is completely different from xsharpen
It's a fancy fine sharp actually, both are not xylographing.
I care more about "xylographing" than ringing cuz that's even uglier.

BakaProxy
9th August 2016, 02:38
The mechanism is completely different from xsharpen
It's a fancy fine sharp actually, both are not xylographing.
I care more about "xylographing" than ringing cuz that's even uglier.
So then how does it compare against finesharp? Performance wise.

Verstuurd vanaf mijn SM-A500FU met Tapatalk

raffriff42
9th August 2016, 04:26
https://www.dropbox.com/s/5s3jemzwi11y9vr/ring-free-sharpening-201-org.png?raw=1

https://www.dropbox.com/s/q2641sim0g4fpxc/ring-free-sharpening-202-S05.png?raw=1

https://www.dropbox.com/s/4j4dpmlxwsm0j7d/ring-free-sharpening-206-S1%2CE24.png?raw=1

What if you killed sharpening on edges (which is where ringing becomes visible) using a suitable edge mask. aWarpSharp2 (http://avisynth.nl/index.php/AWarpSharp2/aWarpSharp2) for one does this.
mhthr=24 ## edge detection threshold - must be tuned
edgemask=mt_edge("hprewitt", thY1=mhthr, thY2=mhthr)
\ .mt_expand.Grayscale.Invert.Blur(1.2)
Overlay(Sharpen(1.0), mask=edgemask) ## use any sharpener here
The tricky part is choosing good edge mask settings for a given image.

(100% accurate ringing detection would require knowledge of the original waveform, which by definition is not available when doing image restoration. The presence of ringing can be guessed at by looking for certain frequencies, certain edge profiles etc, but these can only be guesses. Of course, edge detection is guesswork too.)

feisty2
9th August 2016, 04:36
https://dl.dropboxusercontent.com/u/108089426/Screenshots/ring-free-sharpening-201-org.png

https://dl.dropboxusercontent.com/u/108089426/Screenshots/ring-free-sharpening-202-S05.png

https://dl.dropboxusercontent.com/u/108089426/Screenshots/ring-free-sharpening-206-S1%2CE24.png

What if you killed sharpening on edges (which is where ringing becomes visible) using a suitable edge mask. aWarpSharp2 (http://avisynth.nl/index.php/AWarpSharp2/aWarpSharp2) for one does this.
mhthr=24 ## edge detection threshold - must be tuned
edgemask=mt_edge("hprewitt", thY1=mhthr, thY2=mhthr)
\ .mt_expand.Grayscale.Invert.Blur(1.2)
Overlay(Sharpen(1.0), mask=edgemask) ## use any sharpener here
The tricky part is choosing good edge mask settings for a given image.

(100% accurate ringing detection would require knowledge of the original waveform, which by definition is not available when doing image restoration. The presence of ringing can be guessed at by looking for certain frequencies, certain edge profiles etc, but these can only be guesses. Of course, edge detection is guesswork too.)

I did not and will not use any edge mask, my goal is to sharpen all high frequency components including edges without ringing, and besides, an edgemask usually masks out all high frequency components, edge or not, then I got nothing to sharpen!

feisty2
9th August 2016, 05:02
or a universal explanation for this,
the computational costs of Non-Local algorithms are VERY expensive, you don't actually expect to get the same quality with a super CHEAP edge mask?
reality is not that nice..

feisty2
13th August 2016, 17:39
http://forum.doom9.org/showthread.php?t=173775
if anyone's still interested and wanna do some tests

CkJ
25th August 2016, 17:47
http://forum.doom9.org/showthread.php?t=173775
if anyone's still interested and wanna do some tests
It looks interesting, but can you make an avisynth version? I'm not familiar with vapoursynth. :thanks:

Edit: Nevermind, I just noticed BM3D (one of dependencies) is not support for avisynth.

royia
25th October 2016, 18:41
Could you explain mathematically what you're doing?

The results looks cool but I don't understand what you do.

manolito
18th July 2020, 01:12
Sorry for bumping an older thread, but this stuff is still relevant IMO...

I do a lot of conversions where I downconvert captured HD sources to SD, and over time it has become a habit to always call FineSharp() just after the resizer. Restores some of the HD crispness without any visible artifacts (the slight ringing has never bothered me), it is fast, and FineSharp always works well with the defaults, no tweaking params for different sources.

After seeing the new FranceBB thread about digitizing old analog master tapes I thought that I might try to find a postprocessing filter for FineSharp which removes the ringing which FineSharp creates. The KNLMeans filter is not an option for me for several reasons, so I started looking for Deringing / Dehaloing filters which might do the job for me.

After doing some research I ended up testing LazyDering, DeHalo_alpha and FineDehalo (based on DeHalo_alpha). Frankly I could not detect any visible artifacts with any of these filters, but speed was different.

LazyDering was the fastest by far, followed by DeHalo_alpha by a wide margin. Last was FineDehalo (all using their defaults).

Anyone has some experience with these filters? So far I prefer LazyDering for its speed. But I read in an earlier post by feisty that he does not like WarpSharp based deringing at all.

Any advice?

manolito
19th July 2020, 22:54
I extended my Dering / Dehalo tests to include BlindDehalo3, abcxyz and YAHRMod. For the comparison I used the test pattern from the first post. The results were zoomed to 400%, you can download the PNG images here:
https://www.sendspace.com/file/oc0nzi


My comments:

First of all the ringing introduced by FineSharp is much much weaker than in the deconvolution example by feisty from the first post. Hard to say if this slight ringing is really noticeable in real world videos.

LazyDering seems to be a little too lazy. There is almost no ringing removed.

BlindDehalo3 and to a lesser degree also abcxyz create visible artifacts around the edges. At least for this synthetic test pattern both are not useable.

DeHalo_alpha blurs the edges way too much.

FineDehalo is better, but it leaves a ringing dot just at the tip of the sawtooth pattern. Hard to say if this will be visible in real world videos.

YAHRMod is the surprise winner for this test.


But then again I have no idea how these results using a synthetic source can be translated to real movies (I am not talking about Anime). It is also possible that the results for some of these filters can be improved by tweaking their parameters. And the last question is if I should even bother. I only use FineSharp for SD videos, and the ringing introduced by FineSharp is not very obtrusive at all.

I will do some real world conversions using FineSharp together with YAHRMod and see if I find any problems...

feisty2
19th July 2020, 23:09
you should probably create a new thread instead of resurrecting this eons old thread with irrelevant content.
the thread was about sharpening algorithms that are designed to not introduce ringing artifacts in the first place, not removing ringing artifacts introduced by cheap unsharp masking stuff.

manolito
20th July 2020, 00:43
Get off your high horse...

"eons old thread" means that a thread which is 4 years old must be totally irrelevant today? Grow up please.

I am result orientated. I do not care which method was used to achieve this particular result. If you achieve the same result by "not introduce ringing artifacts in the first place" or if you use postprocessing after the sharpener to get the same result is totally irrelevant. And BTW FineSharp is NOT "cheap unsharp masking stuff".

feisty2
20th July 2020, 01:01
Grow up please.



oh, personal attack, this is a new low even for old fart like you sweetie. your comment is a violation of rule 4.

and if you're too old to understand the difference between "not introducing ringing in the first place" (which only takes effect on the difference produced by the sharpening filter and thus does not harm the original input) and "removing ringing afterwards" (which damages the coupled result as a whole), just shut up, will you?

manolito
20th July 2020, 01:12
just shut up, will you?

I would rather spank your ass real good... :devil: