CMOS/ADTG/Digic register investigation on ISO

Started by a1ex, January 10, 2014, 12:11:01 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Audionut

Quote from: Greg on January 20, 2014, 06:18:31 PM
In practice, the difference is not so big.  :(

The Nikon 500D result looks slightly better, but it's biased by a lower rendered brightness.

Quinton

Quote from: Audionut on January 20, 2014, 06:32:16 PM
I expose so that the white patch (in the colorchecker) is exposed as high as possible before over exposure.  The images in the above test are exposed 5EV lower with shutter, and increased 5EV in post.  Note:  This should put the black patch around -9.7EV.  I WB and brightness correct from a correctly exposed image.  This removes any error due to noise, and obviously, ensure lighting remains consistent.
Sorry new about here.
Thanks for the explanation, makes much more sense now ;)

Audionut

Would it be possible to option a change of color of the SNR curve, or an option to only screenshot the curve without the background data.  This should make it easy to overlay data in post.

I can get this, but it misses the fine detail in one of the curves.



With my tweaks on the last page.  Changing only ISO in canon menu and CMOS gain in ML.

https://www.dropbox.com/sh/dwobqot98fdm8k3/AAC3WYZhGtwzuHtK_99_trKRa?dl=0

a1ex

The SNR curve needs some offset tweaking first. Since we are tweaking the ISO (getting a different clipping), this results in shifting the curve horizontally (so, 100% in Canon ISO should not be the same as 100% in ML ISO, but right now on the graph they appear to be the same).

Instead, I'd like to consider the test scene as reference (that is, when you double the shutter speed and the shadow noise gets twice as small, you should see a 1-stop difference on the graph). That means we should shift the curve horizontally with the Bv value (from expo menu) and the ISO correction computed by the iso_regs module.

Marsu42

The benefit oft the mini_iso module is automatic, but I still think adding it directly to auto_iso in M mode would be a good idea. In Av and Tv, you cannot do anything about it, the user has to add the +ec gained by ml (since we have no way of intercepting the shot to modify the ec, then reset it afterwards).

But if auto_iso & autoexpo set iso, aperture, shutter and ec in m anyway, wouldn't be a good idea to modify the ec in m value with the exact mini_iso.mo value to always gain optimum exposure? Should this be done in the modules or could mini_iso please deliver a weak function to return a modified Canon 8-system value according to the requested iso?

Audionut

I assume,

static CONFIG_INT("black.ref", black_reference, 0);

is ADTG black (0x8880)?


a1ex


Audionut

Quote from: a1ex on January 20, 2014, 10:37:52 PM
Yes, not implemented yet.

I was going to have a go at doing it myself  :)

Quote from: a1ex on January 20, 2014, 08:34:54 PM
Instead, I'd like to consider the test scene as reference (that is, when you double the shutter speed and the shadow noise gets twice as small, you should see a 1-stop difference on the graph). That means we should shift the curve horizontally with the Bv value (from expo menu) and the ISO correction computed by the iso_regs module.

I'm not sure I understand.  A 1 stop shutter difference shows this.


The entire curve has shifted 1EV.  1/3s shutter shot had clipped highlights which is why the WL didn't shift a full stop.  But the rest of the SNR curve looks like it did.


I know I don't understand what needs to happen for the true ISO adjustments.  But the above data looks accurate.

a1ex

Yes, but they overlap perfectly. Think at one single color patch from your test image: one of them will be rendered with twice as much signal, and roughly the same amount of noise (so the SNR should be roughly 1 stop higher on one of them). And it shows up correctly.

However, the two points on the curve corresponding to our patch are not at the same X position. I want them to be in the same position, so from two overlapped curves I should be able tell how big the improvement was for our patch (and all others). Now I can tell the exposure was shifted to the right, the curve did not really change with shutter speed, but I can't tell how better our patch was rendered.

So, there's nothing wrong with the curve, but to compare things it may be useful to change the X origin (link it to the test scene, not to the recorded data).

Audionut

I like how it shows where the data is rendered in the 14bits also.



My highlight (red dot) got shifted up both scales (as it should IMO).  I should have gained a little extra SNR, but it got clipped at 13.5EV, but I did gain bit depth precision.

My shadow detail (green dot) got shifted down 1EV in both SNR and bitdepth.

edit:  I see your point now, it would be helpful to see how the SNR changed in the image without the bitdepth interference.

hjfilmspeed

Are there more tests needed? Anything I can help with? Not good at programming but in the middle of a snow storm so just sitting here refreshing this page ha ha JK.

5d3 running the nighters

a1ex

Updated some research tools:

