2016-11-23 73 views
0

我正在開發iOS項目。我需要在實況視頻中檢測彩色圓圈。 我正在使用CvVideoCameraDelegate。這是我的代碼:iOS - OpenCV視頻處理優化

-(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); 
     } 
    } 
} 

它工作正常,但需要大量的時間和視頻有點laggy。 我想把我的代碼放在另一個隊列中,但是我開始在這條線上獲得EXC_BAD_ACCESScv::medianBlur(image, image, 3);

我開始使用objective-c只是爲了這個項目,所以我很難理解幕後發生了什麼,但我意識到image變量擁有該Mat的地址(至少這是我的C++的知識說),所以當我的代碼執行不再存在的時候。 (對嗎?)

比我試圖解決這個問題。我已添加此

Mat m; 
image.copyTo(m); 

在我的隊列之前。但是這導致了內存泄漏。 (爲什麼不是自動發佈?(再次,沒有太多的obj-c知識)

然後我有最後一個想法,我在隊列的第一行添加了這一行:Mat m = image;。開始變得EXC_BAD_ACCESCV ::墊內,它仍然落後這裏是我的代碼現在的樣子:

-(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教程,因爲我發現的一切都是使用其他環境,或者沒有足夠的處理時間來進行優化。

回答

0

好的,對於那些會遇到同樣問題的人,我設法找出解決方案。我的第二次嘗試的方式非常接近,我試圖處理所有幀的問題(我認爲),所以我把它們全部複製到內存中,並且因爲處理需要很多的時間,所以堆積起來並填充記憶。所以我所做的是我修改了代碼,以便它每次處理一幀,並跳過(顯示未經處理)所有其他幀。