以下是基于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 ms
OpenCV 3上的BoxFilter: 0.403 ms
为什么第一次调用boxFilter(72.368ms)所花费的时间比第二次(0.495ms)和第三次调用<0.43ms(0.403ms)要多得多 。
更重要的是,如果我在第三次调用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。
答案 0 :(得分:3)
差异的原因是时间是由指令缓存和数据缓存引起的。可以通过强制将矩阵重新分配给不同的大小(例如,调整图像大小)来验证数据高速缓存。如果在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 ms
OpenCV 2上的BoxFilter:1.599 ms
OpenCV 3上的BoxFilter:1.568 ms
OpenCV 1上的BoxFilter:2.225 ms
OpenCV 2上的BoxFilter:2.368 ms
OpenCV 3上的BoxFilter:2.091 ms
答案 1 :(得分:1)
嗯,我认为它可能是由指令缓存引起的(毕竟,CPU中有* MB L2缓存)。但我无法弄清楚如何验证并改进它。