Closed Beep6581 closed 9 years ago
Correction: contrast = 25*(hidev/lodev)
Reported by michaelezra000
on 2011-11-02 03:42:48
The contrast setting seems for normal images to just give 25 for the result, so not
much different from setting that value; except for low key images (eg night scenes)
where because hidev is so much larger than lodev, contrast is cranked up way too high.
I suspect we want something more like using MAX(lodev,hidev) to set contrast such
that it increases that max value to some target. That way, if the image is mostly
in shadow, the shadows won't be further crushed by contrast. Whichever deviation from
the median is larger won't get pushed too far.
Reported by ejm.60657
on 2011-11-03 03:02:49
Another question: I set midgray to 18%; should we be using 12-13%? The former is middle
gray (L=50); the latter is the average reflectance of the typical scene. Apparently
it's a longstanding debate.
Reported by ejm.60657
on 2011-11-03 03:11:44
I just did a more comprehensive testing for contrast. The formula that seems to give
a very close fit to my manual corrections is:
contrast = 25*(hidev/lodev) + MIN((lodev+hidev)/ABS(lodev-hidev),15)
I tested this for wide range of images, except high key (need to get a few samples)
This contrast formula requires some further adjustments for the brightness model.
About midgray - I suppose this should be correlated with the camera calibration procedure?
Reported by michaelezra000
on 2011-11-03 04:02:22
So in a typical image with lodev~hidev you are cranking the contrast to 40? Seems way
too much.
Reported by ejm.60657
on 2011-11-03 05:37:01
It depends on the objective of auto-levels, whether it should give the quick and "final"
look or a starting point. I will post screenshots to illustrate, later in the evening.
In general, higher values of contrast work better with the increase of brightness slider
in rt as that does not let shadows to be crushed.
BTW, with auto-levels I have not seen black getting into the negative values, although
it is sometimes more useful instead of brightness. Of course this may complicate auto-algorithm
further.
Reported by michaelezra000
on 2011-11-03 12:19:53
There is one more factor to mention, in my testing I used clipping = 0
Reported by michaelezra000
on 2011-11-03 14:05:26
About blacks, blacks are only shifted positively, to pull down the toe of the histogram
according to the clip fraction. If one were to use black to adjust brightness, one
would have to give up this feature, since it can't be positive and negative at the
same time. We could however change the shape of the brightness curve if you think
another one is more pleasing.
Reported by ejm.60657
on 2011-11-03 14:11:15
I think having the option of current brightness vs negative black is valuable as well.
+ Brightness perceptively desaturates colors and +Contrast does the opposite, so they
can balance each other if adjusted properly. I wonder if this balance from the point
of view of the saturation could be derived from the curves for each of these tools.
Reported by michaelezra000
on 2011-11-03 14:25:40
Here are some illustrations:
http://www.timelessme.com/temp/Postings/AutoLevels_scrrenshots_01.jpg
Reported by michaelezra000
on 2011-11-04 01:29:39
One of the problems with the high RGB contrast setting, however, is that it can lead
to muddy skin tones. + Brightness can somewhat mitigate that. Normally for good skin
tones I would use a tone curve that in simplified version would be a created by a single
point moved up, depending on the image. This increases contrast and brightness together
in very natural balance and does not lead to muddy skin tones.
The brightness and contrast tools seems to be quite more useful for other colors, such
as in landscapes, where human eye is not as critical to not 100% natural appearance
of hues.
My suggested brightness and contrast settings are really a quick fix. For comparison,
here is a somewhat (over)developed version of the same shot as was shown above
Reported by michaelezra000
on 2011-11-04 01:57:46
I tweaked manual brightness adjustments a bit while making screenshots in comment 60,
and will re-upload the excel (likely by tomorrow morning).
I made a few tests with high key images and it seems to work just as well.
I suppose contrast may need additional adjustment based on amount of clipping, did
not evaluate that yet.
Reported by michaelezra000
on 2011-11-06 00:09:36
I've been thinking that some metric using quantiles of the histogram might be appropriate.
The median is the quantile where half the pixels are above, half below. If we further
divide into say octiles, we find our where the n/8'th brightest pixels are located,
for n=1,2,3,... If the octiles (or however many divisions are useful) are close together,
the histogram has a significant peak in that region. A single peak histogram will
have the middle octiles bunched together and the high/low ones further spread; a low-key
image will have the low end octiles bunched and the high ones spread and vice-versa
for high-key; a bimodal histogram (eg landscape with ground and sky will have the ends
bunched and the middle spread. So we might want something where we use this measure
to say where the histogram is peaked, and spread the peak using the contrast slider
in some way. Not sure whether the separation of the quantiles should be in L (gamma=3),
Y (gamma=2.2), or log(R+G+B) (zone system).
If this doesn't work, we could just leave contrast out of the auto-exposure routine
and put it at some preset for the default profile, as is done currently.
Reported by ejm.60657
on 2011-11-06 01:04:07
The lodev and hidev seem to be quite descriptive on peaks distance on left and right
sides from the median. I'll try to put illustration of the untouched images histogram
into the same screenshots from comment 60. This will allow to better view the impact
of auto levels.
There may be a significant benefit from more detailed, zoned view at the histogram,
as you described, as this may allow to compose a finely tuned curve that could specifically
work around the peaks, being able to adaptively alter contrast and brightness for the
different regions of the histogram.
I am also not sure what gamma encoding would be best. All my screenshots wee made using
ProPhoto RGB working and output space. Is current histogram reflective of that?
Another approach could be to look at the smoothed version of the histogram, detect
significant minimums and maximums, for each add a point on the tone curve. Displace
the points up/down to achieve desired contrast (and brightness). This actually could
become a new auto-curve button on the curve tool. It should then work off the input
histogram for the given curve tool and (if I understand correctly) at that point it
already has data encoding suitable for corresponding type of curve; Input histogram
is displayed within the curve tool.
Reported by michaelezra000
on 2011-11-06 04:20:32
autoexposure histogram for raw files is done in linear gamma, just multiplying each
raw pixel by corresponding WB and adding the resulting value to the histogram.
Reported by ejm.60657
on 2011-11-06 05:10:30
I tried using the curve approach manually. The problem with it the sequence in which
adjustments are applied - brightness and contrast adjustments provide input to the
curve, therefore curve cannot be adjusted first, it must be the last in this approach.
This also is a methodological question - in case when user would rely on Auto Levels
- what would be a better user experience -
1. to have the curve automatically calculated and let user play with sliders or
2. let auto-levels set the sliders and let user fine-tune the curves.
This likely depends on the user's skill and individual preferences. Should RT cater
to that?
There is also the question of objective of auto levels -
A. should this be tuned for advanced users (giving well balanced starting point) or
B. for more of the 1-button click users when more or less final optimal look is achieved.
Reported by michaelezra000
on 2011-11-06 15:33:01
I don't think we want to do an auto curve adjustment. I was more thinking that one
use the quantiles to set the contrast. For instance, so that the average quantile
spacing is so many EV (haven't tested what works yet). What bothers me about your
formula in #54 is that it blows up when lodev=hidev (eg a symmetrical, bell curve histogram).
Reported by ejm.60657
on 2011-11-06 15:55:08
And to answer A vs B -- I think the objective is to give reasonable look for 1-button
click users, and for batch processing automation. This is why I haven't paid attention
to it so far; my personal prejudice is that RT is that users should look at the image
and adjust it, according to that image. I can understand that some people have large
batches of photos to process and want automation, it's just not the way I work.
Reported by ejm.60657
on 2011-11-06 16:09:54
oops, you are absolutely right about /0, I will try to find another fit.
Reported by michaelezra000
on 2011-11-06 19:35:42
I am an "A" user in your choice - I shoot a batch of photos in one environment, I apply
my custom PP to all of them, that custom profile has auto levels enabled to get me
as close to a good result as possible, then I go through each photo and tweak it as
needed. I do "look at each image and adjust it", but a good starting point saves me
time.
As for 1 vs 2, I prefer tuning the curve - more powerful than the sliders... although
it saves me time when the exposure slider is auto-adjusted to begin with.
Reported by entertheyoni
on 2011-11-06 19:54:01
I think A vs B could be eventually exposed via preferences:
A - no auto contrast
B - with auto contrast
Brightness adjustments in approaches A and B may need to use different formulas as
well.
*****************************************
On contrast, I tried to use the following logic. Contrast seems to depend on
1. lodev and hidev relative to each other: A*hidev/lodev + B*lodev/hidev
2. distance between peaks: C*(lodev+hidev)
3. median vs average difference: D*median/average
so, contrast = A*hidev/lodev + B*lodev/hidev + C*(lodev+hidev) + D*median/average
I suppose that weights could be derived using some assumptions and specifics of the
contrast curve, but values below are purely empirical.
I found the following weights to give the closest fit using this formula:
contrast = 23*hidev/lodev - 0.5*lodev/hidev + 2.5*(lodev+hidev) + 2.2*median/average
however, there was an additional adjustment seemed necessary:
when image has largely separated peaks (sky/land image), it is beneficial to increase
the contrast (accompanied with increase of brightness as this expands shadows and rolls
highlights), yet if peaks are too far apart, increase of contrast should be tamed down.
To accommodate that I found that
factor A can be represented as (33-(lodev+hidev)*hidev/lodev)*hidev/lodev
factor B =1 and C=D=0 worked as well.
The end result is:
contrast = (33-(lodev+hidev)*hidev/lodev)*hidev/lodev + lodev/hidev
Reported by michaelezra000
on 2011-11-08 05:47:59
Here's a patch incorporating my approach: compute octiles of histogram (generalization
of median -- brightness level of n/8'th brightest pixel for n=0,1,2,3,...), then demand
that average spacing of octiles is increased if too small or decreased if too large.
Reported by ejm.60657
on 2011-11-08 18:24:46
This is fun:)!!!
Your approach leads to very good ballpark.
I made a couple of printf changes to include values of my approach as well:
contrast = (33-(lodev+hidev)*hidev/lodev)*hidev/lodev + lodev/hidev
bright = bright*hidev/lodev
Here is a link to comparison (4 MB):
http://www.timelessme.com/temp/Postings/AutoLevels_scrrenshots_02.jpg
In rtthumbnail.cc lines 726 (ipf.getAutoExp ) and 734 (CurveFactory::complexCurve )
There is some inconsistency in what variables are passed in - either locally declated
(expcomp, bright, etc) or from params.toneCurve
Should this all be changed to use params.toneCurve?
Reported by michaelezra000
on 2011-11-09 02:34:51
I am curious, were you envisioning enabling zones display in UI?
The octile/zones implementation could probably be used for enabling visual guides and
to also provide quantitative feedback in UI.
Reported by michaelezra000
on 2011-11-09 04:10:55
Yes, that is an inconsistency that should be cleaned up.
I hadn't thought of zones display in UI; I'm not sure how octiles would be useful to
the end user, having the full histogram at hand.
The particular function I used for determining contrast was a rough guess and could
certainly be improved upon. Your version leads to more contrast in most cases (the
kitchen scene is the one main exception), so you get a punchier output typically, which
I like in some cases (landscapes mostly); generally I prefer a slightly flatter look.
I suspect the octiles approach has the flexibility to be tweaked, by using a weighted
average that might weigh say the brighter tones more. Also the particular function
I chose has constants in it that could be adjusted, or one could modify the functional
form. For instance if I wanted to approximate your function I might replace lodev
by the second octile (octile[1]) and hidev by the sixth octile (octile[5]) (these are
the medians of the top half and bottom half of the pixel values).
Reported by ejm.60657
on 2011-11-09 05:22:35
What is your thinking behind the particular choice of function you made?
Reported by ejm.60657
on 2011-11-09 05:36:44
I tried to get the closest approximation to manual adjustments made to control images.
Here is the latest version of the excel outlining my iteration through 5 different
models.
Even in simplest form contrast is well approximated in model1 (hidev/lodev)
contrast = A*hidev/lodev
The hidev/lodev is clearly getting the primary weight
On example of the cliff image, when left and right peaks are spread too far (cliff
image, compare to Autumn Field), hidev/lodev alone gives value that is too high. The
idea was to reduce the multiplier when peaks are too far, thus dependency on (lodev+hidev).
This factor further benefited from additional multiplication on hidev/lodev to fit
in the cliff image. So A got transformed into A-(lodev+hidev)*hidev/lodev. Value of
constant A was chosen to fit manual adjustments, and control was a reasonable contrast
for symmetric distribution when (lodev+hidev) is about 1.5 and hidev/lodev also about
1.
Overall hidev/lodev seems to be a good ballpark descriptor, but for contrast its weight
should be lowered for its high values.
The lodev/hidev term is to give some positive weight when lodev is higher than hidev.
For brightness 0.33*hidev/lodev also fitted manual adjustments when used along with
the contrast formula.
Reported by michaelezra000
on 2011-11-09 12:58:26
correction:
Overall hidev/lodev seems to be a good ballpark descriptor, but for contrast its weight
should be lowered for its high values AND when peaks are spreading from each other.
If you compare cliff and autumn field images (and their numbers in excel), my final
formula enables higher contrast for autumn field and lowered contrast for cliff, but
at the same time allows lower contrast for histograms in the kitchen-like images, also
see guy with the dog.
Reported by michaelezra000
on 2011-11-09 14:25:31
Hi Emil,
I made an adjustment to the formula to better handle specifically images with bell-shaped
histograms, all other types of histograms should be mostly unaffected (e.g. kitchen
images, etc)
contrast = (33-(lodev+hidev)*hidev/lodev)*hidev/lodev - 0.5*lodev/hidev + 50*((lodev+hidev)/(median/ave))^3
The idea is that the additional expression 50*((lodev+hidev)/(median/ave))^3 gets significant
values mostly on bell shaped histograms, thus allowing to narrow influencing contrast
for that class of images (see row 13)
Analysis is in the updated excel (contrast 6)
Test image - http://www.timelessme.com/temp/Postings/WA2011_1472.zip
Reported by michaelezra000
on 2011-11-10 05:25:08
I'm confused. Suppose you have a histogram of the landscape sort -- bimodal, but with
equal weight between land and sky. Then median=average and lodev+hidev is large, and
the last term will boost it tremendously if lodev+hidev>1.
Could you also send me the 'surfer-dog' image? That one, the cliff and the kitchen
scene are the ones where our two approaches differ most. In the surfer-dog and kitchen,
my approach overcooks the image, in the cliff your approach overcooks it (it also slightly
overcooks some landscapes where mine is too conservative). Almost sounds like we might
want to average the two formulas :^)
Reported by ejm.60657
on 2011-11-10 13:08:18
I made a modification that seems to address some of the issues with my approach -- change
line 670 of improcfun.cc in my latest patch to
ospread += (octile[i+1]-octile[i])/MAX(0.5,(i>2 ? (octile[i+1]-octile[3]) : (octile[3]-octile[i])));
What this does is to divide the octile spacing by the distance of the octile from the
median. This then damps the weight of octiles far from the median (eg bimodal histograms
of the sort common in landscapes, or high key images like the kitchen scene) so that
the algorithm is not trying to 'spread' the histogram when the bulk of its mass is
far from the median. A lower bound on this additional factor of 0.5 was chosen (this
could probably be better tuned) so that one doesn't penalize narrow, bell-shaped histograms
where the histogram is clumped around the median -- after all, these are the ones one
wants to give the most contrast to!
Reported by ejm.60657
on 2011-11-10 15:22:41
for comment 81:
true, but take a look at excel column L (Train), its basically the case you are describing,
but the calculated contrast value is only 6.
P.S. I will try your change in the evening.
Reported by michaelezra000
on 2011-11-10 16:36:01
I made a mistake, the actual formula I ended up using in excel is different, NOT what
I quoted in comment 80:
contrast = (33-(lodev+hidev)*hidev/lodev)*hidev/lodev - 0.5*lodev/hidev + 50*((median/ave)/(lodev+hidev)*lodev)^3
Reported by michaelezra000
on 2011-11-10 16:42:02
my day job is distracting me, clearly:) I missed parentheses in denominator:
contrast = (33-(lodev+hidev)*hidev/lodev)*hidev/lodev - 0.5*lodev/hidev + 50*((median/ave)/((lodev+hidev)*lodev))^3
Reported by michaelezra000
on 2011-11-10 18:22:05
I tried both formulae, and they still seem to have issues with overly contrasty landscapes
-- the cliff still gets contrast >50 which IMO is way too high.
Reported by ejm.60657
on 2011-11-11 02:30:21
Simply try to change constant 33 to either 29 or 28
Reported by michaelezra000
on 2011-11-11 02:51:32
That's better, though still a bit contrasty on some landscapes. Worst example is the
pine branch (in the pack of images I linked you to) where the contrast maxes out at
100 even with 33->28 (unless I made a mistake).
I am pretty happy with the mod in #82, a little fine-tuning might help it but it's
already quite good on every image I've tested. A little conservative, but that's my
preference; it could easily be jacked up if that was deemed preferable.
Reported by ejm.60657
on 2011-11-11 03:30:04
BTW, thanks for those images very helpful!
I just saw problem with "20101024-160019.nef" as well but this fixes it.
This will likely be closer to your taste:
contr = (29-1.1*(lodev+hidev)*hidev/lodev)*hidev/lodev - 0.5*lodev/hidev + 50*pow((median/ave)/(lodev+hidev),3);
On the other hand should RT have user preference for the strength of the auto levels?
My concern is that auto levels are re-triggered on reopening of the image if they were
previously selected and this will not match previous setting one algorithm is changed.
We could add new parameter to autoexposure and pp3 - autoExpMethod, this way param
files can be backwards compatible.
Reported by michaelezra000
on 2011-11-11 04:06:18
Just to make sure we're on the same page, with the mod in #89 I'm getting the contrast
lowered from 100 to 87 on the problem image "20101024-160019.nef" (let's call it the
'pine bough' image). I still think this is way too high; my preference is about 40-45;
my latest version #82 gives 39.
Reported by ejm.60657
on 2011-11-11 04:36:53
yes 45 is a better setting, the third term in my formula is not working well.
For the picture of black car (6494.NEF) I prefer higher brightness and contrast (42/39).
Autumn image (VT_200910_284.NEF) auto gives 8/29, I prefer (40/54).
Just looking over most of the images the brightness seem to always benefit from multiplication
on hidev/lodev.
Reported by michaelezra000
on 2011-11-11 05:09:45
This should fix the third term:
contr = (29-1.1*(lodev+hidev)*hidev/lodev)*hidev/lodev - 0.5*lodev/hidev + 150*pow((median/ave)/(1+lodev+hidev),3)
The problem was that for narrow bell-shape distributions 1/(lodev+hidev) grows too
fast as (lodev+hidev) <1.
With this change surfer dog is 24
It seems that with this change a single parameter (the first constant, 29 here) can
be used as the main "strength" driver for this contrast formula.
Reported by michaelezra000
on 2011-11-11 06:29:06
It is interesting that such different approaches give mostly similar results for such
high range of scenarios
Reported by michaelezra000
on 2011-11-11 06:38:45
I need to think more on what is a good way to characterize brightness enhancement; I
would rather it be based on some principle (like the octile approach for contrast)
than simply sticking in some factors to deal with specific problem images. I do agree
that without the factor hidev/lodev, the current approach leaves brightness adjustment
too weak.
Reported by ejm.60657
on 2011-11-11 06:56:28
Well, I haven't been able to come up with a manifestly better approach to brightness
-- what we have seems to do a reasonable job in the cases I have examined, slightly
high or low in some cases but always in the ballpark. The final brightness/contrast
formula that I like is
//now find brightness if gain didn't bring ave to midgray
float midtmp = gain*(median)/scale;
if (midtmp<0.1) {
bright = (midgray-midtmp)*15.0/(midtmp);
} else {
bright = (midgray-midtmp)*15.0/(0.10833-0.0833*midtmp);
}
bright = 0.25*(median/ave)*(hidev/lodev)*MAX(0,bright);
contr = 50.0*(1.1-ospread);
contr = MAX(0,MIN(100,contr));
Reported by ejm.60657
on 2011-11-11 20:53:51
This works pretty good:)
I am curious, how did you come up with the constants in
bright = (midgray-midtmp)*15.0/(0.10833-0.0833*midtmp);
The bug with thubmnails could be due to a possible mismatch in the sequence of some
arguments?
I suppose we should add "autolevels method" to the UI to be backwards compatible now
and, possibly, going forward if new methods/strengths are introduced?
The default profile will likely need to become like neutral but with autolevels enabled.
This is a nice cleanup as adaptive auto levels can now hide/compensate shortcomings
of the poor camera matrixes, something I was trying to do with a mix of lab/rgb adjustments
in the default profile.
Reported by michaelezra000
on 2011-11-12 03:33:20
For the structure and constants in the brightness formula, the idea is that bright here
is the envelope of the 'control cage' brightness curve -- the actual brightness function
is less than or equal to this value. If it were the actual brightness function rather
than the envelope of that function, 'bright' would be the value of the brightness slider
that maps 'midtmp' to middle gray. Often this is too strong, thus the subsequent correction
factor 0.25*(median/ave)*(hidev/lodev).
Do we add a choice button to the autolevels interface, or simply read the tag on the
pp3 and apply the old version if the date tag is earlier that the date this upgrade
is implemented. If users then update the pp3 at some point by re-editing, then there
should be some logic that turns off the auto-levels function, leaving the sliders at
the values that were determined by the old autolevels. That way existing users will
not lose old edit settings, and we don't clutter the user interface even more than
it already is.
Perhaps the default profile should incorporate autolevels, and since people seem to
like the new vibrance tool (I haven't had a chance to test it myself, or find out how
it works) use that for saturation in the default profile.
Are we ready for a code cleanup?
Reported by ejm.60657
on 2011-11-12 04:23:51
"If users then update the pp3 at some point by re-editing, then there should be some
logic that turns off the auto-levels function"
I suppose this may be pretty expensive to implement on the individual tool level, may
be at the point when pp3 is saved so evaluation could be made globally.
The thing is that there are not many tools (if any) that allow user to intervene with
auto functions of software. Custom profile builder is the first breakthrough in this
area in RT. But Auto Levels will likely get wider adaptation, as it is so much easier
to use (although of course neither one excludes the other). If we have flexibility
to let users select preferences for auto levels this can cater to various user bases
- batch processors (eg event photography) where finished look is desired out of the
box, raw enthusiasts and possibly more advanced users. I think current state of auto
levels is between raw enthusiast and possibly advanced user needs.
What I had in mind for UI is to replace the toggle button with a (smaller) checkbox
(to make its state is so much easier to see, btw) and use text in the dropdown itself,
without labels: "Auto 'RT3'", "Auto 1", "Auto 2" or some other descriptive short names.
I have not yet done extensive testing with saturation/contrast and vibrance. What concerns
me about the vibrance is Jasques' warning to not to combine it with other saturation
tools for accuracy, as they lead to shifts in hues. However, so does the RGB contrast.
We could let saturation also be auto controlled (wia whatever tool we find more suitable).
Generally it seems that the higher the contrast the less of saturation boost is required
(there might be exceptions I would need to look), but dependency would need to be modeled.
Reported by michaelezra000
on 2011-11-12 05:04:53
One of the examples of auto-level variances could be also be to deviate auto levels
output from currently attempted normalized form to a decisive low key or high key.
Although this could also be implemented by the tone curve on top of existing auto levels.
Reported by michaelezra000
on 2011-11-12 12:32:17
Giving it another thought.. may be this is over complicating, if auto levels give a
normalized image then flavor can be added with a curve preset and applied to many images
when needed via a partial paste/profile preset.
Reported by michaelezra000
on 2011-11-12 12:52:46
agree with #100.
Do we need the 'clip' input any more? It doesn't do much now; I'd be in favor of choosing
a nominal value like 0.001 and dropping it, unless we find that there isn't an acceptable
handling of legacy pp3's without it.
Reported by ejm.60657
on 2011-11-12 14:47:05
Originally reported on Google Code with ID 940
Reported by
michaelezra000
on 2011-08-25 14:42:29