Log in

View Full Version : New filter: NoMoSmooth


Pages : [1] 2

SansGrip
7th November 2002, 05:31
While playing with code I wrote to apply 3x3 matrices temporally to 9 consecutive frames I was struck with an idea for a temporal smoother that might not be as suceptible to ghosting as others.

Edit 3: See this post (http://forum.doom9.org/showthread.php?s=&threadid=37471#post207385) and on for a rewritten version implementing motion-adaptive spatial-temporal smoothing.

Here's my first attempt at implementing it. It's proof of concept code, and as such is very (I mean extremely) slow and might not even do anything on your system other than crash. That said, it works ok on mine ;).

See the docs (http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-readme.html) for more information on the algorithm.

As I said this is not intended to be a proper "release" of a filter. I'm more interested in receiving as much feedback as possible (positive or negative) than putting out something you can actually use in your encodes.

If people think this filter shows promise I'll fix it up.

Have fun and don't blame me ;).

Edit: Yes, I had some difficulty coming up with a good name. The one I chose was inspired by TomsMoComp and I think is fairly appropriate. Feel free to suggest another ;).

Edit 2: Removed links to old version.

High Speed Dubb
7th November 2002, 07:13
It’s working well here — no crashes, and no artifacts.

I like the aspect that you give up averaging beyond a certain time if that timepoint shows evidence for motion. It would be interesting to see the same trick used for spatial smoothing, in which an intervening pixel of a different color would prevent averaging with a pixel further away.

The threshold of 2 is probably a little too low to make this effective. At that value, even very light noise is going to cut the averaging range short. At least for over the air stuff, you can expect a mean difference of about 4 to 7 (for luma and chroma combined) even in stationary areas. (Thanks go to folks over in the video capture forum for that number.)

If you decide to put more effort into this sequential approach, you might eventually want to look up hidden Markov models (HMMs). You could use an HMM to infer the probability that motion began at any particular time in the sequence.

SansGrip
7th November 2002, 13:28
The threshold of 2 is probably a little too low to make this effective.

That's just the default I settled for on for my test material, which is a slightly noisy DVD. I didn't try on captured material yet.

You could use an HMM to infer the probability that motion began at any particular time in the sequence.

Sounds interesting. I'll ask Dr Google :).

SansGrip
7th November 2002, 17:12
Since my specified minimum of one person gave some positive feedback (and that person happened to be someone whose opinion I respect :)) I rewrote the filter and optimized the algorithm.

In the process I improved performance somewhat (it's now only pretty darn slow ;)), discovered I could eliminate one of the two thresholds, and unfortunately had to lose "show" mode. Shouldn't matter too much though as it was mainly for debugging.

With some more positive feedback I'll go for a first release with (hopefully) better performance and any nice changes people might suggest.

Edit: Removed links to, er, redundant version ;).

sh0dan
7th November 2002, 18:15
I'm sorry, but what's the difference between this filter and C3D, except the bigger radius and slower processing?

SansGrip
7th November 2002, 18:22
I'm sorry, but what's the difference between this filter and C3D, except the bigger radius and slower processing?

C3D does both spatial and temporal smoothing, this does only temporal. And the ability to use a larger radius without ghosting makes the averaging more accurate.

sh0dan
7th November 2002, 18:46
Oh - I see - thanks for the clarification :)

Edit: btw, the results looks good - smooths temporal noise very well, without any ghosting, and the speed is very acceptable.

SansGrip
7th November 2002, 19:18
the results looks good - smooths temporal noise very well

I'm testing the code with radii up to 15 -- obviously unrealistic -- with good results (except the speed ;)). Though when the radius gets very large there's more danger of artifacts from scene changes, though theoretically these shouldn't be too noticible. I'm contemplating adding an optional scene-change detector in there.

At the moment I'm pondering an interleave scheme such as in TemporalSoften which should improve performance greatly (e.g. incrementing one pointer instead of one for each frame in the radius).

and the speed is very acceptable.

Either you're being kind or you've only tried low radii (3-5) or you're running it on a quad Xeon system :D. I don't think the speed is acceptable at the moment, though as I said interleaving will help that. I fear any improvements beyond that will have to wait until I've learned assembler (though this gives me good incentive to actually do it :)).

SansGrip
7th November 2002, 19:51
I like the aspect that you give up averaging beyond a certain time if that timepoint shows evidence for motion.

