这是我基于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毫秒