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.026secs。我不知道是什麼讓我的雙線變得如此緩慢(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 操作系統:WIN7 64位CPU :英特爾I3-2330M(2.2G)
例如,'cv :: resize'有可能利用處理器指令集擴展,如SSE,允許它並行運行多個乘法。要做到這一點,你需要智能編譯器優化或手動編寫x86程序集。 **編輯:** [根據消息來源,GCC使用'-O3'標誌實現了矢量化。](http://stackoverflow.com/questions/7919304/gcc-sse-code-optimization)。 (但是,'-O3'可能會導致令人難以置信的奇怪錯誤,所以一般不會使用它。) – 2012-12-15 00:47:52
謝謝,我最近會看看opencl,希望gpgpu開發的代碼更加便攜。 – StereoMatching
通過考慮具體情況的具體實現,您可以開始加速它,比方說每個通道具有8位深度的典型RGB整數圖像。然後可以用更少的乘法和更多的按位操作來執行內插。雖然我沒有一個符合評論的實現,但你可以在http://cboard.cprogramming.com/game-programming/19926-super-fast-bilinear-interpolation.html找到一個,我沒有檢查正確性。 – mmgp