That's gone (at least for the moment) because I find it works just as well, if not better, if I just skip that value and continue. Edit: This seems to make it identical to TemporalSoften. Note to self: Read Avisynth source properly before coding an idea ;).

It would be interesting to see the same trick used for spatial smoothing, in which an intervening pixel of a different color would prevent averaging with a pixel further away.

I'm coding it right now :). Edit: No i'm not.

sh0dan
7th November 2002, 21:05
Originally posted by SansGrip
[i]Either you're being kind or you've only tried low radii (3-5) or you're running it on a quad Xeon system :D.

Running it on a TBird 1.2Ghz, and I'm comparing the speed to temporalsoften. Speed is relative to the complexity to me. :)


It would be interesting to see the same trick used for spatial smoothing, in which an intervening pixel of a different color would prevent averaging with a pixel further away.

I'm coding it right now

This is one of the tricks SmoothHiQ uses - the main problem is that you very seldom have straight lines to the center pixel, except when x or y is the same. I did a test before v1.0, where I actually tested all pixels inbetween pixel x (in the window around the pixel), based on a line drawn from it. It was _painfully_ (and I mean painfully) slow, and gave a very minimal visual improvement (if any).

Testing straight lines (with same x and y) is a posibility, but I don't think it'll give you much. Perhaps as gradiant improver on anim-e?

You should rather try different methods of weighing, and experiment with "frames further away have less influence", and "frames with pixels with bigger difference to the current has less impact on it".

(Example is in "float", but translates to fixed ints)
For the first you could create a table, where:
weight_frame[i] = 1/i, where i is your frame offset from the current frame. Then normalize the values in weight_frame[], so they add up to 1 (or a fixed point value, 65536 for example) .
Use this as a weight table. So you have:

c_frame = current frame number
c_ip = input pixel from frame c
ap = accumulated weighed pixels
aw = accumulated weights
ipw = inverse pixel weight
ip = input pixel (from the current frame 0)
op = output pixel

then for a passed pixels:

ap += weight_table[c_frame] * c_ip
aw += weight_table[c_frame]

For non-passed pixels you do nothing. To calculate the final pixel use:

ipw = 1 - aw
op = (ap + (ipv * ip)) / 1

Divide by one is to show that if you use fixed point you must divide with the accumulated weight value. This is a constant, so there is no divide in the algorithm (use >>16 for example).

So the fewer of the neighboring frames pass, the less the current pixel will be blurred. You can also do a "weigh with difference", where you have another table, where:

diff_table[i] = max(0,(1/threshold)*(threshold-i)). Then calculate ap and aw as:

weight = weight_table[c_frame] * difftable[abs(c_ip-ip)]
ap += weight* c_ip
aw += weight


- This is basicly what I use in SmoothHiQ for better averaging in "Weighed Average" mode.

neily
7th November 2002, 23:08
SansGrip,

If you want someone to agree with you, yes it is very slow :) However I was more concerned about the lack of effect at the ends of a clip. The first frames included in the radius do not seem to get much change. I would have thought that they should at least by influenced by half the value of the radius frames rather than none at all.

SansGrip
7th November 2002, 23:18
The first frames included in the radius do not seem to get much change.

At the moment the first radius / 2 frames don't get any change.

I would have thought that they should at least by influenced by half the value of the radius frames rather than none at all.

They will, if this filter turns out to be useful enough to continue development on :). Edit: Seems it is useful, so useful in fact that it's been in the core for ages :D. I'm somewhat red-faced now. I'll keep working on it and try to come up with something that makes it different ;). Hey -- at least I know I'm thinking the right things ;).

High Speed Dubb
8th November 2002, 03:24
Sh0dan,

Very cool — That sounds like a very nice design. I really strongly favor the weighted average approach. I even have a convoluted, approximate justification for why that (threshold - difference)/threshold weighting should be fairly close to optimal.

SansGrip,

I did warn you that HMMs were my pet method. ;) And I promise to do my best to unearn whatever respect you might have for my opinion. ;)

The sequential approach does have some merit to it. For the most part, it shouldn’t make any difference. After all, if there’s a little evidence for motion at t = -1, then there will probably be more at t = -2. That’s probably why you didn’t see much effect when you removed it.

But there’s a very important exception. Motion over textures will often have a pixel value wavering around some value. In that case, it’s common for older pixel values to be closer than recent pixel values — but you still don’t want to average with those older values.

