Skip to content

Repository files navigation

opencvsharp_blazor_sample

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.

Pages

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.

Stack

Assets

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.

Running locally

Requires the .NET 10 SDK and the wasm-tools workload:

dotnet workload install wasm-tools
dotnet run --project BlazorApp

Then open the URL printed in the console (typically http://localhost:5089).

Deployment

Pushing to main publishes and deploys the app to GitHub Pages via .github/workflows/deploy-pages.yml.

Known issues / workarounds

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.dll crashes 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-opt predates some binaryen features Release publish needs (dotnet/runtime#114723) — worked around by swapping in a newer build during CI publish
  • OpenCvSharp5.runtime.wasm ships its native lib as libOpenCvSharpExtern.a, but the managed side declares [LibraryImport("OpenCvSharpExtern")] (no lib prefix); 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 .a file before native build
  • cv::ocl::haveOpenCL() used to throw instead of returning false on this wasm build, hanging or hard-aborting any algorithm that internally allocates a cv::UMat (e.g. ORB, CascadeClassifier.DetectMultiScale, Aruco.ArucoDetector.DetectMarkers, Cv2.Stitcher.Stitch) (opencvsharp#2037) — fixed upstream in opencvsharp#2041, confirmed resolved as of OpenCvSharp5/OpenCvSharp5.runtime.wasm 5.0.0.20260712
  • Cv2.DrawMatches' P/Invoke signature crashes the Mono interpreter (OpenCvSharp.dll runs interpreted on this wasm build, per the AOT-exclusion workaround above) (opencvsharp#2040) — the /samples/features page works around this by drawing match correspondence lines manually instead of calling Cv2.DrawMatches
  • Cv2.Aruco.DrawDetectedMarkers crashes with "memory access out of bounds" inside cv::FontFace (likely missing freetype/font support in this build) — the /samples/aruco page works around this by drawing each marker's outline and corner manually instead
  • Cv2.Stitcher.Stitch aborts this wasm build with a cv::gemm assertion 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/stitching page 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 by WasmAllowUndefinedSymbols in BlazorApp.csproj, letting those stay unresolved unless actually invoked at runtime
  • FaceDetectorYN.Create emits a CV_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 with Cv2.SetLogLevel(OpenCvSharp.LogLevel.ERROR) in Program.cs

About

OpenCvSharp + Blazor WebAssembly Code Samples

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages