PDA

View Full Version : applying filter only to Chroma ?


Wizal
25th May 2002, 18:32
Another stupid question : Can I apply a smoothing filter only to Chroma, without affecting Luma ?

Acaila
25th May 2002, 20:45
Only if that particular filter has that option. Most don't though. The only one I can think of right now is Temporal Cleaner, but there's probably others too. You can find it on Donald Graft's page.

Wizal
25th May 2002, 21:33
Unfortunately, a temporal filter is not what I need in this case :(

Would there be a way to separate chroma and luma, apply different filters for each plane and remerge them after ?

manono
26th May 2002, 00:33
Hi-

I've got a beta version of the AviSynth version of SSHiQ which allows you to tweak the Chroma and Luma thresholds separately. If you check back here in a few days it should be available (Thursday maybe?). Or you can e-mail me and I'll be happy to pass it along. It's not any faster yet than the VDub version though.

Wizal
26th May 2002, 01:57
That could help, thanks a lot, but really I need more a general way to process Y and UV separately than a specific filter :(

manono
26th May 2002, 03:20
Hi Again-

OK-No problem, but the original question was:

Can I apply a smoothing filter only to Chroma, without affecting Luma ?

And the answer is yes, very soon.

Wizal
26th May 2002, 04:04
You're right, I should have said a "specific" smoothing filter, which in my case is a General Convolution one :)

sh0dan
26th May 2002, 15:04
The seperate thresholds only have influence on which pixels are blurred - it still blurs on both chroma or luma - but the idea is nice though. I think I'll try to make two different 'amount' settings - one for chroma and one for luma. That way it is not an 'on-off' switch, but it'll be possible to blur luma half as much as chroma for instance.

- Just pass on the beta - it seems to be able to crash on some systems, and I need more info on what's special about these systems.

OUTPinged_
26th May 2002, 22:23
shodan, can you implement some thresh for central pixel's value to be replaced with average value instead of blurring?

b0b0b0b
31st May 2002, 01:04
Check this out:

http://freevcr.ifrance.com/freevcr/virtualdub/cnr-en.html

Looks fancy.

sh0dan
31st May 2002, 11:47
@Outpinged: I'm not sure what you mean. Right now this is how it works:

Smart Smoother, Spatial Smoother, SSHiQ Average mode: Every pixel is tested against all surrounding pixels, if the difference between the two pixels are lower than a given threshold, it is added to a sum, so:

RGBsum = PassedPixel1 + PassedPixel2 + .... + Current pixel

The final pixel is then calculated as:

Pixel = RGBsum / number of passed pixels.

So only pixels below the threshold is added.

What would you test against - the difference between the original pixel and the final averaged pixel?

@All: Wouldn't it be possible to do an Avisynth filter that stores the Chroma or Luma values, that can be restored later. If memory can be shared among two filter instances, it should be fairly straightforward - and easy to optimize.

pandv
1st June 2002, 16:53
(Consider this as only a test to see if i understand correctly who AviSynth works).

Maybe you only need a filter capable to merge the Luma from one clip and the Chroma from another.

So, you can duplicate the opened clip, process one copy, and finally get the chroma from the processed copy, and the luma from the unprocessed.

Of course you get a overhead in processing time, but is only a workaround.

Can this works?

pandv.

sh0dan
1st June 2002, 17:26
Yearh - that was kinda what I was thinking, so the AVS-script could look like this:

LoadPlugin("c:\apps\avisynth\MPEG2DEC.DLL")
mpeg2source("c:\apps\avisynth\main.d2v")
StoreLuma()
SmoothHiQ(5,30,50,255,5)
RestoreLuma()


Of course the image size cannot be changed between the Store and Restore. It seems like it is necessary to copy the image data no matter what, since most filters just modify the original image and overwrites it with the filtered data.

1) Store a pointer to the original image and copy all data to a new image. Very fast, but memory intensive.

2) Store only Luma or Chroma. Will use half the memory-bandwidth, but require more CPU. Would probably need image width to be multiple of 4 or 8 to be fast (so 2 or 4 quadwords can be processed at the same time).

Restore time will probably be the same using either algorithm.

Does anyone with AviSynth experience know if it is possible to pass a pointer between two filter instances?

Wizal
1st June 2002, 18:43
That's a very smart idea, thanks for the tip :)

sh0dan
1st June 2002, 20:26
OK - made it work!

Made an AviSynth filter, to preserve luma or chroma.

