这是我基于OpenCV的代码:

int main()
{
    clock_t start, stop;
    Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
    img.convertTo(img, CV_32F, 1.0);
    float *imgInP = (float *)img.data;    // get the input data point
    Mat imgOut = Mat::zeros(Size(img.rows, img.cols), CV_32F);   // create output mat
    float *imgOutP = (float *)imgOutP.data;  // get the output data point

    // test several calling of opencv boxFilter
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 1 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 2 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
     start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 3 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;

    return 0;
}

这是上面程序的输出:

OpenCV 1上的BoxFilter: 72.368ms

OpenCV 2上的BoxFilter: 0.495毫秒

OpenCV 3上的BoxFilter: 0.403毫秒

为什么第一个调用boxFilter(72.368ms)花费的时间比第二个(0.495ms)和第三个(0.403 ms)的多得多

更重要的是,如果我第三次调用boxFilter来更改输入图像,输出也不会改变。因此,它可能不是图像数据缓存的因素...

感谢您的任何建议。

我的系统是Ubuntu 14.04,i5-4460,12GB RAM,OpenCV版本:3.1,cmake版本:3.2,g++版本:4.8.4

以下是我的cmake文件:
cmake_minimum_required(VERSION 3.7)
project(boxfilterTest)

set(CMAKE_CXX_STANDARD 11)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

set(SOURCE_FILES main.cpp)
add_executable(boxfilterTest ${SOURCE_FILES})

target_link_libraries(boxfilterTest ${OpenCV_LIBS})

IDE是CLion。

最佳答案

差异的原因是时序是由于指令缓存和数据缓存所致。可以通过强制将矩阵重新分配为其他大小(例如调整图像大小)来验证数据缓存。如果在对boxFilter的不同调用之间调整图像的大小,则boxFilter调用的执行时间将变得非常接近。这是演示上述现象的示例代码。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    clock_t start, stop;
    Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
    img.convertTo(img, CV_32F, 1.0);
    float *imgInP = (float *)img.data;    // get the input data point
    Mat imgOut = Mat::zeros(Size(img.rows, img.cols), CV_32F);   // create output mat
    float *imgOutP = (float *)imgOut.data;  // get the output data point

    // test several calling of opencv boxFilter
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();

    cv::resize(img, img, cv::Size(), 1.1, 1.1); //Force data re-allocation

    cout << "BoxFilter on OpenCV 1 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    //GaussianBlur(img, imgOut, Size(31, 31), 0.5);
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();

    cv::resize(img, img, cv::Size(), 0.909, 0.909);  //Force data re-allocation

    cout << "BoxFilter on OpenCV 2 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
     start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 3 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;

    return 0;
}

程序输出:

不重新分配数据:

OpenCV 1上的BoxFilter:2.459毫秒

OpenCV 2上的BoxFilter:1.599毫秒

OpenCV 3上的BoxFilter:1.568毫秒

使用数据重新分配:

OpenCV 1上的BoxFilter:2.225毫秒

OpenCV 2上的BoxFilter:2.368毫秒

OpenCV 3上的BoxFilter:2.091毫秒

10-07 13:38