Skip to content
>sdcb.ai
Newlatest v1.0.0 · Oct 14, 2026Apache-2.0 · MIT modelsnet10.0

SimdGcdrNet

Pure-C# GCDRNet (IEEE TAI 2023): shadow removal and appearance enhancement for camera-captured documents. No onnxruntime or any third-party inference engine.

Install
dotnet add package Sdcb.SimdGcdrNet
dotnet add package Sdcb.SimdGcdrNet.Models
A hand-drawn poster shot on a phone: hand shadow on the left, SimdGcdrNet output on the right
OriginalEnhanced

Drag the divider — a phone photo of a poster with a hard hand shadow

0
third-party inference deps
~9.6 ms
Vulkan end-to-end on a 3080 Ti (1600×1152)
5.9×
vs PyTorch e2e 57.2 ms (30.5 ms pure)
~700 ms
per image in the browser (WASM SIMD + Workers)

Why

Shadows out of phone photos, before anything else

Phone photos of documents almost always carry hand shadows, creases and show-through. GCDRNet is a two-stage network: GC-Net estimates a per-pixel illumination map, a division correction follows, then DR-Net consumes both the original and the corrected image to restore detail.

SimdGcdrNet ports the model and the inference engine itself into C#: a bundled ONNX proto reader and a graph compiler (shape specialization, constant folding, operator fusion, arena planning), with convolutions, LayerNorm and activations hand-written in SIMD. No onnxruntime, no third-party inference engine — one NuGet package is everything.

  • Any interleaved 8-bit layout: Bgr24 / Rgb24 / Bgra32 / Rgba32
  • Arbitrary strides, in-place enhancement
  • Thread-safe GcdrEnhancer
  • Native AOT compatible
  • Models embedded as resources, zero-copy
  • Pads to a multiple of 32 (replicate), crops back
Two-stage pipeline
I_sGC-NetI_sm
inputilluminationshading map
I_GC = clamp(I_s / I_sm, 0, 1) — division correction
DR-Net [I_s; I_GC] 6ch → enhanced
Engine
Managed ONNX proto reader · zero inference deps
Graph compiler — shape specialization · constant folding · operator fusion · arena planning
AVX-512
x64
AVX2 · FMA · MT
x64
AdvSIMD (NEON)
ARM64
PackedSimd
WASM SIMD128
Vector<T> / scalar
portable
Vulkan
cross-platform
Metal
Apple Silicon

Teal: GPU backends. In the browser it is always the CPU PackedSimd tier.

Quick start

Bring your own imaging library — pass pixel memory directly

Program.cs
using Sdcb.SimdGcdrNet;
using Sdcb.SimdGcdrNet.Models;

// Auto:macOS Apple Silicon 优先 Metal,否则 Vulkan,最后退回 CPU(默认值是 Cpu)
using GcdrEnhancer enh = GcdrEnhancer.FromBytes(GcdrModels.GcNet, GcdrModels.DrNet, GcdrBackend.Auto);
// 不用模型包时:GcdrEnhancer.FromFiles("gcdrnet_gcnet_sim.onnx", "gcdrnet_drnet_sim.onnx", ...)

byte[] dst = enh.Enhance(bgr, width: 1600, height: 1152);   // 紧密排列的 BGR24,HWC
// 带 stride、任意 8 位交错格式,输出与输入同格式(alpha 原样拷回),可原地写:
enh.Enhance(srcSpan, w, h, srcStride, dstSpan, dstStride, GcdrPixelFormat.Rgba32);

Performance

From RTX to Snapdragon to the browser

Numbers from the per-device reports under docs/ (49-image RealDAE corpus, warm-up excluded).perf.md ·wasm.md ·corpus.md

RTX 3080 Ti · single 1600×1152

PyTorch vs SimdGcdrNet Vulkan

PyTorchVulkan
inference only0.31×
30.5 ms
9.6 ms
end-to-end (with pre/post)0.17×
57.2 ms
9.6 ms

SimdGcdrNet's 9.6 ms already includes upload/download and pre/post.

Corpus mean · CPU vs GPU

49 RealDAE · ms/img

CPUVulkan
RTX 3080 Ti0.04×
722 ms
28 ms
Arc B5800.09×
414 ms
36 ms
Radeon 880M0.35×
285 ms
100 ms
Adreno 750 (8 Gen 3)0.47×
1030 ms
486 ms

In the browser

Edge · Ryzen 9 5950X · ms/img

Vector<float>PackedSimd
corpus mean (49 img)0.64×
1081 ms
696 ms
1152×1600 gc+dr0.62×
636.3 ms
393.7 ms

Desktop AVX2 on the same 5950X runs ~420 ms/img — the browser reaches 60% of it.

Pairs well

Enhance, then hand off to SimdPaddleOCR

Both libraries consume the same decoded pixel buffer: SimdGcdrNet enhances in place and SimdPaddleOCR reads it straight — no re-encoding, no copies. This RealDAE page on the right has heavy show-through: OCR on the original returns 56 lines (mostly garbage from the back side), on the enhanced image the 14 real lines.

original OCR: 56 linesenhanced: the 14 real lines
A RealDAE document page: show-through mostly gone after enhancement
OriginalEnhanced

Back-side show-through is nearly gone after enhancement

Platforms

One package, everywhere

  • Targets net10.0
  • NativeAOT compatible (IsAotCompatible, no trim/AOT warnings)
  • Models (~21 MB) load straight from embedded resources
  • Measured on Snapdragon 8 Gen 3, RK3399 and in the browser
OSCPUGPU
Windows
x64ARM64
Vulkan
Linux
x64ARM64
Vulkan
macOS
x64ARM64
Metal
Android
ARM64
Vulkan
Browser
wasm
–

NuGet

Packages & models

The Models package is ~21 MB (GC-Net + DR-Net ONNX), shipped as embedded resources and versioned independently of the engine.

Credits

The model comes from the paper “Appearance Enhancement for Camera-captured Document Images in the Wild” (IEEE TAI 2023) and its upstream implementation ZZZHANG-jx/GCDRNet (weights under MIT, Copyright (c) 2024 Jiaxin Zhang).

Sample images and the test corpus come from the RealDAE dataset of the same paper (sdcb/DocGainFixture). The Sdcb.SimdGcdrNet engine is Apache-2.0.

WeChat group QR code

C#/.NET Computer Vision community

Scan to join the WeChat group. The QR code rotates weekly — if it has expired, join QQ group 579060605 instead.