Log in

View Full Version : Is there a filter for autolevels?


lansing
18th October 2021, 07:13
I have a grayscale clip that only has visible area between brightness of 50-100, so I'm looking for a filter that can do autolevels to make the image more visible. Is there any?

Julek
18th October 2021, 15:27
Is this for mask? You can try retinex.

lansing
18th October 2021, 15:54
Is this for mask? You can try retinex.

This is for previewing UV plane in vseditor2. I just need to map the levels to a wider range so they're more visible. Retinex is too much for the job.

poisondeathray
18th October 2021, 16:36
if you know the min/max levels (maybe using planestats ?) - can't you just plug those into values into levels filter programmatically ?

lansing
18th October 2021, 16:49
if you know the min/max levels (maybe using planestats ?) - can't you just plug those into values into levels filter programmatically ?

Yes that is what's I was thinking, but I just don't know how to get the max and min value of the levels. I'll try Planestats now.

poisondeathray
18th October 2021, 16:52
You might have to blur or process image with something - because of "stray" pixels (maybe less of an issue for U, V planes than Y) - but the absolute min/max will probably give you not ideal results

(Another less favorable option would be loading an avs plugin...)

Myrsloik
18th October 2021, 17:04
You might have to blur or process image with something - because of "stray" pixels (maybe less of an issue for U, V planes than Y) - but the absolute min/max will probably give you not ideal results

(Another less favorable option would be loading an avs plugin...)

"Stray pixels" => median filter it like crazy before getting max and min

lansing
18th October 2021, 19:51
I run into a problem with the invoking sequence. The normal order for invoking multiple filters would be like:

output_node -> invoke_function1 -> invoke_function2 -> get_frame -> display

But for this, I'll need to get the frame twice:
output_node -> invoke_PlaneStats -> get_frame -> get_frame_prop -> invoke_Levels -> get_frame -> display

Can this be simplified?

WolframRhodium
19th October 2021, 03:29
with builtins

def f(n, f, clip=src):
min_in = f.props["PlaneStatsMin"]
max_in = f.props["PlaneStatsMax"]
return clip.std.Levels(min_in, max_in, min_out=0, max_out=255, planes=[0])

stats = core.std.PlaneStats(src, plane=0)
flt = core.std.FrameEval(src, f, stats)


with Akarin's Expr (https://github.com/AkarinVS/vapoursynth-plugin)

stats = core.std.PlaneStats(src, plane=0)
expr = "x {min_in} - {max_in} {min_in} - / {max_out} {min_out} - * {min_out} +".format(min_in="x.PlaneStatsMin", max_in="x.PlaneStatsMax", min_out=0, max_out=255)
flt = core.akarin.Expr(stats, [expr, ""])

lansing
19th October 2021, 08:21
with builtins

def f(n, f, clip=src):
min_in = f.props["PlaneStatsMin"]
max_in = f.props["PlaneStatsMax"]
return clip.std.Levels(min_in, max_in, min_out=0, max_out=255, planes=[0])

stats = core.std.PlaneStats(src, plane=0)
flt = core.std.FrameEval(src, f, stats)


with Akarin's Expr (https://github.com/AkarinVS/vapoursynth-plugin)

stats = core.std.PlaneStats(src, plane=0)
expr = "x {min_in} - {max_in} {min_in} - / {max_out} {min_out} - * {min_out} +".format(min_in="x.PlaneStatsMin", max_in="x.PlaneStatsMax", min_out=0, max_out=255)
flt = core.akarin.Expr(stats, [expr, ""])


I don't know how to turn the first one into c++. Like how do I set a function as argument?


VSPlugin * pStdPlugin = m_cpVSAPI->getPluginByID("com.vapoursynth.std", m_pCore);

m_cpVSAPI->mapConsumeNode(pArgumentMap, "clip", a_pVideoNode, maReplace);
m_cpVSAPI->mapSetFunction(pArgumentMap, "eval", "???", maReplace);

VSMap * pResultMap = m_cpVSAPI->invoke(pStdPlugin, "FrameEval", pArgumentMap);


For the second one, how do I convert the entire expr line into a string?

WolframRhodium
19th October 2021, 11:04
For the second one,

#include <sstream>

auto min_in = "x.PlaneStatsMin";
auto max_in = "x.PlaneStatsMax";
auto min_out = 0;
auto max_out = 255;

std::ostringstream expr_stream {};
expr_stream << "x " << min_in << " - " << max_in << " " << min_in << " - / " << max_out - min_out << " * " << min_out << " +";
auto expr = expr_stream.str();

vsapi->mapSetData(args, "expr", expr, std::size(expr), dtBinary, maReplace); // Y plane
vsapi->mapSetData(args, "expr", "", 0, dtBinary, maAppend); // U plane
vsapi->mapSetData(args, "expr", "", 0, dtBinary, maAppend); // V plane

lansing
20th October 2021, 18:55
For the second one,


Thanks it works. I modified the string a little because the vsapi function was looking for "const * char" instead of string.


std::ostringstream expr_stream {};
expr_stream << "x " << min_in << " - " << max_in << " " << min_in << " - / " << max_out - min_out << " * " << min_out << " +";
auto expr = _strdup(expr_stream.str().c_str());

vsapi->mapSetData(args, "expr", expr, strlen(expr), dtBinary, maReplace); // Y plane