CPGA-Net β€” LiteRT (on-device low-light enhancement, fully-GPU)

CPGA-Net (Shyandram, IJPRAI), low-light image enhancement (brighten dark photos) via Channel Prior + Gamma Correction, converted to LiteRT and running fully on the CompiledModel GPU (ML Drift) on Android. 0.025 M params / 0.1 MB fp16 β€” the smallest model in the LiteRT-Models zoo.

CPGA-Net β€” dark -> enhanced on-device LiteRT GPU

On-device (Pixel 8a, Tensor G3 β€” verified)

nodes on GPU 135 / 135 LITERT_CL (full residency)
inference ~2 ms (256Γ—256)
size 0.1 MB (fp16)
accuracy device-vs-PyTorch corr 0.99999, no NaN
image[1,3,256,256] (RGB [0,1]) β†’[GPU: CPGA-Net]β†’ enhanced[1,3,256,256] ([0,1])

Minimal usage

Android (Kotlin, CompiledModel GPU)

val model = CompiledModel.create(context.assets, "cpga_fp16.tflite",
    CompiledModel.Options(Accelerator.GPU), null)
val inputs = model.createInputBuffers()
val outputs = model.createOutputBuffers()
inputs[0].writeFloat(chw)            // [1,3,256,256] RGB in [0,1], NCHW
model.run(inputs, outputs)
val enhanced = outputs[0].readFloat()    // [1,3,256,256], [0,1]

Python (desktop verification)

import numpy as np
from PIL import Image
from ai_edge_litert.interpreter import Interpreter

img = Image.open("dark.jpg").convert("RGB")
w, h = img.size; s = min(w, h)
img = img.crop(((w-s)//2, (h-s)//2, (w+s)//2, (h+s)//2)).resize((256, 256))
x = (np.asarray(img, np.float32) / 255.0).transpose(2, 0, 1)[None]   # [1,3,256,256]

it = Interpreter(model_path="cpga_fp16.tflite"); it.allocate_tensors()
it.set_tensor(it.get_input_details()[0]["index"], x); it.invoke()
y = it.get_tensor(it.get_output_details()[0]["index"])[0]            # [3,256,256], [0,1]
Image.fromarray((y.transpose(1, 2, 0).clip(0, 1) * 255).astype(np.uint8)).save("enhanced.png")

How it converts (litert-torch) β€” three numerically-exact fixes

  1. Gamma correction x^Ξ³ β†’ exp(Ξ³Β·log x) β€” torch.pow lowers to the banned POW; the identity x^Ξ³ = exp(Ξ³Β·log x) is exact (base clamped to [1e-9,1]) and uses native EXP/LOG.
  2. CBAM / gamma global pools β†’ mean(3).mean(2) and F.max_pool2d(x, (H,W)).
  3. The dark/bright channel prior (max/min over RGB) stays as REDUCE_MAX/REDUCE_MIN.

Banned ops NONE, ≀4D, tflite-vs-torch corr 1.0, device-vs-torch corr 0.99999. Guided-filter disabled.

Preprocessing

Center-crop, resize 256Γ—256, RGB scaled to [0,1], NCHW.

License

MIT. Upstream: Shyandram/CPGA-Net-Pytorch.

Downloads last month
8
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support