opencv2.framework
(or compile & drag-in).
// 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
}
// DetectorWrapper.h (added to Bridging Header)
#import <UIKit/UIKit.h>
UIImage * _Nullable detectObjects(UIImage * _Nonnull imgIOS);
let processed = detectObjects(uiImage)
Notes 🛈 : keep UI work on the main thread and heavy OpenCV processing on a background
DispatchQueue
to avoid UI stutter.
# CMakeLists.txt (excerpt)
add_library( cvdetect SHARED Detector.cpp )
find_package( OpenCV REQUIRED )
target_link_libraries( cvdetect ${OpenCV_LIBS} )
// 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;
}
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[]
}
}
armeabi-v7a
, arm64-v8a
, & x86_64
→ Platforms/Android
.<uses-feature android:name="android.hardware.camera" />
in AndroidManifest.-O3 -s
flags for native code.With these wrappers, your cross-platform MAUI UI remains in C# while the heavy lifting executes inside an optimised C++ OpenCV library.