View Single Post
Old 12th November 2010, 06:36   #61  |  Link
frustum
Registered User
 
Join Date: Sep 2010
Location: Austin, TX
Posts: 40
Gavino --

I looked at convert.h just enough to find the yuy2 to rgb conversion (and back) and didn't see any option for matrix. Now that you've clued me in, I see the matrix choices in convert_yuy2.cpp.

IanB --

Doing everything consistently in yuv space has the advantage that a given video source converted into rgb or yuv space running through the filter would give very similar results, whereas running it through using max(r,g,b) vs luma(r,g,b) would give different results. In RGB space, a pure blue pixel has already pegged the range (a 0x00 component and a 0xFF component) and no levels adjustment is possible, while in YUV space, such a pixel has a luma value of only ~11%.

I've looked a bit at some imagemagick filters for ideas and an array of options are offered, including adjusting each rgb channel independently, or by luma, or intensity, or brightness, or ...

http://www.fmwconcepts.com/imagemagi...evel/index.php

From the thumbnail example given it is hard to discern the difference between some of them. At any rate, I guess there isn't a one right way to do it, that different approaches make sense in different situations. Because I'm not doing much in the way of optimization (unrolling or assembly), each flavor of conversion routine probably costs only a few hundred bytes incrementally, so it wouldn't be unthinkable to offer a mode option to specify joint rgb vs separate rgb vs 709 luma vs 601 luma vs avg intensity. I just had a look at levels.cpp and it isn't trying any harder than I am to be fast, so I guess it is acceptable.

It would also be a relatively small extension to offer an auto gamma option based on the same statistics being gathered for autolevels and the same machinery for adjusting pixel values. From the same source as before:

http://www.fmwconcepts.com/imagemagi...amma/index.php

A more fully featured autolevels might want to support more of the features of levels. Ignoring all issues of feature creep and just dreaming out loud, I could imagine these features fitting together into one filter:

Version 0.3 options:

[filterRadius] -- number of frames before/after to average over

[sceneChgThresh] -- sensitivity to detecting scene changes

[frameOverrides] -- specify frames or ranges to ignore/enforce scene changes

new options:

[debug] -- info/debug option (in version 0.4 already)

[clip_low] -- fraction of dark pixels to ignore (default 1/256)
[clip_high] -- fraction of bright pixels to ignore (default 1/256)
[clip] -- specifies same value for clip_low, clip_high

[input_low] -- as in levels()
[input_high] -- as in levels()
[output_low] -- as in levels()
[output_high] -- as in levels()
[coring] -- as in levels()
[gamma] -- as in levels()

[autogamma] -- exclusive of use with [gamma], it is 0 by default, meaning don't autoadjust gamma, while 1.0 means estimate and apply a gamma; weights between the two change it in proportion, above 1.0 gooses it higher than what the algorithm calculates.

[mode] -- used only for rgb formats, "rgb" means adjust each r, g, b plane separately, "joint" means use the min/max of rgb component of each pixel and adjust all planes the same, while rec709/rec601/pc.709/pc.601/average are like the "matrix" option for converting rgb/yuv.

One thing is I would want the filter to produce the same results as the 0.3 version given the same parameters. This means that by default outliers in the distribution could map to luma < 16 and luma > 236. There should be some mechanism to specify that these values should be clamped to [16 .. 235], perhaps just another flag, but maybe there is some less verbose way to infer this without another parameter. For instance, mode could default to pc.601 and "pc.*" signifies whether luma is limited to [16 .. 235] when operating in yuv space.
frustum is offline   Reply With Quote