That may seem a little esoteric, but motion over low contrast texture is usually the hardest case for a temporal smoother, so it makes some sense to concentrate on it. (I usually set my smoothers to the point that they no longer mangle faces. So a small improvement with faces means I can use more aggressive settings for everything else.)

In other words, I’d take a close look at slowly moving smooth facial features, and see if the sequential version was able to reduce blending.


So thinking about Sh0dan’s description of SmoothHiQ, here’s another possible sequential method.

Starting with the current pixel (t=0), travel forward in time pixel by pixel. Probability(t=0 is stationary relative to t=0) = 1. Then let

Probability(t=n is stationary relative to t=0) =
Probability(t=n-1 is stationary relative to t=0)*Probability(t=n is stationary, given that t=0 through t=n-1 are stationary)

where
Probability(t=n is stationary, given that t=0 through t=n-1 are stationary) = (threshold - |Y(t = n) - Y(mean of 0 through n-1)|)/threshold (but limited to a minimum of 0)

(That last formula is a fudge, but is probably a good enough estimate to work with.)

So you can get Prob(t=1 is stationary) based on Prob(t=0 is stationary), get Prob(t=2 is stationary) based on Prob(t=1 is stationary), and so on. The exact same process can be run backward in time.

Then the final pixel value would be
Sum_over_pixels( pixel_color*Prob(pixel_is_stationary) ) / Sum_over_pixels( Prob(pixel_is_stationary) )

LigH
8th November 2002, 09:07
@ SansGrip:

Seems that you suddenly removed it from your page; I hope I'll find your idea soon in another one of your projects when it is getting ready...

SansGrip
8th November 2002, 14:40
Seems that you suddenly removed it from your page; I hope I'll find your idea soon in another one of your projects when it is getting ready...

That particular version was redundant. I'll post 0.0c if there's merit in the tweaks I'm making now :).

@sh0dan & HSD:

Thanks for the suggestions, I was thinking about them last night and am currently playing :).

SansGrip
9th November 2002, 00:07
I've been watching variously smoothed clips very carefully and have come to the conclusion (that of course many before me have reached) that detecting motion is the key to retaining detail.

To that end I've been playing with various algorithms and have come up with one that seems to work quite well. It effectively differentiates between motion and moderate noise (between 1-3). Since posting grabs would be pointless, I've made a 2.62mb 27-second clip (http://www.jungleweb.net/~sansgrip/modet-demo.mpg) to demonstrate. I know it's bad quality, but it is small ;).

The detection was done at 720x480 and then it was simple-resized down to its current resolution.

Anyway, before I start attempting to make it do something useful like smoothing, I thought I'd run it by people here to see if they can spot any obvious problems with the output. The threshold for this clip might have been a little on the sensitive side, but it's pretty finely tunable.

I'd appreciate any comments :).

High Speed Dubb
9th November 2002, 02:07
That looks reasonably good. It definitely gets the moving edges. Depending on the use for the motion estimate, that could be all you need.

The hard part for motion detection is identifying the insides of objects/areas in motion as moving. The green areas are missing the lower contrast stuff in faces and in the grass (toward the end of the clip). That’s very difficult to manage — I’m still looking for a better way to do it. But it can affect picture quality, since incorrectly smoothing/weaving inside textures doesn’t look so good.

SansGrip
9th November 2002, 05:37
Yes, it's time again to put my head on the block and see what comes a-swingin' ;).

Here's 0.0c, still proof of concept (source available here). It incorporates the abovementioned motion detector, with temporal smoothing applied to static areas and spatial smoothing to areas in motion.

While the motion detection algorithm is optimized (runs near real-time at 720x480 on my system) the smoothers aren't (and don't), with the spatial smoother being especially slow. This will be fixed if there's interest in me doing so.

Other caveats are it passes through pixels within spatial_radius of the edges and frames within temporal_radius of the ends of the clip.

See the documentation (http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-readme.html) for more information and usage.

Here we go again... :)

Edit: Removed links to old version.

SansGrip
10th November 2002, 00:45
My observations so far:

It seems more tolerant of higher temporal settings (both radius and threshold) than spatial. High spatial settings (particularly threshold) seem to produce much more noticible artifacts.

Increasing caching with SetMemoryMax seems to increase speed, especially with a higher temporal radius.

Comments and suggestions always welcome :).

