8 · Embedding C++ OpenCV Object-Detection in Mobile Apps (Swift & Android / .NET MAUI)

8.1 Bridging C++ → Swift

  1. Add OpenCV framework
    File ▸ Add Packages… → search opencv2.framework (or compile & drag-in).
  2. Create an Objective-C++ wrapper
    // DetectorWrapper.mm  (⚠️ .mm)
    #include <opencv2/opencv.hpp>
    extern "C" UIImage * detectObjects(UIImage *imgIOS){
        cv::Mat frame;
        UIImageToMat(imgIOS, frame);               // from cv::imgcodecs
        static cv::HOGDescriptor hog(cv::HOGDescriptor::getDefaultPeopleDetector());
        std::vector<cv::Rect> people;  hog.detectMultiScale(frame, people);
        for(auto &bb: people) cv::rectangle(frame, bb, {0,255,0}, 2);
        return MatToUIImage(frame);                // helper in OpenCV
    }
  3. Expose to Swift via a bridging header
    // DetectorWrapper.h   (added to Bridging Header)
    #import <UIKit/UIKit.h>
    UIImage * _Nullable detectObjects(UIImage * _Nonnull imgIOS);
  4. Call from SwiftUI/View Controller
    let processed = detectObjects(uiImage)

Notes 🛈 : keep UI work on the main thread and heavy OpenCV processing on a background DispatchQueue to avoid UI stutter.

8.2 Android Studio & .NET MAUI

8.2.1 Compile OpenCV as a Shared Library (.so)

# CMakeLists.txt (excerpt)
add_library( cvdetect SHARED Detector.cpp )
find_package( OpenCV REQUIRED )
target_link_libraries( cvdetect ${OpenCV_LIBS} )

8.2.2 JNI Wrapper

// DetectorJNI.cpp
#include <jni.h>
#include <opencv2/opencv.hpp>

extern "C"
JNIEXPORT jintArray JNICALL
Java_com_example_ObjDet_detect(JNIEnv *env,jobject, jlong addr){
    cv::Mat &frame = *(cv::Mat*)addr;
    static cv::HOGDescriptor hog(cv::HOGDescriptor::getDefaultPeopleDetector());
    std::vector<cv::Rect> boxes; hog.detectMultiScale(frame, boxes);

    jintArray out = env->NewIntArray(boxes.size()*4);
    jint *buf = env->GetIntArrayElements(out,nullptr);
    for(size_t i=0;i<boxes.size();++i){
        auto bb=boxes[i]; int j=i*4;
        buf[j]=bb.x; buf[j+1]=bb.y; buf[j+2]=bb.width; buf[j+3]=bb.height;
    }
    env->ReleaseIntArrayElements(out,buf,0);
    return out;
}

8.2.3 Calling from .NET MAUI (C#)

using System.Runtime.InteropServices;

public partial class Detector {
    [DllImport("cvdetect", EntryPoint="Java_com_example_ObjDet_detect")]
    private static extern IntPtr Detect(IntPtr matAddr);

    public static Rect[] Run(SKBitmap bitmap){
        // Convert SKBitmap → cv::Mat via OpenCV for Unity or AOT-friendly helpers
        IntPtr matAddr = /* ... */;
        IntPtr arr = Detect(matAddr);
        // marshal jintArray → Rect[]
    }
}

With these wrappers, your cross-platform MAUI UI remains in C# while the heavy lifting executes inside an optimised C++ OpenCV library.