====== RGB UVC Gamma Adjustment ====== At this stage of the imaging pipeline the pixel data is represented in full-range RGB color space with 12-bit precision per component, as produced by the CMX stage ([[isp:gen5-cmx]]). The purpose of this block is to apply **UVC gamma adjustment** in **RGB space** by applying the **same LUT** to all three channels (baseline implementation). This avoids the undesired desaturation artifacts caused by applying a nonlinear transfer function to luma-only in YCbCr. This block is intended to be implemented in FPGA logic and therefore avoids runtime floating-point arithmetic. After this stage completes, the next pipeline stage is the RGB-to-YCbCr conversion stage ([[isp:gen5-rgb-to-yuv]]). ===== Input format ===== The input consists of RGB pixels with the following properties: \[ R12 \in [0..4095]\\ G12 \in [0..4095]\\ B12 \in [0..4095] \] All values are unsigned 12-bit integers. ===== Output format ===== The output format is identical to the input format: \[ R12^{\gamma} \in [0..4095]\\ G12^{\gamma} \in [0..4095]\\ B12^{\gamma} \in [0..4095] \] All three channels are modified by the gamma adjustment stage. ===== Step 1: UVC gamma transfer function ===== Gamma adjustment is applied **independently** to each RGB channel \(R12\), \(G12\), and \(B12\) using the **same** transfer function / LUT. The UVC gamma transfer function is defined in the following document: [[https://wiki.sub2r.com/doku.php/isp:gamma|UVC Gamma Correction Specification]] No additional interpretation or modification of the transfer function is performed at this stage. ===== Step 2: LUT-based FPGA implementation ===== For FPGA implementation, the UVC gamma adjustment shall be realized using a LUT with **4096 entries**, indexed by the 12-bit channel value. Each LUT entry maps a 12-bit input channel value to a 12-bit output channel value: X_in = i // i in range [0..4095] X_out = LUT[i] // gamma-adjusted channel value The same LUT instance (same contents) is used for all channels. ===== Step 3: LUT generation tool ===== To simplify and standardize LUT generation, the following online tool may be used: [[https://toolbox.sub2r.com/sub2r-tb-gamma.html|Sub2r Gamma LUT Generator]] The tool generates FPGA-ready gamma tables compatible with a 12-bit input and 12-bit output pipeline. ===== Step 4: pixel reconstruction ===== For each pixel, the output components are constructed as: \[ R12^{\gamma} = LUT[R12]\\ G12^{\gamma} = LUT[G12]\\ B12^{\gamma} = LUT[B12] \] No additional scaling, offsetting, or clamping is required beyond the LUT bounds. ===== Integration notes ===== This block is placed as follows: ... -> CMX -> RGB UVC Gamma -> RGB-to-YCbCr -> ... The downstream RGB-to-YCbCr block consumes \(R12^{\gamma}\), \(G12^{\gamma}\), and \(B12^{\gamma}\) as its inputs. {{:isp:screenshot_2026-01-27_063531.png?400|}} ===== Expected results ===== * Gamma \(1.0\) is an identity gamma, that produces a LUT of a linear set of incremental values with one-to-one correspondence between input and output * Image doesn't get washed out too much when Gamma is increased (within the \(1.0\)-\(2.5\) range) * Slight hue drift is expected, but not to be an excessive one at extreme Gamma values * LUT table for a given Gamma should match the one produced by the [[https://toolbox.sub2r.com/sub2r-tb-gamma.html|online tool]] ===== Notes ===== * This block operates entirely in **RGB space**. * Gamma adjustment is applied independently to **all three channels** using the **same** LUT (baseline implementation). * This stage assumes **full-range (computer-range) 12-bit RGB** coding.