SansGrip
10th November 2002, 23:18
In order to teach myself YV12 I decided to practice on my newest filter.

To that end, here is 0.0c built for Avisynth 2.5 (http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-YV12-0.0c.zip). Note: At the moment it only works in YV12. Also note it's not necessarily faster because it's totally unoptimized.

Currently the YV12 version only processes luma. When I've got a better handle on things I'll reintroduce chroma smoothing, hopefully in the next couple of days.

This was just a quick release (I didn't update the docs yet) to make sure that it works for people other than myself :).

I'd be extremely grateful for feedback from those testing 2.5.

iago
11th November 2002, 17:23
@SansGrip

I'll run some tests now on motion parts of a couple of sources and report back the results soon.

regards,
iago

iago
11th November 2002, 18:23
@SansGrip

Some short test results of a high motion scene with "NoMoSmooth YV12":

XviD Koepi's 09112002-1 build (constant quant 2 - Qpel - MPEG quantization) / AviSynth 2.5 alpha (07-11-2002) / VirtualDubMpg2 (modified by Shodan) / Marc's mpeg2dec3 v0.91 / LanczosResize(640,272)

compressibility:
----------------
normal encode: 38804 kb
NoMoSmooth() encode: 38556 kb
NoMoSmooth(motion_threshold=10) encode: 38220 kb

(temporal/spatial defaults too low, or something else?)

visuals/artifacts:
------------------
thin white lines constanly appearing on all four sides of the picture.

speed:
------
not too bad, but I guess it can be optimized?


regards,
iago

SansGrip
11th November 2002, 18:48
(temporal/spatial defaults too low, or something else?)

Probably a combination of no chroma smoothing in YV12 mode and the high-motion nature of the clip.

Those are expected (and, for me, desirable) results from a high-motion clip, since it's designed to use spatial smoothing where it won't be noticed, i.e. areas in motion. Obviously spatial smoothing already blurred areas will only increase compressibility a little (and that's what we saw). In a more "real world" encode there should be a lot more static areas and thus room for the temporal smoother to kick in. I think this is where the compressibility gains will be made.

Either that or it's a flawed concept ;).

Anyway, my main concern was that someone other than me could get some output with 2.5 and YV12. Now I know the YV12 code works I can go ahead and implement it properly, along with porting the rest of my filters.

thin white lines constanly appearing on all four sides of the picture.

Yes, proper edge handling is another thing I left out of the YV12 version ;).

speed not too bad, but I guess it can be optimized?

Greatly.

iago
11th November 2002, 19:18
@SansGrip

Well, nice to hear those ;). So, I'm sure we'll soon have an optimized version of NoMoSmooth with proper edge handling ;). Using motion detection and applying more (especially spatial) smoothing to high-motion areas in the picture to eliminate blocking and to save bits is an important concept (just like the idea behind Marc's MAM filter I guess).

Btw, can you elaborate a bit more on the motion detection algo? How does it work and within what ranges, etc.? (Sorry if these are already answered.)

Also, increasing spatial_radius and spatial_threshold while keeping the other values as default helps increasing compressibility too (as expected with a high-motion clip in my example).

For instance, NoMoSmooth(spatial_radius=3,spatial_threshold=6) decreased filesize to 34816 kb in my short test with the same previously mentioned encoding parameters.

regards,
iago

SansGrip
11th November 2002, 19:59
So, I'm sure we'll soon have an optimized version of NoMoSmooth with proper edge handling ;).

I'm working on it right now :).

Btw, can you elaborate a bit more on the motion detection algo? How does it work and within what ranges, etc.?

It's very simple (thus fast), yet surprisingly effective. It's very good at differentiating between noise and motion, picking up all moving edges of the image. It's not able to detect motion inside "flat" low-contrast areas, but since these aren't changing much temporal smoothing is probably more suitable anyway.

Basically it takes a 3x3 block of the current frame and the previous frame, sums the temporal difference of each of the pixels, then compares the absolute value of the sum with the threshold. In this way it favours change that's in the same spatial direction for each pixel, thus significantly reducing its sensitivity to noise over a SAD approach. I'd call this ASD (absolute sum of differences) if I wasn't sure it already has a name ;).

If you look at show mode while playing with the threshold you'll see it can detect a large amount of real motion before it starts getting false hits from noise.

