2016-11-23 3 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); 
     } 
    } 
} 

Он отлично работает, но занимает много времени, и видео немного лаги. Я хотел поставить свой код в другую очередь, но я начал получать EXC_BAD_ACCESS на этой строке: cv::medianBlur(image, image, 3);.

Я начал использовать объектив-c только для этого проекта, поэтому мне немного сложно понять, что происходит за кулисами, но я понял, что переменная image содержит адрес этого мата (по крайней мере, это то, Знание C++ говорит), поэтому, когда мой вопрос доходит до выполнения кода, он больше не существует. (Я прав?)

Чем я пытался обойти эту проблему. Я добавил (а) это

Mat m; 
image.copyTo(m); 

перед моей очередью. Но это вызвало утечку памяти. (Почему не выдается автоматически? (Опять же, не слишком много знаний obj-c)

Тогда у меня была последняя идея. Я добавил эту строку: Mat m = image; в первой строке очереди. начал получать 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); 
      } 
     } 
    }); 

} 

Я был бы признателен за любую помощь или, возможно, учебник о обработках видео в прошивке, потому что все, что я нашел, использовалось в других средах или не занимало достаточно времени для оптимизации.

ответ

0

Хорошо, для тех, у кого будет такая же проблема, мне удалось выяснить решение. Моя вторая попытка очень близка, проблема (я думаю), что я пытался обработать все фреймы, поэтому я сделал копию всех из них в памяти и потому, что обработка занимает много времени в болоте, она была сложена и заполнена память. Так что я сделал то, что я модифицировал код, чтобы он обрабатывал один кадр за раз и пропускал (показывает без обработки) все остальные.

Смежные вопросы