Code samples showing OpenCvSharp running entirely in the browser via Blazor WebAssembly. All image processing happens client-side, on-device, via WebAssembly — no server involved, no image ever leaves the browser.
| Route | Description |
|---|---|
/ |
Landing page |
/build-info |
Cv2.GetBuildInformation() output for the OpenCV build compiled into this app |
/samples/pseudo-color |
Applies a false-color palette to a grayscale photo with Cv2.ApplyColorMap, switchable between colormaps |
/samples/threshold |
Binarizes a photo with Cv2.Threshold, either a manual slider cutoff or Otsu's automatic threshold |
/samples/canny-edges |
Tunes Canny's two hysteresis thresholds live to see which edges survive |
/samples/frequency-filter |
Visualizes a photo's DFT magnitude spectrum and applies a circular low-pass/high-pass mask before Cv2.Idft |
/samples/features |
AKAZE keypoint detection, plus feature matching between an image and a rotated copy of itself |
/samples/template-matching |
Drag out a patch and find every place it matches elsewhere in the photo with Cv2.MatchTemplate |
/samples/detection |
Real-time face detection against a live webcam feed using a Haar cascade classifier |
/samples/aruco |
Generates an ArUco marker and composites it onto a photo at a random position/rotation, then detects it |
/samples/color-tracking |
Tunes an HSV range live and tracks the largest matching blob in the webcam feed with Cv2.InRange + FindContours |
/samples/optical-flow |
Tracks corner points frame-to-frame in the webcam feed with Cv2.CalcOpticalFlowPyrLK |
/samples/interactive |
Drag a rectangle over an image to run Cv2.GrabCut and extract the foreground |
/samples/watershed-hough |
Live HoughLinesP/HoughCircles tuning with sliders, plus interactive marker-based Cv2.Watershed segmentation |
/samples/shape-analysis |
Draw a shape and see its convex hull, rotated bounding box, and polygon approximation at once |
/samples/distance-transform |
Paint a blob and visualize how far every pixel is from its nearest edge with Cv2.DistanceTransform |
/samples/skeleton |
Paint a blob and erode it down to a 1-pixel-wide skeleton with Cv2.XImgProc.Thinning |
/samples/document-scanner |
Auto-detects a tilted document's corners with FindContours/ApproxPolyDP, then straightens it with a perspective warp after manual correction |
/samples/photo-editing |
Drag-to-place Cv2.SeamlessClone blending compared against a naive paste, plus paint-to-remove Cv2.Inpaint |
/samples/pyramid-blend |
Blends two photos across a seam using Laplacian pyramids instead of a hard cut |
/samples/stitching |
Stitches two overlapping photos into one panorama with Cv2.Stitcher; stitching is a known-issue preview (see below) |
/samples/dnn-detection |
Real-time face detection and landmark localization against a live webcam feed using the YuNet ONNX model via Cv2.Dnn |
/samples/super-resolution |
Upscales a deliberately low-resolution photo 4x with ESPCN via Cv2.DnnSuperres, compared against a naive bicubic resize |
/samples/image-classification |
Classifies a photo against ImageNet's 1000 categories using MobileNetV2 via Cv2.Dnn.ClassificationModel |
/samples/text-detection |
Detects regions of text in a photo using PP-OCRv3's DB detector via Cv2.Dnn.TextDetectionModelDB |
/samples/object-detection |
Detects COCO's 80 object categories in a photo using YOLOX via a raw Cv2.Dnn.Net and a hand-written grid/stride decode |
Most photo-based samples default to a bundled test image, but accept any uploaded photo via a file picker (normalized to a fixed size, with a button to reset back to the default) - the synthetic-image samples (Document Scanner, Watershed & Hough's Hough half, ArUco) don't offer this since they need their specific generated content to demonstrate the algorithm.
- .NET 10 / Blazor WebAssembly
- OpenCvSharp5 + OpenCvSharp5.runtime.wasm
Bundled test images and DNN models are third-party assets, not original work — see BlazorApp/wwwroot/images/README.md and BlazorApp/wwwroot/models/README.md for sources and licenses.
Requires the .NET 10 SDK and the wasm-tools workload:
dotnet workload install wasm-tools
dotnet run --project BlazorAppThen open the URL printed in the console (typically http://localhost:5089).
Pushing to main publishes and deploys the app to GitHub Pages via .github/workflows/deploy-pages.yml.
The current wasm-tools toolchain has a couple of rough edges around statically linking a large native library (like OpenCV) into a Blazor WebAssembly app. BlazorApp.csproj and the deploy workflow carry documented workarounds for:
- AOT-compiling
OpenCvSharp.dllcrashes the Mono AOT compiler (#8) — worked around by excluding just that assembly from AOT compilation. That exclusion in turn breaks loading any component with an OpenCvSharp-typed field (#11), so Release publish currently runs with AOT off entirely until one of the two issues is resolved upstream - The bundled
wasm-optpredates some binaryen features Release publish needs (dotnet/runtime#114723) — worked around by swapping in a newer build during CI publish OpenCvSharp5.runtime.wasmships its native lib aslibOpenCvSharpExtern.a, but the managed side declares[LibraryImport("OpenCvSharpExtern")](nolibprefix); the wasm toolchain derives the P/Invoke module name from the file name verbatim, so this mismatch leaves the P/Invoke table empty (opencvsharp#2039) — worked around by re-referencing a locally renamed copy of the.afile before native buildcv::ocl::haveOpenCL()used to throw instead of returningfalseon this wasm build, hanging or hard-aborting any algorithm that internally allocates acv::UMat(e.g.ORB,CascadeClassifier.DetectMultiScale,Aruco.ArucoDetector.DetectMarkers,Cv2.Stitcher.Stitch) (opencvsharp#2037) — fixed upstream in opencvsharp#2041, confirmed resolved as ofOpenCvSharp5/OpenCvSharp5.runtime.wasm5.0.0.20260712Cv2.DrawMatches' P/Invoke signature crashes the Mono interpreter (OpenCvSharp.dllruns interpreted on this wasm build, per the AOT-exclusion workaround above) (opencvsharp#2040) — the/samples/featurespage works around this by drawing match correspondence lines manually instead of callingCv2.DrawMatchesCv2.Aruco.DrawDetectedMarkerscrashes with "memory access out of bounds" insidecv::FontFace(likely missing freetype/font support in this build) — the/samples/arucopage works around this by drawing each marker's outline and corner manually insteadCv2.Stitcher.Stitchaborts this wasm build with acv::gemmassertion failure deep in the bundle adjustment step, followed by an unrecoverable WASM trap (opencvsharp_blazor_sample#12, not yet root-caused as a core OpenCV bug vs. a usage issue) — the/samples/stitchingpage keeps its "Stitch" button disabled and documents this inline- Without trimming, the wasm linker sees every P/Invoke declared in
OpenCvSharp.dll, including modules the wasm native lib doesn't build (e.g.text,dnn), not just the ones this app calls — worked around byWasmAllowUndefinedSymbolsinBlazorApp.csproj, letting those stay unresolved unless actually invoked at runtime FaceDetectorYN.Createemits aCV_LOG_WARNING(about targets not supported by the new graph engine) that trips Blazor's global unhandled-error banner even though the app keeps running correctly underneath — worked around by raising the log threshold withCv2.SetLogLevel(OpenCvSharp.LogLevel.ERROR)inProgram.cs