For instance, NoMoSmooth(spatial_radius=3,spatial_threshold=6) decreased filesize to 34816 kb in my short test with the same previously mentioned encoding parameters.

Yes, I set the spatial radius low for speed reasons. The default spatial threshold is more or less a value I found maintained good detail in my test source. It's likely they're not the best values.

iago
12th November 2002, 10:26
@SansGrip

Thanks for the explanation about motion detection algo. Also, what's the significance of the default 40 value for motion_threshold?

Well, I mean, I can see that if you lower motion_threshold, say to 10, more spatial smoothing will be applied to the entire clip due to more sensitivity to motion, and less temporal smoothing to the overall clip since less parts in the clip will be considered static areas, leaving less room for temporal smoothing. (And vica versa of course.)

Or, to put it more clearly, how high can you go with the motion_threshold and what's the upper limit of it? ;) I'm asking this to have a (relatively) better understanding of possible ranges to be applied when setting the motion_threshold for specific clips.

best regards and thanks again for your efforts and useful work,
iago

SansGrip
12th November 2002, 14:52
Thanks for the explanation about motion detection algo. Also, what's the significance of the default 40 value for motion_threshold?

It's simply a value I found picked up a lot of motion without getting false hits from noise (with the source I was testing). It very well might not be the best default for it. More tests are needed.

Well, I mean, I can see that if you lower motion_threshold, say to 10, more spatial smoothing will be applied to the entire clip due to more sensitivity to motion

Yep, and with 10 you'll likely see false hits in the motion detection, unless you have a very clean source.

Or, to put it more clearly, how high can you go with the motion_threshold and what's the upper limit of it? ;)

Well, since it processes a 3x3 block from two frames, if you had one totally black (=0) block followed immediately by one totally white (=255) block the motion detection would reach 255 * 9 = 2295. I've never tried a setting this high though ;).

I considered normalizing it to 1-100 or whatever, but felt that I'd rather have fine-grained control than an easy-to-remember maximum, at least while testing.

I'm asking this to have a (relatively) better understanding of possible ranges to be applied when setting the motion_threshold for specific clips.

I've yet to try it with a very noisy source to see how that affects the detection.

Bear in mind that if you set it too high then temporal smoothing will start to be applied to more and more areas in motion, leading to the classic weird artifacts of strong temporal smoothing, which I find most noticible in faces.

If you go too low the detector will start mistaking noise for motion and will apply spatial smoothing where temporal should be used.

Rrrough
12th November 2002, 18:41
If you're interested, we should probably take this to the NoMoSmooth thread ok, thanks for the invitation, here I am ;)
could you consider using multiple thresholds with multiple filter strengths ?

cheers

SansGrip
12th November 2002, 19:06
could you consider using multiple thresholds with multiple filter strengths ?

Would it be better to have multiple thresholds, which could lead to a myriad of almost identical parameters, or to weight the strength of the smoothing based on amount of detected motion?

scmccarthy
12th November 2002, 19:47
I vote for the weighting method, it is simpler and if everybody uses the same wight curve, you will get better imput on what works best.

Regarding Motion Smoothing, 100fps states that 24fps is not fast enough to create an illusion of motion. They explain that in film, motion looks smooth because the motion is blurred in each frame. If the blurring due to motion gets sharpened, it hurts the illusion of motion. In Matrix, the images in each frame are so sharp that motion looks unnatural. That might be deliberate for Matrix. This is why sharpening static images while smoothing motion is the way to go.

I know the above applies to NoMoSmooth; I just can't say exactly how, since I don't know the algorithm well enough. It's worth contemplating in this context, howver.

SansGrip
12th November 2002, 20:33
I vote for the weighting method, it is simpler and if everybody uses the same wight curve, you will get better imput on what works best.

That is also my inclination.

I know the above applies to NoMoSmooth; I just can't say exactly how, since I don't know the algorithm well enough. It's worth contemplating in this context, howver.

NoMoSmooth doesn't sharpen anything. It smooths temporally in static areas and smooths spatially in motive areas.

Rrrough
12th November 2002, 23:03
of course the weighting method sounds more reasonable. any idea of how to implement ? I'll be here for testing.

cheers

SansGrip
12th November 2002, 23:13
of course the weighting method sounds more reasonable. any idea of how to implement ?

I'm going to finish porting to YV12 and then look into this more thoroughly. My initial thought is pretty simple: both temporal and spatial smoothing should get weaker as the motion approaches the threshold.