iso_regs.mo (source: iso_regs.c) - 5D3 only, requires CONFIG_GDB=y:

- added register 8880 (halfway done by Audionut)
- increased range of B/W offset

adtg_gui.mo (source: adtg_gui.c avl.c avl.h) - cross-platform, requires CONFIG_GDB=y:

- also intercepts DIGIC registers (experimental, there are LOTS of them)
- it adds no less than 4096 menu entries (2048 were not enough on 5D3) => it will slow down boot and menu navigation.
- if you get ERR70 out of memory, change the max region heuristic in memory.c from free_space / 2 to free_space / 4 (or add a wrapper to GetSizeOfMaxRegion)
- it's not usable in LiveView, but if you really want to try, FPS override is your friend

raw_diag.mo (source: raw_diag.c) - cross-platform, anyone can run it

- LiveView support (only relevant in movie mode, not in photo LiveView)
- updated README (including a small TODO list, if anyone feels like coding or doing some math)
- to read it, press Q in ML modules menu

Audionut

I'm seeing some ADTG/CMOS registers being doubled/tripled in the menu.  I'm seeing ADTG6[8000] 4 times.

a1ex


Audionut

edit:  Of course you need to subtract the mean to calculate DR.

ayshih

Regarding raw_diag.mo, this is a very minor quibble, but you may want to tweak the definition of the optical-black region for the left black bar.  You start at y = 20 instead of y = raw_info.active_area.y1 + 20 as is done in raw.c.  The 50D, at least, has a structured pattern for the first ~thirty lines of the top black bar, so starting the optical-black region that early picks up that pattern.  It's so few pixels that it probably doesn't really affect any histograms, but you might as well play it safe.
Canon EOS 50D | 17–40mm f/4L & 70–300mm f/4.5–5.6 DO IS | Lexar 1066x

a1ex

Solved.

Also updated the first post with a little FAQ and links to research tools. If you still have questions, just let me know.

lionelp

Great work Alex and everyone! Appreciate all that you do!
Canon 60D, 50D | Lenses: Nikkor : 18-55 , 3.5 | 50, 1.8 | 24, 2.8 | 28,2.8 | 35, 2.8 |Helios 58 | A few other Nikon manual zooms and prime lenses|
Komputerbay 1000x, Sandisk 95 MB/ s

ayshih

As discussed on a recent pull request, a massively overexposed frame affects the left optical-black region for the 50D (but does not in the 5D Mark III).  This effect complicates determination of the black level and the read noise, and consequently can throw off the measurement of dynamic range.

The first plot shows the histogram for raw_diag.mo with only minor overexposure.  The measured read noise is comparable to that of a dark frame with the same exposure settings.  The second plot shows the histogram when the image is massively overexposed.  You can see that the read noise appears to be larger, which appears to reduce the dynamic range by ~0.2 EV.


Diving into the images themselves, here are the histograms for pairs of columns, starting from the left edge of the sensor (the bottom-most line) and going to just before the image itself (the top-most line).  The solid lines (as opposed to the dashed lines) are the columns in the inner optical-black region used by raw_diag.mo to determine the black level and the read noise.  The first plot, corresponding to the minor overexposure, shows that all of the columns in the inner optical-black region have about the same mean and standard deviation.  The second plot, corresponding to the massive overexposure, shows that all of the columns have about the same standard deviation, but there is significant drift in the mean, and averaging over this drift is what is producing the appearance of a larger read noise and a slight decrease in the black level.


Thus, the read noise isn't actually changing, which is good, but the apparent drift of the black level is not good.  I don't know whether this points to some form of sensor bleed or a deficiency of the black-level clamp.  Either way, on cameras with sensors like the 50D's, take care not to overexpose images by too much.
Canon EOS 50D | 17–40mm f/4L & 70–300mm f/4.5–5.6 DO IS | Lexar 1066x

Audionut

Have you tried making small adjustments to 0x8880?

Audionut

My investigative work so far.

Old settings vs New


mini_iso vs old settings vs new


With the new settings, I've brought the WL back to 15281 and cleaned the histogram further.  However, a close look at the histogram suggests there is probably still some room for (slight) improvement.

@a1ex:  Notice the Digital Gain default changes.  I have no idea what causes this.  I've tried retracing my steps but can't narrow it down.


@all:  No sample images as yet, but my last samples showed that the old settings vs simple ADTG gain adjustment delivered an improvement in image quality.

Digital Gain shifts the entire exposure.  This appears to be digital as it has a large impact on the histogram.  Try adjusting this one first.

