opencvsharpblazorsample

July 14, 2026 ยท View on GitHub

๐Ÿš€ Live demo

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

RouteDescription
/Landing page
/build-infoCv2.GetBuildInformation() output for the OpenCV build compiled into this app
/samples/pseudo-colorApplies a false-color palette to a grayscale photo with Cv2.ApplyColorMap, switchable between colormaps
/samples/thresholdBinarizes a photo with Cv2.Threshold, either a manual slider cutoff or Otsu's automatic threshold
/samples/canny-edgesTunes Canny's two hysteresis thresholds live to see which edges survive
/samples/frequency-filterVisualizes a photo's DFT magnitude spectrum and applies a circular low-pass/high-pass mask before Cv2.Idft
/samples/featuresAKAZE keypoint detection, plus feature matching between an image and a rotated copy of itself
/samples/template-matchingDrag out a patch and find every place it matches elsewhere in the photo with Cv2.MatchTemplate
/samples/detectionReal-time face detection against a live webcam feed using a Haar cascade classifier
/samples/arucoGenerates an ArUco marker and composites it onto a photo at a random position/rotation, then detects it
/samples/color-trackingTunes an HSV range live and tracks the largest matching blob in the webcam feed with Cv2.InRange + FindContours
/samples/optical-flowTracks corner points frame-to-frame in the webcam feed with Cv2.CalcOpticalFlowPyrLK
/samples/interactiveDrag a rectangle over an image to run Cv2.GrabCut and extract the foreground
/samples/watershed-houghLive HoughLinesP/HoughCircles tuning with sliders, plus interactive marker-based Cv2.Watershed segmentation
/samples/shape-analysisDraw a shape and see its convex hull, rotated bounding box, and polygon approximation at once
/samples/distance-transformPaint a blob and visualize how far every pixel is from its nearest edge with Cv2.DistanceTransform
/samples/skeletonPaint a blob and erode it down to a 1-pixel-wide skeleton with Cv2.XImgProc.Thinning
/samples/document-scannerAuto-detects a tilted document's corners with FindContours/ApproxPolyDP, then straightens it with a perspective warp after manual correction
/samples/photo-editingDrag-to-place Cv2.SeamlessClone blending compared against a naive paste, plus paint-to-remove Cv2.Inpaint
/samples/pyramid-blendBlends two photos across a seam using Laplacian pyramids instead of a hard cut
/samples/stitchingStitches two overlapping photos into one panorama with Cv2.Stitcher; stitching is a known-issue preview (see below)
/samples/dnn-detectionReal-time face detection and landmark localization against a live webcam feed using the YuNet ONNX model via Cv2.Dnn
/samples/super-resolutionUpscales a deliberately low-resolution photo 4x with ESPCN via Cv2.DnnSuperres, compared against a naive bicubic resize
/samples/image-classificationClassifies a photo against ImageNet's 1000 categories using MobileNetV2 via Cv2.Dnn.ClassificationModel
/samples/text-detectionDetects regions of text in a photo using PP-OCRv3's DB detector via Cv2.Dnn.TextDetectionModelDB
/samples/object-detectionDetects 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