I'll be here for testing.

Great! What do you think of the YUY2 version of 0.0c? It is more complete than the YV12 version.

I'd be interested to hear peoples' opinion of the non-weighting version before I make any major changes.

Edit: Removed link to old version.

scmccarthy
13th November 2002, 00:36
NoMoSmooth doesn't sharpen anything. It smooths temporally in static areas and smooths spatially in motive areas.

I know it doesn't actually sharpen anything, but I thought you were contemplating making it smooth more as motion increased. The fact that blurring motion makes motion look more smooth is an argument in favor of doing that.

SansGrip
13th November 2002, 00:59
The fact that blurring motion makes motion look more smooth is an argument in favor of doing that.

That's an aspect of it I hadn't considered before. It will be interesting to see if it makes a difference.

Rrrough
13th November 2002, 15:30
hi, your filter looks very promising, the motion-/edge-detection runs very well. I'm still playing with the settings in combination with show. one thing I stumbled across is that there isn't a scene-change detection, if I'm not wrong. you can see it clearly in your sample-clip at positions 125,235,265,322,416,491 resulting in "green-valley ;)". Those are the positions where the codecs would encode an I-frame, which is decisive for the picture quality of the consecutive scene. At that point, there shouldn't be too much filtering I guess, because the following p-/b-frames can't compensate too much... But I'm not really sure about it, so maybe I'm totally wrong here.
Next I'll try visual quality / filesizes with different settings.

cheers

SansGrip
13th November 2002, 16:04
one thing I stumbled across is that there isn't a scene-change detection, if I'm not wrong

You aren't wrong, and it's possible that at least temporal smoothing should be turned off for the first temporal_radius frames after a scene change.

I'd like some more input on the impact of doing without scene change detection before I add it, though, since it would slow things down.

Edit: I know that because the temporal averaging only includes values within the threshold there won't be any corruption because of a scene change. That said, areas that do get temporally smoothed won't be "accurate" until temporal_radius frames after the change.

Next I'll try visual quality / filesizes with different settings.

Many thanks for your help -- I hope we can prove right the claim often made that motion-adaptive smoothing really does offer the best of both worlds ;).

Teegedeck
15th November 2002, 13:04
Thanks for this filter; it already works very well! I use it on noisy TV-caps.

SansGrip
15th November 2002, 15:34
Thanks for this filter; it already works very well! I use it on noisy TV-caps.

That's great to hear! Let me know if you have any problems with it, or suggestions for improvement.

By the way, what settings do you use with noisy source?

OUTPinged_
16th November 2002, 00:05
Just tried on 2 test encodes, working great!

Torture clip for TemporalSoften looks identical to source!

Good job on that one, SG.

