0

I'm creating a Swift UI application to process images on a device and use the OpenCV library, specifically the BackgroundSubtractor algorithm. I was able to follow the OpenCV iOS guide and perform basic image operations, like take an image, convert to Matrix, make it gray or perform bitwise operations with OpenCV functions but when I try to use the BackgroundSubtractor.apply method, the app crashes with EXC_BAD_ACCESS error:

Thread 1: EXC_BAD_ACCESS (code=2, address=0x10455aa40)

Here is my code:

+ (UIImage *)toMyGreatImage:(UIImage *)source {
    
    Mat sourceMat = [OpenCVWrapper _matFrom:source];
    Mat result;
    
    BackgroundSubtractor *backSub = createBackgroundSubtractorMOG2();
    Mat mask;
    backSub->apply(sourceMat, mask); // crashes here
    return [OpenCVWrapper _imageFrom:mask];
}

Just to compare, my other function works perfectly fine with the same source image:

+ (UIImage *)toGray:(UIImage *)source {
    return [OpenCVWrapper _imageFrom:[OpenCVWrapper _grayFrom:[OpenCVWrapper _matFrom:source]]];
}

I have also tested the background subtractor code in python and it works as expected. What did I miss in my iOS setup?

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
Mando
  • 11,414
  • 17
  • 86
  • 167
  • 1
    `BackgroundSubtractor *backSub = createBackgroundSubtractorMOG2();` dont use a *raw* pointer ! you need a refcounted `Ptr backSub = createBackgroundSubtractorMOG2();` else your newly created instance is DOA – berak Feb 11 '22 at 07:41
  • 1
    Indeed! In my case Ptr<> was ambiguous and no candidates were suggested so I just went with the regular pointer. After your clarification switch to cv::Ptr<> and to works. Thanks for the help. Please post as an answer so I can mark it as a solution. – Mando Feb 11 '22 at 09:12

1 Answers1

1

you need a "smart pointer" to capture your newly created BackgroundSubtractor instance (not a "raw" one), else it will self-destruct, and crash when you call a method on an invalid pointer:

cv::Ptr<BackgroundSubtractor> backSub = createBackgroundSubtractorMOG2();

(note, that cv::Ptr is just an alias for std::shared_ptr nowadays)

(also, tutorial)

berak
  • 1,226
  • 2
  • 5
  • 7