Light-box protocol: T10 secuplug-t10-jxh42, 2026-11-07
OpenIMP #230 light-box test, generated 2026-11-08 11:57 by lightbox_report.py from run-1107-v2, run-1107-d1d4. Open vs vendor on one camera.
At a glance
The open stack passes 28 of 31 compared checks against the vendor stack; all 3 failed checks are explained or handled (none open).
Key numbers, open vs vendor
Where a direction is defined, open is better in 14, equal (within 3 %) in 7 and worse in 1 rows. This direction chip is the raw open-vs-vendor comparison; pass/fail uses the tolerance of each row.
Contents
- At a glance
- Summary (full text)
- Findings and follow-up (3 rows)
- Deviations and warnings (4)
- Checks (pass/fail) (28 pass, 3 fail)
- Protocol (camera, stacks, lamps)
- A1 P1 defaults (default AE, comp 128)
- A2 Matched exposure + NV12 noise (P2)
- A3 Colour (dE00) and grey row
- A4 Sharpness (slanted edge at the chart edges)
- Pictures (16)
- Method
Summary (full text)
Camera secuplug-t10-jxh42 (T10) in the light box with the SpyderCheckr 24 chart, lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K. Both stacks ran on the same camera, the same chart position and the same light: the open stack (open-tx-isp + OpenIMP + streamer) and the vendor stack (Ingenic ISP module + vendor libimp + streamer built for it), one after the other.
Result: 28 pass, 3 fail (1 vendor difference, 2 accepted), 1 info/warn, 15 planned checks not run in these runs.
Failed checks: frame luma p1_night (AE target, default comp 128) (open 87.2, vendor 76.0; pass = open within +-10 % of vendor); p2_a frame luma at the same exposure (open 70.8, vendor 49.4; pass = within +-3 %); p2_night frame luma at the same exposure (open 68.6, vendor 74.8; pass = within +-3 %).
Passed: frame luma p1_day (AE target, default comp 128); chart grey RG (AWB, 1.0 = neutral); chart grey BG (AWB, 1.0 = neutral); p2_a NV12 temporal noise Y (Y 32..224); p2_a NV12 temporal noise U; p2_a NV12 temporal noise V; p2_b frame luma at the same exposure; p2_b NV12 temporal noise Y (Y 32..224); p2_b NV12 temporal noise U; p2_b NV12 temporal noise V; ...
How to read: "pass" means the open stack is equal to or better than the vendor stack within the tolerance named in each row; matched-exposure rows (A2) compare the same integration time and gain on both stacks, read back from the ISP.
Findings and follow-up
3 rows
One row per failed or deviating (warn) check and how it is handled. Issue states were read from GitHub at generation time. The check name links to its row in the checks table.
| check | stacks | open | vendor | verdict | handling |
|---|---|---|---|---|---|
| frame luma p1_night (AE target, default comp 128) | open, vendor | 87.2 | 76.0 | fail | accepted open is brighter with longer integration time and less noise |
| p2_a frame luma at the same exposure | open, vendor | 70.8 | 49.4 | fail | vendor difference vendor is 2x darker at the same exposure |
| p2_night frame luma at the same exposure | open, vendor | 68.6 | 74.8 | fail | accepted vendor tone curve differs |
Deviations and warnings
4
- box thermometer value was stale (watcher not running): ambient temperature not known for this run
- P2 point a (2x): the vendor stack is 30 % darker than at 4x/8x at the same exposure x gain; open is linear over 2x/4x/8x (vendor quirk at the 2x step).
- Night P2n: at identical exposure the vendor is ~9 % brighter (night tone curve); in P1n defaults open is brighter (longer IT), open noise lower. Low priority.
- 3000 K fair pass: the chart was off-centre (top row and right column cut, PTZ re-homes on every reboot); identical framing on both stacks, so the open/vendor comparison holds. The 5000 K colour pass was centred and checked on a snapshot before the start.
Checks (pass/fail)
28 pass, 3 fail
Cells: open / vendor value, Δ = open - vendor (relative to vendor), then the direction chip (better / equal / worse, where the row defines one) and the pass/fail verdict with its rule. Rows are grouped by test section.
| check | setting | open | vendor | Δ open-vendor | open vs vendor | verdict | rule / note | handling |
|---|---|---|---|---|---|---|---|---|
| A1 P1 defaults | ||||||||
| frame luma p1_day (AE target, default comp 128) | default AE, comp 128 | 91.7 | 92.6 | -0.9 (-1 %) | pass | pass = open within +-10 % of vendor | ||
| frame luma p1_night (AE target, default comp 128) | default AE, comp 128 | 87.2 | 76.0 | +11.2 (+15 %) | fail | pass = open within +-10 % of vendor | accepted open is brighter with longer integration time and less noise | |
| chart grey RG (AWB, 1.0 = neutral) | lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 1.0883 | 1.1063 | -0.0180 (-2 %) | equal | pass | pass = |open - vendor| <= 0.02 | |
| chart grey BG (AWB, 1.0 = neutral) | lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 0.8752 | 0.8806 | -0.0054 (-1 %) | equal | pass | pass = |open - vendor| <= 0.02 | |
| A2 matched exposure | ||||||||
| p2_a frame luma at the same exposure | IT 351 / AGain 32 / IspDG 0 | 70.8 | 49.4 | +21.4 (+43 %) | fail | pass = within +-3 % | vendor difference vendor is 2x darker at the same exposure | |
| p2_a NV12 temporal noise Y (Y 32..224) | IT 351 / AGain 32 / IspDG 0 | 1.200 | 1.117 | +0.083 (+7 %) | worse | pass | pass = open <= vendor x (1 + 2 x A/A spread 5 %) | |
| p2_a NV12 temporal noise U | IT 351 / AGain 32 / IspDG 0 | 0.748 | 0.785 | -0.037 (-5 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 9 %) | |
| p2_a NV12 temporal noise V | IT 351 / AGain 32 / IspDG 0 | 0.440 | 0.509 | -0.069 (-14 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 7 %) | |
| p2_b frame luma at the same exposure | IT 175 / AGain 64 / IspDG 0 | 70.2 | 69.0 | +1.2 (+2 %) | pass | pass = within +-3 % | ||
| p2_b NV12 temporal noise Y (Y 32..224) | IT 175 / AGain 64 / IspDG 0 | 0.865 | 0.892 | -0.027 (-3 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 5 %) | |
| p2_b NV12 temporal noise U | IT 175 / AGain 64 / IspDG 0 | 0.749 | 0.856 | -0.107 (-12 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 9 %) | |
| p2_b NV12 temporal noise V | IT 175 / AGain 64 / IspDG 0 | 0.420 | 0.535 | -0.115 (-21 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 7 %) | |
| p2_c frame luma at the same exposure | IT 88 / AGain 96 / IspDG 0 | 70.0 | 68.7 | +1.3 (+2 %) | pass | pass = within +-3 % | ||
| p2_c NV12 temporal noise Y (Y 32..224) | IT 88 / AGain 96 / IspDG 0 | 1.098 | 1.125 | -0.027 (-2 %) | equal | pass | pass = open <= vendor x (1 + 2 x A/A spread 5 %) | |
| p2_c NV12 temporal noise U | IT 88 / AGain 96 / IspDG 0 | 0.874 | 0.951 | -0.077 (-8 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 9 %) | |
| p2_c NV12 temporal noise V | IT 88 / AGain 96 / IspDG 0 | 0.497 | 0.610 | -0.113 (-19 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 7 %) | |
| p2_night frame luma at the same exposure | IT 73 / AGain 32 / IspDG 0 | 68.6 | 74.8 | -6.2 (-8 %) | fail | pass = within +-3 % | accepted vendor tone curve differs | |
| p2_night NV12 temporal noise Y (Y 32..224) | IT 73 / AGain 32 / IspDG 0 | 1.604 | 1.753 | -0.149 (-8 %) | better | pass | pass = open <= vendor x (1 + 2 x A/A spread 5 %) | |
| A/A repeatability (p2_a vs p2_a2, same point twice) | IT/gain of p2_a | Ytemp 0% U 9% V 3% | Ytemp 0% U 1% V 7% | info | relative |a - a2|; > 15 % = the method is noisier than the difference sought | |||
| A3 colour | ||||||||
| p1_day dE00 mean, unclipped patches | chart_de.py, lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 9.33 | 9.31 | +0.02 (+0 %) | equal | pass | pass = open <= vendor + 1.0 | |
| p1_day dE00 mean, grey-normalised | chart_de.py, lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 7.25 | 7.22 | +0.03 (+0 %) | equal | pass | pass = open <= vendor + 1.0 | |
| p2_a dE00 mean, unclipped patches | chart_de.py, lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 8.73 | 9.24 | -0.51 (-6 %) | better | pass | pass = open <= vendor + 1.0 | |
| p2_a dE00 mean, grey-normalised | chart_de.py, lamps 3000 (fair pass) + 5000 (colour pass, D1/D4) K | 7.03 | 7.26 | -0.23 (-3 %) | better | pass | pass = open <= vendor + 1.0 | |
| grey row tone slope | P1 day | 0.881 | 0.877 | +0.004 (+0 %) | equal | pass | pass = |open - vendor| <= 0.05 | |
| A4 sharpness | ||||||||
| MTF50 median of 8 chart edges (cycles/pixel) | P1 day, 8 frames averaged | 0.481 | 0.434 | +0.047 (+11 %) | better | pass | pass = open >= 0.9 x vendor | |
| 10-90 % edge rise median (px) | P1 day | 0.83 | 0.84 | -0.01 (-1 %) | equal | pass | pass = open <= vendor x 1.1 | |
| B3 CPU/RAM | ||||||||
| system busy % (idle streamer, 60 s) | 0 RTSP clients | 3.20 | 5.30 | -2.10 (-40 %) | better | pass | pass = open <= vendor + 0.5 points | |
| streamer % of all CPU | 0 RTSP clients | 2.59 | 7.37 | -4.78 (-65 %) | better | pass | pass = open <= vendor + 0.5 points | |
| ISP/codec kernel threads % | 0 RTSP clients | 0.05 | 7.92 | -7.87 (-99 %) | better | pass | pass = open <= vendor + 0.5 points | |
| C1 D1/D4 | ||||||||
| D1 dark start: ISP night | streamer daynight trace, dark start, lamps on 180 s, off 180 s | mode=Night | - | pass | 60 s after start in the dark | |||
| D4 lamps off: ISP night after 180 s | streamer daynight trace, dark start, lamps on 180 s, off 180 s | mode=Night | - | pass | ||||
| D4 lamps on: ISP day after 180 s | streamer daynight trace, dark start, lamps on 180 s, off 180 s | mode=Day | - | pass | ||||
| Planned, not run in these runs | ||||||||
| A1b: AE comp sweep 40..200 + path test | - | - | - | not run | not part of the runs in this report | |||
| A2b: AWB 3000/5000 K + WB presets | - | - | - | not run | not part of the runs in this report | |||
| A1c: AE step response (lamps on/off) | - | - | - | not run | not part of the runs in this report | |||
| A2c: noise vs analog gain | - | - | - | not run | not part of the runs in this report | |||
| A4b: substream MTF / colour / NV12 layout | - | - | - | not run | not part of the runs in this report | |||
| A5: encoder H.264/H.265: FixQP bytes, CBR quality | - | - | - | not run | not part of the runs in this report | |||
| A6: banding / flicker | - | - | - | not run | not part of the runs in this report | |||
| A7: night IR picture | - | - | - | not run | not part of the runs in this report | |||
| B1: SSIM/PSNR + P/I ratio | - | - | - | not run | not part of the runs in this report | |||
| B2: RC modes CBR/VBR/FixQP + bitrate jump | - | - | - | not run | not part of the runs in this report | |||
| B5: startup time | - | - | - | not run | not part of the runs in this report | |||
| C4: motion detection (PTZ cams) | - | - | - | not run | not part of the runs in this report | |||
| B4: reload 10x + kill -9 + i2c release | - | - | - | not run | not part of the runs in this report | |||
| C2: control API with picture check | - | - | - | not run | not part of the runs in this report | |||
| C3: stability: 3 RTSP clients, snapshot under load, restart, persistence | - | - | - | not run | not part of the runs in this report | |||
Protocol (camera, stacks, lamps)
| item | value |
|---|---|
| camera | secuplug-t10-jxh42 (T10, sensor jxh42), position: light box, chart centred, camera at the card centre (fixed, no PTZ) |
| run dirs | run-1107-v2, run-1107-d1d4 |
| open stack time (run-1107-v2) | 2026-11-07 22:01:52 .. 22:17:18 |
| open stack time (run-1107-d1d4) | 2026-11-07 23:34:09 .. 23:52:05 |
| vendor stack time (run-1107-v2) | 2026-11-07 22:17:40 .. 22:45:51 |
| lamps | CT 3000 (fair pass) + 5000 (colour pass, D1/D4) K (2 x DiCUNO E14 5 W CRI 98 per CT, DC LED) |
| lamp marker | 22:13:47 NEED_LAMPS_OFF_1 (run-1107-v2) |
| lamp marker | 22:14:05 LAMPS_OFF_1 (run-1107-v2) |
| lamp marker | 22:17:40 NEED_LAMPS_ON (run-1107-v2) |
| lamp marker | 22:17:59 LAMPS_ON (run-1107-v2) |
| lamp marker | 22:41:16 NEED_LAMPS_OFF_2 (run-1107-v2) |
| lamp marker | 22:41:29 LAMPS_OFF_2 (run-1107-v2) |
| lamp marker | 23:38:16 NEED_LAMPS_OFF_1 (run-1107-d1d4) |
| lamp marker | 23:38:36 LAMPS_OFF_1 (run-1107-d1d4) |
| lamp marker | 23:41:36 NEED_LAMPS_ON_2 (run-1107-d1d4) |
| lamp marker | 23:41:49 LAMPS_ON_2 (run-1107-d1d4) |
| lamp marker | 23:44:51 NEED_LAMPS_OFF_3 (run-1107-d1d4) |
| lamp marker | 23:45:04 LAMPS_OFF_3 (run-1107-d1d4) |
| lamp marker | 23:48:32 NEED_LAMPS_ON_4 (run-1107-d1d4) |
| lamp marker | 23:48:45 LAMPS_ON_4 (run-1107-d1d4) |
| box temperature | 21.8 C (STALE: thermometer not logged during the run) |
| flashed image / build | secuplug_sp1_t10l_jxh42_mt7601 build="claude/aperto-port-1107+725a14d, 2026-11-07 19:53:25 UTC" |
| open: ko file in /lib/modules (flashed; the loaded ko is under stack pieces) / libimp mapped | tx_isp_t10 md5=0da5d9d4 libimp=0c0132c8 |
| open: streamer | streamer bin_md5=5d79ec5d version=v1.12.0 |
| open: streamer version (/control) | v1.12.0 |
| vendor: ko file in /lib/modules (flashed; the loaded ko is under stack pieces) / libimp mapped | tx_isp_t10 md5=0da5d9d4 libimp=da38e940 |
| vendor: streamer | streamer bin_md5=69c86ddb version=websocket version 13 required |
| vendor: streamer version (/control) | vendor-t10-bb048e4 |
| open stack pieces (md5) | tx-isp-t10.ko 0da5d9d4 (run-1107-v2), sensor_jxh42_t10.ko b0e940bc (run-1107-v2), libimp.so 0c0132c8 (run-1107-v2), streamer 5d79ec5d (run-1107-v2) |
| vendor stack pieces (md5) | libalog.so 90a3c90d (run-1107-v2), libimp.so da38e940 (run-1107-v2), libsysutils.so 3e9d3e8b (run-1107-v2), tx-isp-t10.ko a9fa2729 (run-1107-v2), sensor_jxh42_t10.ko 36c8fac8 (run-1107-v2), streamer 69c86ddb (run-1107-v2), fair_preload.so d65ce4bf (run-1107-v2), tx-isp-t10.ko 0da5d9d4 (run-1107-v2) |
| open stack | open-tx-isp tx_isp_t10 (flashed) + OpenIMP libimp (flashed) + installed streamer under LD_PRELOAD fair_preload.so |
| vendor stack | ingenic-sdk tx-isp-t10.ko (vendor ISP blob 3.12.0) + sensor_jxh42_t10.ko + vendor libimp 3.12.0 (da38e940) + streamer bb048e4 USE_OPENIMP=0 |
A1 P1 defaults (default AE, comp 128)
| stack | phase | mode | IT (lines) | AGain | IspDG | EV | jpg Y (0..255) | R/G | B/G | clipped | time | run |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| open | p1_day | Day | 450 | 37 | 0 | 570 | 91.7 | 1.0883 | 0.8752 | 0.0 | 22:08:02 | run-1107-v2 |
| vendor | p1_day | Day | 448 | 37 | 2 | 595 | 92.6 | 1.1063 | 0.8806 | 0.0 | 22:35:19 | run-1107-v2 |
| open | p1_night | Night | 208 | 0 | 0 | 256 | 87.2 | - | - | - | 22:16:33 | run-1107-v2 |
| vendor | p1_night | Night | 175 | 0 | 0 | 256 | 76.0 | - | - | - | 22:43:56 | run-1107-v2 |
A2 Matched exposure + NV12 noise (P2)
Same integration time (lines) and gains (x1024) forced on both stacks through the streamer, read back from the ISP (verify). NV12: 8 frames of channel 1, centre half, temporal std per pixel.
| stack | phase | verify | mode | IT (lines) | AGain | IspDG | EV | jpg Y (0..255) | NV12 Y (0..255) | Ytemp (std) | U (std) | V (std) | drift | time | run |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| open | p2_a | ok | Day | 351 | 32 | 0 | 512 | 70.8 | 78.52 | 1.200 | 0.748 | 0.440 | 0.10 | 22:09:14 | run-1107-v2 |
| vendor | p2_a | ok | Day | 351 | 32 | 0 | 512 | 49.4 | 55.52 | 1.117 | 0.785 | 0.509 | 0.18 | 22:36:34 | run-1107-v2 |
| open | p2_a2 | ok | Day | 351 | 32 | 0 | 512 | 70.5 | 78.22 | 1.202 | 0.825 | 0.454 | 0.10 | 22:12:08 | run-1107-v2 |
| vendor | p2_a2 | ok | Day | 351 | 32 | 0 | 512 | 49.4 | 55.45 | 1.113 | 0.792 | 0.549 | 0.22 | 22:39:34 | run-1107-v2 |
| open | p2_b | ok | Day | 175 | 64 | 0 | 1024 | 70.2 | 77.95 | 0.865 | 0.749 | 0.420 | 0.11 | 22:10:12 | run-1107-v2 |
| vendor | p2_b | ok | Day | 175 | 64 | 0 | 1024 | 69.0 | 75.95 | 0.892 | 0.856 | 0.535 | 0.22 | 22:37:35 | run-1107-v2 |
| open | p2_c | ok | Day | 88 | 96 | 0 | 2048 | 70.0 | 78.10 | 1.098 | 0.874 | 0.497 | 0.29 | 22:11:10 | run-1107-v2 |
| vendor | p2_c | ok | Day | 88 | 96 | 0 | 2048 | 68.7 | 76.10 | 1.125 | 0.951 | 0.610 | 0.19 | 22:38:34 | run-1107-v2 |
| open | p2_night | ok | Night | 73 | 32 | 0 | 512 | 68.6 | 125.48 | 1.604 | - | - | 0.70 | 22:17:17 | run-1107-v2 |
| vendor | p2_night | ok | Night | 73 | 32 | 0 | 512 | 74.8 | 134.21 | 1.753 | - | - | 0.94 | 22:44:41 | run-1107-v2 |
A3 Colour (dE00) and grey row
chart_de.py (audit/issue230/colour) per phase, cells = open / vendor. Lower dE00 is better.
| phase | dE00 mean | dE00 median | dE00 max | dE00 mean, unclipped patches | dE00 mean, grey-normalised | chroma ratio (1 = reference) | dE00 skin patches | grey a* cast | grey b* cast | gamma fit |
|---|---|---|---|---|---|---|---|---|---|---|
| p1_day | 9.41 / 9.40 | 8.30 / 8.28 | 16.10 / 16.08 | 9.33 / 9.31 | 7.25 / 7.22 | 0.83 / 0.83 | 14.87 / 14.83 | -2.03 / -1.90 | 5.91 / 5.62 | 0.91 / 0.90 |
| p2_a | 8.73 / 9.24 | 7.20 / 7.90 | 15.70 / 16.69 | 8.73 / 9.24 | 7.03 / 7.26 | 0.90 / 0.92 | 15.22 / 16.28 | -0.75 / -0.01 | 4.94 / 3.81 | 1.02 / 1.07 |
Suite colour-cct, P1 day
audit/chart/spyder.py: sRGB -> Lab D50, CIEDE2000, reference = Datacolor default values, D50 assumed, not batch specific.
| metric | open | vendor | Δ open-vendor | open vs vendor |
|---|---|---|---|---|
| dE00 mean (raw) | 8.67 | 8.49 | +0.18 (+2 %) | equal |
| dE00 mean (grey-normalised) | 7.68 | 7.51 | +0.17 (+2 %) | equal |
| dE00 colour patches | 9.72 | 9.44 | +0.28 (+3 %) | equal |
| dE00 grey patches | 5.51 | 5.67 | -0.16 (-3 %) | equal |
| dE00 max | 14.37 | 13.88 | +0.49 (+4 %) | worse |
| chroma ratio (1 = reference) | 0.83 | 0.85 | -0.02 (-2 %) | equal |
| mean hue error deg | 6.72 | 6.94 | -0.22 (-3 %) | better |
| grey a* cast | 0.84 | 0.75 | +0.09 (+12 %) | worse |
| grey b* cast | 5.96 | 5.81 | +0.15 (+3 %) | equal |
dE00 per patch, P1 day
| patch | open | vendor | patch | open | vendor |
|---|---|---|---|---|---|
| A1 | 15.1 | 15.3 | C1 | 15.4 | 15.4 |
| A2 | 6.9 | 6.6 | C2 | 6.1 | 6.1 |
| A3 | 7.2 | 7.0 | C3 | 8.7 | 8.6 |
| A4 | 5.6 | 5.4 | C4 | 5.4 | 5.4 |
| A5 | 2.9 | 2.9 | C5 | 10.7 | 10.8 |
| A6 | 3.0 | 2.8 | C6 | 14.6 | 14.6 |
| B1 | 7.9 | 7.9 | D1 | 13.1 | 13.2 |
| B2 | 7.1 | 7.1 | D2 | 13.5 | 13.5 |
| B3 | 11.3 | 11.6 | D3 | 12.2 | 12.2 |
| B4 | 4.4 | 4.4 | D4 | 11.1 | 11.2 |
| B5 | 7.6 | 7.6 | D5 | 16.1 | 16.1 |
| B6 | 6.3 | 6.2 | D6 | 13.6 | 13.6 |
Grey row A1..A6
| metric | open | vendor | Δ open-vendor | open vs vendor |
|---|---|---|---|---|
| tone slope log-log (1 = reference gamma) | 0.881 | 0.877 | +0.004 (+0 %) | equal |
| mean dL | -3.357 | -3.478 | +0.121 (-3 %) | |
| max |dL| | 18.662 | 19.272 | -0.610 (-3 %) | better |
| white A1 code | 244.497 | 245.000 | -0.503 (-0 %) | |
| black A6 code | 55.386 | 56.259 | -0.873 (-2 %) | |
| clipped greys | 0.000 | 0.000 | +0.000 | equal |
| range ratio | 23.453 | 22.856 | +0.597 (+3 %) | |
| code A1 | 244.497 | 245.000 | -0.503 (-0 %) | |
| code A2 | 239.720 | 242.154 | -2.434 (-1 %) | |
| code A3 | 201.602 | 203.716 | -2.114 (-1 %) | |
| code A4 | 155.728 | 157.538 | -1.810 (-1 %) | |
| code A5 | 111.521 | 112.338 | -0.817 (-1 %) | |
| code A6 | 55.386 | 56.259 | -0.873 (-2 %) |
A4 Sharpness (slanted edge at the chart edges)
Outer edge of the two middle patches on every chart side (patch vs black chart frame), 8 frames averaged, edge ESF with sub-pixel registration from the small chart tilt (lbmetrics.edge_sharpness): 10-90 % rise in pixels (lower = sharper) and MTF50 in cycles/pixel (higher = sharper).
| edge | rise open (px) | rise vendor (px) | MTF50 open (c/p) | MTF50 vendor (c/p) | contrast o | contrast v | tilt (deg) |
|---|---|---|---|---|---|---|---|
| bottom-23 | 0.83 | 0.84 | 0.481 | 0.434 | 77 | 81 | -2.4 |
| bottom-33 | 1.47 | 1.48 | 0.321 | 0.315 | 53 | 52 | -3.7 |
| left-01 | - | - | - | - | - | - | - |
| left-02 | 0.79 | 0.80 | 0.563 | 0.531 | 125 | 118 | 2.2 |
Pictures
16
Downscaled to 800 px, JPEG q75. Chart and grey card only. Click a picture to see it large (Esc or click closes).
A1 p1_day
A1 p1_night
A2 p2_a
A2 p2_night
A3 dE00 overlay p1_day (chart_de.py)
A3 dE00 overlay p2_a (chart_de.py)
A4 MTF crops
Method
- Same camera, same chart position, same lamps; open stack first, then the vendor ISP module + vendor libimp are loaded from /tmp (nothing flashed); the camera returns to the flashed image at the end (module reload or reboot).
- P1 = camera defaults (AE, AWB, comp 128). P2 = matched exposure: the same integration time and gains on both stacks, set inside the streamer and read back from the ISP; rows whose read-back differs are marked verify=FAIL and not compared.
- A/A: point p2_a is measured twice (p2_a, p2_a2); the relative difference is the repeatability of the method. A difference between the stacks counts only beyond 2 x that spread (floor 5 %).
- NV12 noise is measured on raw NV12 frames from the streamer (no JPEG in the path): temporal standard deviation per pixel over the burst, mean over Y 32..224, and U/V.
- Colour: SpyderCheckr 24 detected automatically, sRGB -> Lab (D50), CIEDE2000 against the Datacolor default values (D50 assumed, not batch specific); 'grey-normalised' removes the white-balance cast first.
- Sharpness: slanted-edge method on the chart's outer patch edges, frames averaged against noise; JPEG snapshot path.
- SSIM/PSNR (when run): both stacks record the same static chart scene at the same bitrate; each stream is decoded and compared against a high-bitrate capture of the SAME stack (reference), so the number is the encoder loss of that stack; a cross-stack comparison on static frames is listed separately and includes the ISP difference.
- Encoder (A5): both stacks get the same streamer settings (codec, rc_mode, qp / bitrate, gop) through a /tmp conf and a streamer restart; the recordings come over RTSP (ffmpeg -c copy). The reference is a mean image, because single NV12 frames are not frame-aligned with the stream; the scene is static, so every decoded frame can be compared with it. A second reference at the end of the phase shows whether the scene or the AE moved in between.
- Lamp switches are made by a person on a marker (NEED_* file); the times above are the marker times.