template<typename T>
cv::Mat_<T> const bilinear_interpolation(cv::Mat_<T> const &src, cv::Size dsize,
float dx, float dy)
{
cv::Mat_<T> dst = dsize.area() == 0 ? cv::Mat_<T>(src.rows * dy, src.cols * dx) :
cv::Mat_<T>(dsize);
float const x_ratio = static_cast<float>((src.cols - 1)) / dst.cols;
float const y_ratio = static_cast<float>((src.rows - 1)) / dst.rows;
for(int row = 0; row != dst.rows; ++row)
{
int y = static_cast<int>(row * y_ratio);
float const y_diff = (row * y_ratio) - y; //distance of the nearest pixel(y axis)
float const y_diff_2 = 1 - y_diff;
auto *dst_ptr = &dst(row, 0)[0];
for(int col = 0; col != dst.cols; ++col)
{
int x = static_cast<int>(col * x_ratio);
float const x_diff = (col * x_ratio) - x; //distance of the nearet pixel(x axis)
float const x_diff_2 = 1 - x_diff;
float const y2_cross_x2 = y_diff_2 * x_diff_2;
float const y2_cross_x = y_diff_2 * x_diff;
float const y_cross_x2 = y_diff * x_diff_2;
float const y_cross_x = y_diff * x_diff;
for(int channel = 0; channel != cv::DataType<T>::channels; ++channel)
{
*dst_ptr++ = y2_cross_x2 * src(y, x)[channel] +
y2_cross_x * src(y, x + 1)[channel] +
y_cross_x2 * src(y + 1, x)[channel] +
y_cross_x * src(y + 1, x + 1)[channel];
}
}
}
return dst;
}
这是双线性插值的实现,我用它来放大512 * 512图像(“lena.png”) 到2048 * 2048,完成这项工作需要0.195秒,但opencv的cv :: resize(不是gpu版本)只花费0.026秒。我不知道是什么让我的双线性变得如此慢(opencv比我快近750%),我想看看opencv调整大小的源代码,但我找不到它的实现。
您是否知道为什么openCV的调整速度如此之快或者我的双线性太慢?
{
timeEstimate<> time;
cv::Mat_<cv::Vec3b> const src = input;
bilinear_interpolation(src, cv::Size(), dx, dy);
std::cout << "bilinear" << std::endl;
}
{
timeEstimate<> time;
cv::Mat output = input.clone();
cv::resize(input, output, cv::Size(), dx, dy, cv::INTER_LINEAR);
std::cout << "bilinear cv" << std::endl;
}
编译器:mingw4.6.2 os:win7 64bits cpu:英特尔®i3-2330M(2.2G)
答案 0 :(得分:3)
使OpenCV的版本更快有两件事:
OpenCV将resize实现为“可分离操作”。即它分两步完成:图像水平拉伸然后垂直拉伸。这种技术允许使用较少的算术运算来调整大小。
手工编码的SSE优化。
答案 1 :(得分:0)
也许有点晚了,但也检查一下你是否在调试模式下运行你的应用程序。 OpenCV是一个库,可能会被编译用于发布 - 使用编译器优化。