It can be downloaded here (http://cultact-server.novi.dk/kpo/ColorSaver_10.zip). I'll probably get Donald to host it, if he wants to.

Use it like this.

Import the filter:

LoadPlugin("c:\dev\AviSynth_filters\ColorSaver\release\ColorSaver.dll")

Usage is:

ColorSave(<mode>)

Where mode is:

0 - Store Luma channel
1 - Store Chroma channel
2 - Restore Luma channel
3 - Restore Chroma channel

Example:

LoadPlugin("c:\apps\avisynth\MPEG2DEC.DLL")
LoadPlugin("c:\dev\AviSynth_filters\ColorSaver\release\ColorSaver.dll")
mpeg2source("c:\apps\avisynth\main.d2v")
ColorSave(0)
Blur(1.0)
ColorSave(2)

This will only blur the Chroma channels.

Another Example:

LoadPlugin("c:\apps\avisynth\MPEG2DEC.DLL")
LoadPlugin("c:\dev\AviSynth_filters\ColorSaver\release\ColorSaver.dll")
mpeg2source("c:\apps\avisynth\main.d2v")
ColorSave(0)
Blur(1.0)
ColorSave(2)
ColorSave(1)
SwapFields()
Colorsave(3)

This will blur the Chroma channels and swap fields in the Luma channel. (Best example of seperate channel processing I could come up with).

In principle it could be used to merge chroma from one source into another, but I'm not experienced enough in the Avisynth language to do that ;)

The filter requires MMX and image width that is multiple of 8. Image size may NOT be changed between store and restore. If widths down to muliple of 2 is REALLY required, write me a message, I'll fix it then. The filter is very badly tested (only 1 clip) - write me here or at kp@interact.dk if there are problems.

Oh yearh - source is included.

Acaila
1st June 2002, 21:35
Wow, this filter could be interesting for a LOT of things. Thanks Sh0dan!

dividee
1st June 2002, 22:48
It's fast but I see at least one problem, maybe two:
Since the buffer is declared statically, I don't think it's thread safe. But I couldn't trigger the problem so maybe it's not an issue; my understanding of the topic is limited.

More serious: you can't guarantee that the calls to the save & restore functions will match: for instance you can't use a temporal filter in between:

ColorSave(0)
TemporalSmoother(2,3)
ColorSave(2)

would cause a desynchronization of 3 frames between luma and chroma, since TemporalSmoother needs to read ahead 3 frames.

Best thing to do is what pandv explained, it would work like that:

mpeg2source("...")
vid=TemporalSmoother(2,3)
MergeChroma(vid)

for chroma only filtering, or

vid=mpeg2source("...")
TemporalSmoother(vid,2,3)
MergeChroma(vid)

for luma only filtering

You don't need to buffer anything, avisynth will take care of it.

sh0dan
2nd June 2002, 11:29
It's a two hour hack, so don't take this too serious ;)

Anyway - I don't think it is thread safe - I don't know how Avisynth operates, so any help in this direction may help!

My impression was that temporalsmoother operated, by requesting previous frames, and not by delaying frames (as virtual dub).

Anyway, would it help, if I modified it, so it took another clip as parameter and merged in the luma/chroma on the fly?

dividee
2nd June 2002, 15:50
AAARRRGGG !!!! :angry:
I wrote a lengthy post, explaining things about avisynth architecture and all, and clicked "Preview Reply" instead of Submit and closed my browser! And it's not saved in the browser history ! One hour of work lost.
:stupid:

I don't have time to rewrite it now, but conclusion was that filters that share knownledge doesn't fit well in avisynth architecture, and that it would be too much work, if even possible, to work around every issue.

A better way would be for the Save filter to return the buffer "casted" to a clip and pass it to the Restore filter.

A simple filter that merge luma from one clip and chroma from the other - as outlined in previous post - would be less hackish, and you only have one function to write instead of four.

sh0dan
2nd June 2002, 16:48
Hope you get time for writing it later - it's not easy to see from the concept from Ben's documtation.

Deleted some stupid stuff, because I didn't understand what you where saying. I'll try to do what you suggest instead ;)

sh0dan
2nd June 2002, 19:12
OK - made a test version.

