首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ -最快可能的双线性插值?

C++ -最快可能的双线性插值?
EN

Stack Overflow用户
提问于 2015-07-15 20:20:08
回答 1查看 7.2K关注 0票数 3

我想加快我的c++双线性插值代码。

设置如下:从灰度图像 img 中提取一个矩形补丁 pat ,位置为E 29E 110分段E 211<代码>E 112具有单位间距且不上下采样。E 213

由于分通常不是整数,所以我必须提前对提取的补丁进行插值。

图像img、提取的贴片拍和位置分号作为浮动存储。贴片大小为2*pad+1,衬垫为位置的左、右两部分。

当前的解决方案如下:

代码语言:javascript
复制
void function(Eigen::Matrix<float, Eigen::Dynamic, 1>* pat, 
              const float* img, 
              const Eigen::Vector2f* cent)
{

  Eigen::Vector4f we; // bilinear weight vector
  // ... [CROPPED: compute bilinear weights]

  float *pat_it = pat->data();
  for (y=cent[1]-pad; y <= cent[1]+pad; ++y)    
  {
    int postmp_a = y        * image_width;
    int postmp_b = (y-1)    * image_width;

    for (x=cent[0]-pad; x <= cent[0]+pad; ++x, ++pat_it)    
    {

          (*pat_it)     = we[0] * img[ x    +  postmp_a] +  
                          we[1] * img[x-1   +  postmp_a] +
                          we[2] * img[ x    +  postmp_b] +
                          we[3] * img[x-1   +  postmp_b]; 
    }
  }
}
  1. 有可能进一步加快速度吗?这个函数将在一个实时信号处理管道中被调用数百万次。没有内存约束.
  2. 可能有特定的本征函数吗?
  3. 由于这是我代码中最关键的瓶颈,我也愿意考虑将代码迁移到不同的编程语言/体系结构(汇编程序、CUDA等)。对此有什么想法/暗示吗?
  4. 更广泛地说,您将如何系统地处理这个问题来进行分析?

更多细节:代码是用'-Ofast -std=c++11‘编译的,并且已经使用OpenMP并行运行。图像大小为1000x1200像素,衬垫在5-10像素之间。

编辑

通过直接使用指向4个相应图像位置的指针,我已经设法提高了~6%的速度。

代码语言:javascript
复制
...
for (x=cent[0]-pad; x <= cent[0]+pad; ++x,++pat_it,
     ++img_a,++img_b,++img_c,++img_d)    
{

      (*pat_it)   = we[0] * (*img_a) +  
                    we[1] * (*img_b) +
                    we[2] * (*img_c) +
                    we[3] * (*img_d); 
}
...
EN

回答 1

Stack Overflow用户

发布于 2015-07-16 10:30:08

你可以试着让艾根简化其中的一些,比如:

代码语言:javascript
复制
void function(Eigen::VectorXf* pat, 
              const float* img, 
              const Eigen::Vector2f* cent)
{
...
  for (y=cent[1]-pad; y <= cent[1]+pad; ++y)    
  {
    ...
    Eigen::Map<Eigen::Array4f, 0, Eigen::OuterStride<>> mp(img + cent[0]-pad -1 +  postmp_b, 4, Eigen::OuterStride<>(image_width));
    for (x=cent[0]-pad; x <= cent[0]+pad; ++x, ++pat_it)    
    {
      new (&mp) Eigen::Map<Eigen::Array4f>(img + x-1 +  postmp_b, 4, Eigen::OuterStride<>(image_width));
      (*pat_it) = (mp * we.array()).sum();
...

注意:您可能必须重新排列we以匹配img元素的新顺序。

通过创建一组地图,而是创建一个大的映射,您可以尝试并做得更好:

代码语言:javascript
复制
void function(Eigen::VectorXf* pat, 
              const float* img, 
              const Eigen::Vector2f* cent)
{
  ...
  Eigen::Map<Eigen::ArrayXXf, 0, Eigen::OuterStride<>> mp(img, image_width, image_height, Eigen::OuterStride<>(image_width));
  for (y=cent[1]-pad; y <= cent[1]+pad; ++y)    
  {
    ...
    for (x=cent[0]-pad; x <= cent[0]+pad; ++x, ++pat_it)    
    {
      (*pat_it) = (mp.block<2,2>(x,y) * we.array()).sum();
...

你也许能做得更好,我还没有测试过这些。这就引出了下面的免责声明。我还没测试过这个。也就是说,你可能不得不改变InnerStrideOuterStrideimage_widthimage_height等等。

如果这对你有帮助的话,我很想知道它能带来多大的加速。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31440257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档