iOS - OpenCV 视频处理优化

iOS - OpenCV Video processing optimization

我正在做一个 iOS 项目。我需要检测实时视频中的彩色圆圈。 我正在使用 CvVideoCameraDelegate。这是我的代码:

-(void)processImage:(cv::Mat &)image{
    cv::medianBlur(image, image, 3);
    Mat hvs;
    cvtColor(image, hvs, COLOR_BGR2HSV);
    Mat lower_red;
    Mat upper_red;
    inRange(hvs, Scalar(0, 100, 100), Scalar(10, 255, 255), lower_red);
    inRange(hvs, Scalar(160, 100, 100), Scalar(179, 255, 255), upper_red);

    Mat red_hue;
    addWeighted(lower_red, 1, upper_red, 1, 0, red_hue);
    GaussianBlur(red_hue, red_hue, cv::Size(9,9), 2,2);


    HoughCircles(red_hue, circles, CV_HOUGH_GRADIENT, 1, red_hue.rows/8,100,20,0,0);
    if(circles.size() != 0){
        for(cv::String::size_type current = 0;current<circles.size();++current){
            cv::Point center(std::round(circles[current][0]),std::round(circles[current][1]));
            int radius = std::round(circles[current][2]);
            cv::circle(image, center, radius, cv::Scalar(0, 255, 0), 5);
        }
    }
}

它工作正常但需要很多时间并且视频有点滞后。 我想把我的代码放在另一个队列中,但我开始在这一行得到 EXC_BAD_ACCESScv::medianBlur(image, image, 3);.

我开始使用 objective-c 只是为了这个项目,所以我有点难以理解幕后发生的事情,但我意识到 image 变量保存了那个 Mat 的地址(至少那是我的 C++ 知识所说的)所以当我达到执行代码的程度时,它就不再存在了。 (我说得对吗?)

然后我试图解决这个问题。我添加了这个

Mat m;
image.copyTo(m);

在我排队之前。但这导致了内存泄漏。 (为什么不是自动释放?(再说一遍,obj-c知识不多)

然后我有了最后一个想法。我在队列的第一行添加了这一行:Mat m = image;。通过这种方式,我开始从 cv::Mat 内部获取 EXC_BAD_ACCES 并且它仍然滞后。这是我的代码现在的样子:

-(void)processImage:(cv::Mat &)image{
    //First attempt
    //Mat m;
    //image.copyTo(m);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        Mat m = image; // second one
        cv::medianBlur(m, m, 3);
        Mat hvs;
        cvtColor(m, hvs, COLOR_BGR2HSV);
        Mat lower_red;
        Mat upper_red;
        inRange(hvs, Scalar(0, 100, 100), Scalar(10, 255, 255), lower_red);
        inRange(hvs, Scalar(160, 100, 100), Scalar(179, 255, 255), upper_red);

        Mat red_hue;
        addWeighted(lower_red, 1, upper_red, 1, 0, red_hue);
        GaussianBlur(red_hue, red_hue, cv::Size(9,9), 2,2);


        HoughCircles(red_hue, circles, CV_HOUGH_GRADIENT, 1, red_hue.rows/8,100,20,0,0);
        if(circles.size() != 0){
            for(cv::String::size_type current = 0;current<circles.size();++current){
                cv::Point center(std::round(circles[current][0]),std::round(circles[current][1]));
                int radius = std::round(circles[current][2]);
                cv::circle(m, center, radius, cv::Scalar(0, 255, 0), 5);
            }
        }
    });

}

我将不胜感激 iOS 中有关视频处理的任何帮助或教程,因为我发现的所有内容都使用其他环境或没有花费足够的处理时间来需要优化。

好的,对于那些遇到同样问题的人,我已经找到了解决方案。我的第二次尝试非常接近,问题(我认为)是我尝试处理所有帧的方式,所以我将所有帧的副本复制到内存中,因为处理需要很多时间,所以它被堆叠起来并填满记忆。所以我所做的是修改代码,使其一次处理一帧并跳过(显示而不处理)所有其他帧。