Копирование объектов OpenCV Mat ускоряется - PullRequest
0 голосов
/ 10 февраля 2019

Недавно я перешел с opencv-python на c ++ версию opencv, потому что я хочу ускорить свое приложение для обработки видео в реальном времени с помощью CUDA.Я новичок в C ++, поэтому я обнаружил некоторые неясные моменты с управлением памятью при оптимизации моего кода.

Например, у меня есть цепочка фильтров, подобная этой:

void apply_blue_edgess(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask) {

      cv::Mat gray_image, blured, canny, canny_3d, in_range_mask;

      cv::cvtColor( matrix, gray_image, CV_BGR2GRAY );
      cv::GaussianBlur( gray_image, blured, cv::Size( 5, 5 ), 0, 0 );
      cv::Canny(blured, canny, 0, 100);
      cv::cvtColor( canny, canny_3d, CV_GRAY2BGR );
      cv::inRange(canny_3d, cv::Scalar(255,255,255), cv::Scalar(255,255,255), in_range_mask);
      canny_3d.setTo(cv::Scalar(0, 171, 255), in_range_mask);
      cv::GaussianBlur( canny_3d, matrix, cv::Size( 5, 5 ), 0, 0 );
      cv::bitwise_and(matrix, mask, matrix);
}

Этонормально использовать новый объект Mat на каждом шаге цепочки фильтров (gray_image, blured, canny, canny_3d, in_range_mask)?Такое непрерывное распределение памяти вредно для производительности?Если да, то как мне писать подобные функции?


Как было предложено в разделе комментариев, я закончил делать обертку функтора:

struct blue_edges_filter {
  blue_edges_filter(int width, int height)
  : gray_image(width, height, CV_8UC1),
    blured(width, height, CV_8UC1),
    canny(width, height, CV_8UC1),
    canny_3d(width, height, CV_8UC3),
    in_range_mask(width, height, CV_8UC3)
  {  }

  int operator()(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask) {

    cv::bitwise_and(matrix, mask, internal_mask_matrix);
    cv::bitwise_and(matrix, inverted_mask, external_mask_matrix);

    cv::cvtColor( matrix, gray_image, CV_BGR2GRAY );
    cv::GaussianBlur( gray_image, blured, cv::Size( 5, 5 ), 0, 0 );
    cv::Canny(blured, canny, 0, 100);
    cv::cvtColor( canny, canny_3d, CV_GRAY2BGR );
    cv::inRange(canny_3d, cv::Scalar(255,255,255), cv::Scalar(255,255,255), in_range_mask);
    canny_3d.setTo(cv::Scalar(0, 171, 255), in_range_mask);
    cv::GaussianBlur( canny_3d, matrix, cv::Size( 5, 5 ), 0, 0 );
    cv::bitwise_and(matrix, mask, matrix);

  }

  private:
    cv::Mat gray_image, blured, canny, canny_3d, in_range_mask;
};

//Usage
blue_edges_filter apply_blue_edgess(1024, 576);
apply_blue_edgess(matrix, mask, inverted_mask);

1 Ответ

0 голосов
/ 11 февраля 2019

Вы можете повторно использовать память без выделения.Создание временных изображений:

  void apply_blue_edgess(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask)
  {
        cv::Mat tmp[2];
        int srcInd = 1;
        auto InvInd = [&]() -> int { return srcInd ? 0 : 1; };
        cv::cvtColor( matrix, tmp[InvInd()], CV_BGR2GRAY );
        srcInd = InvInd();
        cv::GaussianBlur( tmp[srcInd], tmp[InvInd()], cv::Size( 5, 5 ), 0, 0 );
        srcInd = InvInd();
        cv::Canny(tmp[srcInd], tmp[InvInd()], 0, 100);
        srcInd = InvInd();
        cv::cvtColor( tmp[srcInd], tmp[InvInd()], CV_GRAY2BGR );
        srcInd = InvInd();
        cv::inRange(tmp[srcInd], cv::Scalar(255,255,255), cv::Scalar(255,255,255), tmp[InvInd()]);
        tmp[srcInd].setTo(cv::Scalar(0, 171, 255), tmp[InvInd()]);
        cv::GaussianBlur( tmp[srcInd], matrix, cv::Size( 5, 5 ), 0, 0 );
        cv::bitwise_and(matrix, mask, matrix);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...