gpu::blur 函数需要更多时间

gpu::blur function takes significantly more time

这是我尝试针对 GPU 优化的函数。 gpu::blur 在此代码中花费了相当长的时间。当我使用此代码的 运行 正常 CPU 版本时,执行 30 张图像需要大约 1.5 秒(framesToProcess 包含 30 张图像)。当我 运行 这段代码(使用 gpu:: 函数和 GpuMat )时,它需要超过 30 秒。如果我评论 gpu::blur 行,执行只需要 0.5 秒。请帮我找出 GPU 版本有什么问题。

void getContourCenters(vector<gpu::GpuMat>  &framesToProcess, vector<pointI>& contourCenter)
{
    size_t j = 0;

    for (int i = 1; i < framesToProcess.size(); i++)
    {

            gpu::GpuMat tempDifferenceImage, tempThresholdImage, tempBlurredImage;
            vector< vector<Point> > contours;
            vector<Vec4i> hierarchy;
            Rect objectBoundingRectangle = Rect(0, 0, 0, 0);
            gpu::absdiff(framesToProcess[i - 1], framesToProcess[i], tempDifferenceImage);
            gpu::threshold(tempDifferenceImage, tempThresholdImage, SENSITIVITY_VALUE, 255, THRESH_BINARY);
            gpu::blur(tempThresholdImage, tempBlurredImage, Size(BLUR_SIZE, BLUR_SIZE));

            Mat contourImage( tempBlurredImage );
            findContours(contourImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
            for (int k = 0; k < contours.size(); ++k)
            {
                    objectBoundingRectangle = boundingRect(contours[k]);
                    int xpos = objectBoundingRectangle.x + objectBoundingRectangle.width / 2;
                    int ypos = objectBoundingRectangle.y + objectBoundingRectangle.height / 2;
                    contourCenter.push_back(mp(xpos, ypos, j++));
            }
    }
}

BLUR_SIZE 是一个常数,值为 50。图像大小为 992 X 1000,CV_8UC1 类型图像。我 运行 正在使用 Nvidia Tegra K1。这是代码的另一个版本:

    void getContourCenters(vector<Mat>  &framesToProcess, vector<pointI>& contourCenter)
{    
    size_t j = 0;       
    for (int i = 1; i < framesToProcess.size(); i++)
    {    
                    Mat tempDifferenceImage, tempThresholdImage;
                    vector< vector<Point> > contours;
                    vector<Vec4i> hierarchy;
                    Rect objectBoundingRectangle = Rect(0, 0, 0, 0);
                    absdiff(framesToProcess[i - 1], framesToProcess[i], tempDifferenceImage);
                    threshold(tempDifferenceImage, tempThresholdImage, SENSITIVITY_VALUE, 255, THRESH_BINARY);
                    blur(tempThresholdImage, tempThresholdImage, Size(BLUR_SIZE, BLUR_SIZE));
                    findContours(tempThresholdImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

                    for (int k = 0; k < contours.size(); ++k)
                    {
                            objectBoundingRectangle = boundingRect(contours[k]);
                            int xpos = objectBoundingRectangle.x + objectBoundingRectangle.width / 2;
                            int ypos = objectBoundingRectangle.y + objectBoundingRectangle.height / 2;
                            contourCenter.push_back(mp(xpos, ypos, j++));
                    }           

    }

}

这段代码在同一台机器上执行需要1.5秒。我想针对 GPU 优化此代码并编写了上面提到的版本,这花费了 30 多秒。

因此,正如我在评论中所述,OpenCV 已经优化了 Tegra 支持(如果使用了 opencv4tegra 库),因此您的 OpenCV GPU 函数很可能不是真正的 "slow",而是您的 "CPU" 版本实际上非常快,因为它在内部调用了一些 tegra 优化函数(而不是使用 CPU)。

http://on-demand.gputechconf.com/gtc/2013/presentations/S3411-OpenCV-For-Tegra.pdf可以看出opencv4tegra有几个优化,包括

  1. NEON SIMD 指令
  2. GLSL 算法,使用 opengl 着色器来加速
  3. Tegra 硬件优化

它们都使用相同的已知 "CPU" API.

其他细节可以在http://docs.opencv.org/opencv2refman-tegra.pdf

中找到

a list of OpenCV functions that are optimized for Tegra platform in the current OpenCV release. Optimization covers the most popular data types and operation modes, that are specified for each function below. When an optimized function is called on a data type or a mode that is not covered by optimization, the original implementation is called.

  • cv::absdiff
  • cv::添加
  • cv::addWeighted
  • 简历::bitwise_and
  • 简历::bitwise_not
  • 简历::bitwise_or
  • 简历::bitwise_xor
  • cv::比较
  • cv::countNonZero
  • cv::Mat::dot
  • cv::inRange
  • cv::max
  • cv::mean
  • cv::meanStdDev
  • 简历::合并
  • cv::min
  • cv::minMaxLoc
  • cv::相位
  • cv::reduce
  • cv::split
  • cv::subtrac
  • cv::sum
  • cv::Mat::convertTo

  • cv::blur

  • cv::boxFilter
  • cv::Canny
  • cv::cvtColor
  • cv::扩张
  • cv::侵蚀
  • cv::filter2D
  • cv::高斯模糊
  • cv::积分
  • cv::matchTemplate
  • cv::中值模糊
  • cv::pyrDown
  • cv::pyrUp
  • cv::resize
  • cv::Scharr
  • cv::索贝尔
  • cv::阈值
  • cv::warpAffine
  • cv::warpPerspective

  • cv::FAST

  • cv::calcOpticalFlowPyrLK

  • cv::buildOpticalFlowPyramid

  • cv::detail::createLaplacePyr

  • cv::detail::normalizeUsingWeightMap
  • cv::detail::BestOf2NearestMatcher::match

  • cv::findCirclesGrid

在文档中标记了哪些函数是 GPU 驱动的