簡體   English   中英

在iOS上帶有OpenCV`cv :: aruco :: detectMarkers()`的EXEC_BAD_ACCESS

[英]EXEC_BAD_ACCESS w/ OpenCV `cv::aruco::detectMarkers()` on IOS

  • opencv:4.1.0(帶有'contrib'擴展名)
  • 迅速:5
  • iOS:12.2

我試圖在iphone攝像機的每一幀上運行opencv的方法cv::aruco::detectMarkers 這可以正常工作,但是在一分鍾左右后它因錯誤而崩潰: Thread 8: EXC_BAD_ACCESS (code=1, address=0x10dea0000)

我已經包括了我認為是應用程序的兩個最相關的部分,即UIViewControllerObjective-C包裝器,並且在每行中都標記了兩行,並在其中注釋了異常。

在我看來這並不是一個並發問題,因為它應該在主線程上同步運行。

這是thread backtrace的結果

* thread #8, queue = 'com.apple.root.default-qos', stop reason = EXC_BAD_ACCESS (code=1, address=0x10dea0000)
  * frame #0: 0x000000010505c700 Camera`cv::pointSetBoundingRect(cv::Mat const&) + 432
    frame #1: 0x000000010505c8c0 Camera`cvBoundingRect + 236
    frame #2: 0x0000000104fdf168 Camera`cvFindNextContour + 4348
    frame #3: 0x0000000104fe00fc Camera`cvFindContours_Impl(void*, CvMemStorage*, CvSeq**, int, int, int, CvPoint, int) + 1008
    frame #4: 0x0000000104fe118c Camera`cv::findContours(cv::_InputArray const&, cv::_OutputArray const&, cv::_OutputArray const&, int, int, cv::Point_<int>) + 972
    frame #5: 0x0000000104fe1bb0 Camera`cv::findContours(cv::_InputArray const&, cv::_OutputArray const&, int, int, cv::Point_<int>) + 96
    frame #6: 0x000000010507df68 Camera`cv::aruco::DetectInitialCandidatesParallel::operator()(cv::Range const&) const + 2056
    frame #7: 0x0000000104f8e068 Camera`(anonymous namespace)::ParallelLoopBodyWrapper::operator()(cv::Range const&) const + 248
    frame #8: 0x0000000104f8df5c Camera`(anonymous namespace)::block_function(void*, unsigned long) + 32
    frame #9: 0x0000000105318824 libdispatch.dylib`_dispatch_client_callout2 + 20

這就是我設置AVCaptureVideoDataOutputSampleBufferDelegate ,該方法接收每個幀作為CMSampleBuffer ,將其轉換為UIImage並將該UIImage發送到opencv以進行Aruco標記檢測。

extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate {
    func captureOutput(
        _ output: AVCaptureOutput,
        didOutput sampleBuffer: CMSampleBuffer,
        from connection: AVCaptureConnection) {

        let image : UIImage = self.sample_buffer_to_uiimage(sampleBuffer: sampleBuffer)

        // call out to opencv wrapper, which eventually blows up
        let annotated_image : UIImage = OpenCVWrapper.drawMarkers(image)

        self.imageView.image = annotated_image

    }
    func sample_buffer_to_uiimage(sampleBuffer:CMSampleBuffer) -> UIImage
    {
        let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
        let cimage : CIImage  = CIImage(cvPixelBuffer: imageBuffer)
        let context:CIContext = CIContext.init(options: nil)
        let cgImage:CGImage   = context.createCGImage(cimage, from: cimage.extent)!
        let image:UIImage     = UIImage.init(cgImage: cgImage)
        return image
    }
}

這就是我設置Objective-C OpenCV包裝器方法的方式

+(UIImage *) drawMarkers:(UIImage *)image {

    cv::Mat colorImageRGBA;
    cv::Mat colorImage;
    cv::Mat grayImage;

    UIImageToMat(image, colorImageRGBA);

    cvtColor(colorImageRGBA, grayImage, cv::COLOR_BGR2GRAY);
    cvtColor(colorImageRGBA, colorImage, cv::COLOR_RGBA2RGB);

    cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);

    std::vector<int> markerIds;
    std::vector<std::vector<cv::Point2f>> markerCorners;

    // this is the line that blows up
    cv::aruco::detectMarkers(grayImage, dictionary, markerCorners, markerIds);

    if (markerIds.size() > 0) {
        cv::aruco::drawDetectedMarkers(colorImage, markerCorners, markerIds);
    }

    return MatToUIImage(colorImage);
}

我報告了一個可以在這里找到的問題: https : //github.com/opencv/opencv/issues/15078

詳細信息已在問題中報告,但是恢復為OpenCV 4.0.0將解決您的問題。 合並請求期間可能出了些問題,並且3.4.6的代碼庫已合並到4.1.0。

因為cv::pointSetBoundingRect在OpenCV 3.4.6和4.1.0中具有完全相同的代碼,但是在4.0.0中已對其進行了重構。

在4.1.0中使用舊代碼庫可能會使NEON / SSE優化陷入混亂。

不幸的是,要更深入地調試源代碼並找到確切的問題並不容易。

干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM