极慢的双线性插值(与opencv相比)

时间:2012-12-15 00:41:11

标签: c++ image algorithm opencv

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)

2 个答案:

答案 0 :(得分:3)

使OpenCV的版本更快有两件事:

  1. OpenCV将resize实现为“可分离操作”。即它分两步完成:图像水平拉伸然后垂直拉伸。这种技术允许使用较少的算术运算来调整大小。

  2. 手工编码的SSE优化。

答案 1 :(得分:0)

也许有点晚了,但也检查一下你是否在调试模式下运行你的应用程序。 OpenCV是一个库,可能会被编译用于发布 - 使用编译器优化。