Download it from here (http://cultact-server.novi.dk/kpo/MergeLuma_10.zip). Source is included.

It takes two parameters.
MergeLuma(clip1, clip2)

It merges luma from clip2 into clip1 chroma, and returns the result.

The only way I could make it work was like this - which seems silly.

Example:

vid1=mpeg2source("c:\apps\avisynth\main.d2v")
mpeg2source("c:\apps\avisynth\main.d2v")
vid2=TemporalSmoother(2,3)
MergeLuma(vid1,vid2)


If I try to pass only one clip to the video it is interpreted as the source clip (child), and not as the second parameter. It seems to me like it will be necessary to duplicate the video clip. If I pass vid1 as source to temporalsmoother, will it not be overwritten with the smoothed data?

I was going to implement a system, that returned a new clip containing only the luma or chroma data, but I couldn't figure out how to do that, so unless there is a way of making this filter work, it look like I'm at it again. :(

dividee
3rd June 2002, 22:41
If I try to pass only one clip to the video it is interpreted as the source clip (child), and not as the second parameter.

That's because named arguments are optionals, it shouldn't be since it's not really optional. Change "c[lumaclip]c" to "cc" and it should work (and you can remove the (!clip) test too).

It seems to me like it will be necessary to duplicate the video clip. If I pass vid1 as source to temporalsmoother, will it not be overwritten with the smoothed data?

No avisynth filter would ever do that! You should have more faith in avisynth ;) It keeps a reference count to each framebuffer in use; that's why you have to call env->MakeWritable(&src): it checks if the reference count is 1 (that it is the sole owner of the buffer) and if it's not it copies the data to a new buffer before processing.

With the above modification, this works and does the same as your script above:

mpeg2source("c:\apps\avisynth\main.d2v")
lumvid=TemporalSmoother(2,3)
MergeLuma(lumvid)


About thread safety, I'm not expert on the subject but I remember dvd2svcd once had this kind of problem with his avisynth subtitler plugin. Moving static variables to member variables fixed it. Of course it wouldn't work for ColorSave, since the save and restore functions are separate instances of the class. But there is a way to use script-wide memory: the ScriptEnvironment has SetVar() and GetVar() methods for that use. But there would still be a problem if someone would want to use more than one pair of Save/Restore calls in the same script; I think it would be necessary to add another argument to the filter for matching Save/Restore calls, a kind of handle.

About the desync with TemporalSmoother: When a script is run, avisynth interprets it during initiliazation and build a filtergraph. From this point on, the script is not needed anymore and could even be deleted. When the application requests a frame, the last filter of the graph (or the top filter, depending on your terminology) is called, which himself calls previous filter(s) (child->GetFrame()).
If we look at the following script excerpt:
ColorSave(0)
TemporalSmoother(2,3)
ColorSave(2)
ColorSave(2) is first asked for frame 0. It asks TemporalSmoother for frame 0. TS, with a radius of 3, will ask ColorSave(0) for frame 0,1,2 and 3 to perform his duty and return filtered frame 0 to it's parent. TS is asked for frame 0 and returns frame 0. No lag. So the last call to ColorSave(0) is for frame 3 while ColorSave(2) operate on frame 0. When asked for frame 1, TS only asks ColorSave(0) for frame 4 since it has already buffered frames 0 to 3. There is a constant desync of 3 frames between the calls to ColorSave(0) and ColorSave(2).
What makes the problem worse is that avisynth heavily caches the output of every filter in the graph. If, by misfortune, for a particular frame, the output of ColorSave(0) or any filter between the save and restore functions is cached, while the output of ColorSave(2) is not, you guessed it won't work. It means you can't rely on a side effect of a filter since you can't be sure it will be called. What could cause such a situation? Using any filters that access previous or future frames, even after ColorSave(2)!

sh0dan
4th June 2002, 11:43
Thanks for the info - it makes perfect sense! I'll do the proper modifications, and perhaps some cleanup, and then release it along with SmootherHiQ for Avisynth, when the documentation is done.

Avisynth is very powerful. The only thing I miss is a filter GUI, that lets users dynamically build up filters and preview every filter step. A Virtual Dub/Avisynth merge would be a very powerful tool. VDub's GUI, but with complete YUV-processing.

I looked through the Avisynth 1.06 source, and I wondered if anyone has tried to convert ConvertToYUY2 to MMX. The only problem I see is "cyg" being bigger than 15bits (33039), but a change to 15bits doesn't seem to loose any significant precision. Not sure if there are enough registers to get a proper speedup though. Has this already been tested?

Just found an mmx "rgb32_to_yuv_mmx" in XVID - has this been tested? A speedup here could really help a lot of VDub filters!

OUTPinged_
4th June 2002, 12:15
@shodan

RGBsum = PassedPixel1 + PassedPixel2 + .... + Current pixel

So the stuff i was asking was an option to remove +Current pixel from RGBSum.

sh0dan
4th June 2002, 12:41
In SSHiQ "weighed mode", with amount=254, the current pixel will not be present at all, if all pixels surrounding the current pixel passes the threshold - so there you have it :)

sh0dan
5th June 2002, 15:07
Finished Merge, and sent it off to Donald. I'll make a more 'public' announcement when it has been uploaded.

I implemented a weight option, that allowes the two lumas/chromas two be blended with a given percentage.

For simplicity (and to maintain the same syntax) i decided to split the filter into a MergeLuma and a MergeChroma.

Find it here (http://cultact-server.novi.dk/kpo/avisynth/merge_as.html).

Also some goodies here (http://cultact-server.novi.dk/kpo/avisynth/smooth_hiq_as.html)