Difference between revisions of "ABMLoose"
From apertus wiki
(Created page with "==Misc Scripts== Display voltages and current flow: ./pac1720_info.sh Output: <nowiki>ZED_5V 5.0781 V [2080] +29.0625 mV [2e8] +968.75 mA BETA_5V 5.1172 V...") |
m |
||
Line 32: | Line 32: | ||
Output: | Output: | ||
ZYNQ Temp 49.9545 °C | ZYNQ Temp 49.9545 °C | ||
==Row noise correction using black reference columns== | |||
Using octave/matlab-like pseudocode. | |||
====For previous frame, compute:==== | |||
For each row: | |||
med_left(y) = median(im(y,1:8)) % median for first 8 columns | |||
med_right(y) = median(im(y,end-7:end)) % median of last 8 columns | |||
For the entire image: | |||
offset_odd_left = median(med_left(1:2:end)) % median of medians from odd left rows | |||
offset_odd_right = median(med_right(1:2:end)) % median of medians from odd right rows | |||
offset_even_left = median(med_left(2:2:end)) % median of medians from even left rows | |||
offset_even_right = median(med_right(2:2:end)) % median of medians from even right rows | |||
====For current frame:==== | |||
'''1. Subtract a dark frame''' (constant image) | |||
im -= dark_frame | |||
'''2. Fix black level offsets''': | |||
* these are expected to change very slowly over time, not from frame to frame, so we are reusing them from previous frame to avoid multiple passes | |||
* subtract an offset for odd rows and another offset for even rows | |||
* the offset varies linearly from left to right | |||
* we will attempt to keep a constant black level: let's say target_black_level = 128 | |||
* subtract these values from each row: | |||
offset_odd(x) = offset_odd_left + (offset_odd_right - offset_odd_left) * x / width - target_black_level; | |||
offset_even(x) = offset_even_left + (offset_even_right - offset_even_left) * x / width - target_black_level; | |||
im(1:2:end,x) -= offset_odd(x) | |||
im(2:2:end,x) -= offset_even(x) | |||
'''3. Fix dynamic row noise''' | |||
* this changes with every frame, and is not correlated from frame to frame | |||
* we have a noisy estimation of this row noise in the black reference columns | |||
* average black columns (16 values for each row): | |||
mb(y) = mean(black_columns)(y) = mean(im(y, [1:8 end-7:end]) | |||
* from each row, we will subtract a scalar value: k * mb(y), where k is 0.6 for gain x1: | |||
im(y,:) -= k * mb(y) | |||
* proof that 0.6 is optimal: https://github.com/apertus-open-source-cinema/misc-tools-utilities/commit/48de47b2a544dc32bbd5a8fd7701bb44a31ea850#diff-624053a553f49c0036b4d31282e58b2fR301 | |||
'''Optional steps (to be tested):''' | |||
* apply a gain frame: | |||
im = (im - target_black_level) .* gain_frame + target_black_level | |||
* apply a clip frame in overexposed highlights: | |||
im(im > clip_thr) -= clip_frame(im > clip_thr) % clip_thr is about 2500 for gain x1; smooth transition might be also needed | |||
* apply a look-up table (either per-channel or global): | |||
im = lut(im) | |||
That's it. | |||
Doing the math on 16 bits is preferred, and when getting back to 12 bits, add one bit of random noise (better results). See pack12/unpack12 on raw2dng for details on the implementation, and http://theory.uchicago.edu/~ejm/pix/20d/tests/noise/noise-p3.html for the rationale behind it. |
Revision as of 15:59, 3 September 2017
1 Misc Scripts
Display voltages and current flow:
./pac1720_info.sh
Output:
ZED_5V 5.0781 V [2080] +29.0625 mV [2e8] +968.75 mA BETA_5V 5.1172 V [20c0] +26.6016 mV [2a9] +886.72 mA HDN 3.2422 V [14c0] -0.0391 mV [fff] -1.30 mA PCIE_N_V 3.2422 V [14c0] -0.0391 mV [fff] -1.30 mA HDS 3.2422 V [14c0] +0.0000 mV [000] +0.00 mA PCIE_S_V 3.2422 V [14c0] -0.0391 mV [fff] -1.30 mA RFW_V 3.2812 V [1500] +0.2734 mV [007] +9.11 mA IOW_V 3.2422 V [14c0] +0.0000 mV [000] +0.00 mA RFE_V 3.2812 V [1500] +0.2344 mV [006] +7.81 mA IOE_V 3.2812 V [1500] +0.0781 mV [002] +2.60 mA VCCO_35 2.5000 V [1000] +0.6641 mV [011] +22.14 mA VCCO_13 2.4609 V [ fc0] +1.2500 mV [020] +41.67 mA PCIE_IO 2.4609 V [ fc0] -0.0391 mV [fff] -1.30 mA VCCO_34 2.4609 V [ fc0] +0.8203 mV [015] +27.34 mA W_VW 1.9922 V [ cc0] -0.0781 mV [ffe] -2.60 mA N_VW 3.1641 V [1440] +0.0000 mV [000] +0.00 mA N_VN 1.8750 V [ c00] +15.4297 mV [18b] +514.32 mA N_VE 3.1641 V [1440] +0.0000 mV [000] +0.00 mA E_VE 1.9922 V [ cc0] -0.0391 mV [fff] -1.30 mA S_VE 1.9531 V [ c80] +0.0000 mV [000] +0.00 mA S_VS 2.9297 V [12c0] +0.3906 mV [00a] +13.02 mA S_VW 1.9922 V [ cc0] -0.1562 mV [ffc] -5.21 mA
Read Temperature on Zynq:
./zynq_info.sh
Output:
ZYNQ Temp 49.9545 °C
2 Row noise correction using black reference columns
Using octave/matlab-like pseudocode.
2.1 For previous frame, compute:
For each row:
med_left(y) = median(im(y,1:8)) % median for first 8 columns med_right(y) = median(im(y,end-7:end)) % median of last 8 columns
For the entire image:
offset_odd_left = median(med_left(1:2:end)) % median of medians from odd left rows offset_odd_right = median(med_right(1:2:end)) % median of medians from odd right rows offset_even_left = median(med_left(2:2:end)) % median of medians from even left rows offset_even_right = median(med_right(2:2:end)) % median of medians from even right rows
2.2 For current frame:
1. Subtract a dark frame (constant image)
im -= dark_frame
2. Fix black level offsets:
- these are expected to change very slowly over time, not from frame to frame, so we are reusing them from previous frame to avoid multiple passes
- subtract an offset for odd rows and another offset for even rows
- the offset varies linearly from left to right
- we will attempt to keep a constant black level: let's say target_black_level = 128
- subtract these values from each row:
offset_odd(x) = offset_odd_left + (offset_odd_right - offset_odd_left) * x / width - target_black_level; offset_even(x) = offset_even_left + (offset_even_right - offset_even_left) * x / width - target_black_level; im(1:2:end,x) -= offset_odd(x) im(2:2:end,x) -= offset_even(x)
3. Fix dynamic row noise
- this changes with every frame, and is not correlated from frame to frame
- we have a noisy estimation of this row noise in the black reference columns
- average black columns (16 values for each row):
mb(y) = mean(black_columns)(y) = mean(im(y, [1:8 end-7:end])
- from each row, we will subtract a scalar value: k * mb(y), where k is 0.6 for gain x1:
im(y,:) -= k * mb(y)
- proof that 0.6 is optimal: https://github.com/apertus-open-source-cinema/misc-tools-utilities/commit/48de47b2a544dc32bbd5a8fd7701bb44a31ea850#diff-624053a553f49c0036b4d31282e58b2fR301
Optional steps (to be tested):
- apply a gain frame:
im = (im - target_black_level) .* gain_frame + target_black_level
- apply a clip frame in overexposed highlights:
im(im > clip_thr) -= clip_frame(im > clip_thr) % clip_thr is about 2500 for gain x1; smooth transition might be also needed
- apply a look-up table (either per-channel or global):
im = lut(im)
That's it.
Doing the math on 16 bits is preferred, and when getting back to 12 bits, add one bit of random noise (better results). See pack12/unpack12 on raw2dng for details on the implementation, and http://theory.uchicago.edu/~ejm/pix/20d/tests/noise/noise-p3.html for the rationale behind it.