Black/White Offset and Saturate Offset are closely aligned.  Adjust either one by N steps and you can adjust the other one by the same N step (in the opposite direction) to bring the histogram back to original.  Here, you can use the BW offset to compensate for digital gain reduction (bring the WL back) and Saturate offset to adjust the black mean. 
So for instance, you can adjust the WL higher then 15281 with BW offset (up to 16383), and use Saturate offset to bring the black mean back to 2048.  Note:  I have tried this and didn't see any improvement (slight negative effect actually), but I've been looking at optical black histograms and adjusting registers for the last 5 days or so, so YMMV.

After I adjust all these, I reduce the ADTG gain to the sweet spot.

I haven't been able to find a pattern to black reference, but I also haven't spent much time with it.  This requires further investigation.


The effect of my new settings on all ISOs.  Note that stdev can vary from shot to shot.




a1ex

@ayshih: for these cameras I would point the camera to a light bulb in the middle of the image, and expose until the edge pixels become dark. If you have like 1% of the image overexposed, it's enough for DR calculation.

@Audionut: default digital gain changes with aperture (it shows Canon is trying to boost the ISO).

Tip: you don't really need to copy Canon settings; you can override only one or two settings at a time, and leave the others to Canon defaults. Might be useful when doing tests at more than one ISO.

I'm not yet sure about 8880 (at first sight it looks it was already tuned to sweet spot by Canon).

ayshih

Quote from: Audionut on January 23, 2014, 04:49:48 AM
Have you tried making small adjustments to 0x8880?

I'm still getting the hang of looking at ADTG registers, but I don't believe the 50D uses that particular register, so I don't know how to change the black level.  (As an aside, I also haven't figured out how to change the ADTG gains on the 50D.  Inspired by Greg's testing with the 500D, I tried overriding the ADTG3[0] and ADTG3[3] registers, but they don't appear to affect anything.)

Thinking more about the effect I've described, it looks like the black-level clamp just has a characteristic time for clamping to the reference voltage (presumably generated by the register value and a DAC), and actually oscillates a bit about the desired level as it gets there.  The amplitude of that oscillation then corresponds to how much the clamp needs to shift the signal in voltage.  If you consider the signal on a given line in an AC-coupled sense, a massive overexposure have a high average charge per pixel, which means that pixels in the optical-black region will be very far from the reference voltage, and the resulting amplitude of the oscillation to be large.  The 5D Mark III presumably has a different, more effective black-level clamp.

If that's the right description, my guess is that there'd be no benefit from small changes to the black level.  Changing the black level by a significant amount could help to stabilize the optical-black region for images that are significantly overexposed, but would compromise normally exposed images, so that doesn't really make sense as a change.

Edit: I got a little mixed up about the direction of the needed change.

Quote from: a1ex on January 23, 2014, 07:59:33 AM
@ayshih: for these cameras I would point the camera to a light bulb in the middle of the image, and expose until the edge pixels become dark. If you have like 1% of the image overexposed, it's enough for DR calculation.

Yup, agreed.
Canon EOS 50D | 17–40mm f/4L & 70–300mm f/4.5–5.6 DO IS | Lexar 1066x

Audionut

If the damage is being done in the CMOS stage, you could presumably fix it there with the digital registers and correct the black level with ADTG.  Just guessing though!

a1ex

Yes, old-generation cameras do not use 888x registers from ADTG (there may be some other registers).

For 5D2, I've got a tiny improvement (0.15 stops) by setting SaturateOffset (0xc0f0819c) from 0x66f to 0x66f + 32 - 1024 - 624 and B/W offset (0xC0F08034) from 0x1991 to 0x1991 + 624. Also fix the digital gain (0xc0f08030) to 0x1000.

The effect of SaturateOffset is that it expands the recorded range while bringing in more highlight detail. So, if your default range is say 1024...15760 and you increase this range to say 32-16383 without changing digital gain (these are the 5D2 values), this would be equivalent to scaling ADTG gain to (15760-1024) / (16383-32) = 0.9 (that is, -0.15 stops). The theory is explained in get_resulting_iso (iso_regs.c).

Basically, ADTG gains and SaturateOffset adjust the same thing internally. So, to get say ISO 77, you can:
a) simply scale factory ADTG gains by 0.77
b) increase the range with SaturateOffset (e.g. with equivalent gain of 0.9) and scale ADTG gains by 0.85 (so the total gain is 0.77). The total gain is limited by the sweet spot (under this point, white level begins to decrease at least in some columns => you get artifacts).

So, on 5D2, the mystery is what register is used for ADTG gain. I believe this gain is used to implement ISO 125 from 100, 250 from 200 and 3200 from 1600 (because of lack of gaps in histogram), but the ADTG tool doesn't report any ADTG register changes when switching between these ISOs.