PDA

View Full Version : Conditional execution & image evaluation


mustardman
1st April 2003, 01:30
I would like to selectivly apply filter(s) depending on the contents of the image in a selected area.

For example, something like...
IF luma(x1,y1,x2,y2) < 20 THEN filter;

'luma' would be a function that evaluates the average brightness of the image bounded by x1,y1,x2,y2.

x1,y1,x2,y2 are numbers and 'filter' is one of the filters available (like HSIAdjust, Levels or ComplementParity) to apply to the _whole_ image.

Virtualdub has a Conditional Execution filter, but the 'luma' function evaluates the entire image, not a selected region, which is what I *really* want to do.

Thanks for any tips or pointers.

sh0dan
1st April 2003, 10:42
The only way to do this is inside a filter.

A generic "conditional source selector" filter should be quite possible to code, but it doesn't exist. :(
Edit: It does now :)

Something like:

Conditionalfilter(clip, source1, source2, "AverageLuma()", "greaterthan","20")

Where source1 would be selected if the condition is true, and source2 if the condition is false.
Functions could be:
"AverageLuma()", "MaximumLuma()", "MinimumLuma()", "LumaDifferenceToPrevious()", "LumaDifferenceToNext()", etc.

These could be implemented as AviSynth functions, returning ints, so the internal parser could be used to something like:

Conditionalfilter(clip, source1, source2, "MaximumLuma()-MinimumLuma()", "lessthan","10")

or

Conditionalfilter(clip, source1, source2, "DifferenceToClip(reference)", "equals","0")

That way conditional functions could actually also be made in other plugins, like MPEG2DEC3 returning interlacing for every frame, or Decomb passing information about detected IVTC patterns. Wow - this could be useful - if only I had the time. ;)

WarpEnterprises
1st April 2003, 16:51
but NOW you can use Layer:

° select you region of interest as a mask (using Crop)
° completely blur it (bilinear downscale it to 2x2, upscale it to your destination resolution)
° level it to black and white depending on your threshold
° use Layer() to switch between two filter paths

Of course both filter paths are executed for EVERY frame, so it's not a conditional _execute_ but a conditional _show_

sh0dan
1st April 2003, 18:28
OK - I actually got inspired, and felt like trying to implement this.

It actually works - and surprisingly well.

However there are still no funtions that actually support this, but you can still test it. The AviSynth parser is used to evaluate the two conditions on each frame, so in principle any function returning either an int, bool or float can be used.

The current frame number is put into the variable "current_frame" before the expressions are evaluated, so for now this is what you can play with.

Some things to have fun with:

ConditionalFilter(last,last.subtitle("S1"),last.subtitle("S2"),"current_frame",">","10")


or

ConditionalFilter(last,last.subtitle("S1"),last.subtitle("S2"),"current_frame%4","=","0")


"=", ">" and "<" are the same as "equals", "greaterthan" and "lessthan". If you want to use the "coder" syntax or the more readable one is up to you.

I hope I'll be able to implement some useful functions for this soon! This is a whole new world!

(dated the binary april 2. so it didn't look like a sick aprils fool joke ;) )

Bidoche
1st April 2003, 19:04
Why not simply concatenate your 3 params into one ?

And maybe use 'n' as the current frame number, for consistency with WarpE zoom plugin

DDogg
1st April 2003, 19:27
With great fear of being crushed like a bug, could this work potentially allow Import to activate at a given frame? Or even a while keyword? (pulling head in shell)

sh0dan
1st April 2003, 19:37
Added three functions:

AverageLuma(), AverageChromaU(), AverageChromaV(). Returns a float from 0 to 255 based on the average pixel values of a plane. Examples of use:

ConditionalFilter(last,last.subtitle("S1"),last.subtitle("S2"),"AverageLuma()","GreaterThan","32")

This will display S1 if average luma is more than 32 - otherwise it will select S2.

@Bidoche: That way I don't have to do any parsing, except finding the condition. You can easy add another function only recieving one string, and then search for the condition and split it into three. Feel free to do so!
We need a less generic variable than "n", to avoid potetial clashes - remember people can still reference variables within the conditions.

@DDogg: Don't think so. This selects between two sources based on the input. It doesn't seem to have anything to do with what you suggest - that would require a complete graph rebuild.

Bidoche
1st April 2003, 19:42
You are not using the avisynth parser ?
Just have to setup the frame number, invoke import with the text and use the result, not really a problem, and it allows all internal functions.

And for your luma functions you could pass them to the parser as variable too.

sh0dan
1st April 2003, 19:46
The code is in CVS - have a look. I AM using the parser - but only to return values from functions. All functions (sin, cos, etc) are available - the result from the two conditions just have to be int, float or bool.

Rebuilding the graph each frame would be dog-slow, and probably resulting in several 100% slowdown.

DDogg
1st April 2003, 20:01
Just to clarify, if import could just be triggered at frame 0 (and hold video event until import is finished) that would be a big help. If import trigger after last frame was also available then that would be even better.

/Edit: Yup, sorry for going OT. When I saw "conditional" I thought they were somehow related.

sh0dan
1st April 2003, 20:05
When frame 0 is requested, the graph is already built, and it's too late for imports. Please open a new thread in the dev. forum to stay on topic.

Bidoche
1st April 2003, 21:28
I read your code and I still don't understand why you bother call the parser twice and make the comparison yourself when the parser could have done it in one shot.

NB: I know you'd rather avoiding learning new librairies, but you should at least make an exception for 'string', it's really better than C manipulations methods.

mustardman
2nd April 2003, 04:39
Thanks for your input guys.

I don't quite get what "layer" will do - what is it? (WarpEnterprises) but now that a dedicated "conditional" has been written... :)

I have written a reply on the new thread "Using per frame conditional filtering", which is a question more from a user viewpoint.

Thanks again.