Two things bothers me. It is unusable due to speed :-( (0.5fps drop from 5.4fps)

Another one, in my "non-anime" clip i saw some artifacts in high motion scene :-(

Screenshots follow in next post.

(Settings were NoMoSmooth(40,3,10,1,20,false) for realtively clean DVD source (luma floats in +-7 range, chroma in +-5)

OUTPinged_
16th November 2002, 00:09
Boo: look at that ugly face. The guy sure didnt have breakfast today.

OUTPinged_
16th November 2002, 00:27
It now looks healthy, but look at this ugly neck and compare it to processed one! That's what we use filters for...

OUTPinged_
16th November 2002, 00:46
Here is the reason: the motion detection engine misses those areas :-(

Look at this shot of motion detector at work. A solution is, if more than n% of pixels in frame are marked, mark whole frame.

SansGrip
16th November 2002, 01:35
Two things bothers me. It is unusable due to speed :-(

Yes, that's a pretty big problem, and one of the reasons I don't claim it's ready for regular use yet unless you have a real fast machine ;).

Unfortunately I don't know x86 assembler, so any optimizations I make will have to be algorithmic until I learn it (I'm planning on ordering a book or two tomorrow). I have some ideas for algorithmic improvements already (such as interleaving temporal frames into one buffer to cut down on the number of pointers I maintain), but the problem with this kind of "no ghosting" temporal smooth is that each pixel in each frame has to be tested against a threshold, and it's this test that slows it down a lot. I'm trying to come up with ways to make it table-based, which should be quite a lot faster.

(0.5fps drop from 5.4fps)

Ouch! That is a lot. Optimization is very high on my to-do list for this filter...

Another one, in my "non-anime" clip i saw some artifacts in high motion scene :-(

I'll wait for the screenshots and see if I can figure out a cause.

(Settings were NoMoSmooth(40,3,10,1,20,false) for realtively clean DVD source (luma floats in +-7 range, chroma in +-5)

That's a fairly high temporal radius, involving comparisons between 7 frames for each frame processed. Do you really get much better results with 3 than with 2? Also, 20 is a high spatial threshold (just try SpatialSoften with a threshold of 20 for comparison...). I guess one can use very strong spatial smoothing with the correct motion_threshold.

Thanks for the tests and the feedback. It really helps to know where to concentrate my development efforts (and also to decide if I should continue at all ;)).

SansGrip
16th November 2002, 19:10
Boo: look at that ugly face. The guy sure didnt have breakfast today.

That's odd. It looks like it missed some chroma information. Is the previous frame greyscale in that area?

It now looks healthy, but look at this ugly neck and compare it to processed one! That's what we use filters for...

I'd need a clip to know exactly what's going on here. I'm working on a new version right now with what I think is a more accurate algorithm, so I'd be very grateful if you can try these problem frames again with the new version. I expect I'll be posting it today.

OUTPinged_
16th November 2002, 21:04
I will be able to host that clip as soon as mr.Graft will get his.

SansGrip
16th November 2002, 21:48
I will be able to host that clip as soon as mr.Graft will get his.

Well, don't worry about it until you've tried the new version. I'm just writing up the docs now...

SansGrip
16th November 2002, 22:20
Here's NoMoSmooth 0.1a (http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-0.1a.zip) for y'all to try, as well as the source (http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-0.1a_src.zip) for y'all to look at should y'all so desire.

It's a total rewrite with a number of algorithmic improvements, so it should now be faster. Brief tests indicate it might even be slightly quicker than Convolution3D(preset="movieHQ"), at least on my system with the default parameters.

I added a simplistic "noise detector" which seems to help reduce temporal smoothing of important and very-noticible-if-missing details such as in skin tones.

This is the first official release, though I'm still classifying it as alpha until it gets more testing and I get more feedback.

Hope this works as good for y'all as it does for me ;).

Edit: Updated links to bugfixed version.

OUTPinged_
16th November 2002, 23:06
Ok, new version is being tested and first impression is that speed is somewhat faster.

..here it comes... there. I get about 2 times faster speeds with 0.8 fps increase from 0.4. Not bad considering the settings.

filter chain looks like that:

TPRSource("C:\temp\uyop1.tpr").ConvertToYUY2.FlipVertical
FieldDeinterlace(dthreshold=5,blend=true,chroma=true)
Lanczos3Resize(544,416)
NoMoSmooth(90,3,20,1,4,false)
Convolution3d(1,5,5,5,5,3,0)
WarpSharp(depth=60, blur=1, bump=128, cubic=-0.6)

[edit] update:

Chroma issue is gone.

here come our little bugs:

If height of the clip is more than 464, it crashes after like 10-15 frames. Good luck hunting.

More speed feedback:

Simple 640x movie clip with (NoMoSmooth(20,3,10,1,1,false)). enabling and disabling a filter doesnt affect my speed much(5.8fps vs 8.4fps). Guess Decomb eats all i can spare in terms of memory throughput :-(

pc is a 800p3+100mhzSDRAM@BX.

Now i will filter nearly every movie dvd. >|-E


[edit2]

Ok, i suck. Forgot to remove stuff. This time speed drop is 7.1fps from 17.3fps.

Filesize decrease is pretty worth the effort:

NoMoSmooth(20,3,10,1,1,false): 1,105,920

unfiltered : 1,277,952

There, 13% decrease.

SansGrip
17th November 2002, 00:16
I get about 2 times faster speeds

Not bad for just algorithmic improvements. I'll think more in that arena, but unfortunately that's as far as I'll be able to go until I learn assembler.

Chroma issue is gone.

Good news.

If height of the clip is more than 464, it crashes after like 10-15 frames. Good luck hunting.

Bad news ;). Funnily enough I only tested with clips < 464. I'll start hunting now...

Ok, i suck. Forgot to remove stuff. This time speed drop is 7.1fps from 17.3fps.

You mean 17.3 without NoMo and 7.1 with it? What other filters are in the chain with those results?

There, 13% decrease.

That's pretty good. But how does it look compared to the source?