如何加快图像的双线性插值?

时间:2014-03-04 12:43:18

标签: c++ performance image-processing interpolation image-rotation

我正在尝试使用插值旋转图像,但对于大图像来说它实时太慢了。

代码类似于:

for(int y=0;y<dst_h;++y)
{
    for(int x=0;x<dst_w;++x)
    {
        //do inverse transform
        fPoint pt(Transform(Point(x, y)));

        //in coor of src
        int x1= (int)floor(pt.x);
        int y1= (int)floor(pt.y);
        int x2= x1+1;
        int y2= y1+1;


        if((x1>=0&&x1<src_w&&y1>=0&&y1<src_h)&&(x2>=0&&x2<src_w&&y2>=0&&y2<src_h))
        {
                Mask[y][x]= 1; //show pixel

                float dx1= pt.x-x1;
                float dx2= 1-dx1;
                float dy1= pt.y-y1;
                float dy2= 1-dy1;

                //bilinear
                pd[x].blue= (dy2*(ps[y1*src_w+x1].blue*dx2+ps[y1*src_w+x2].blue*dx1)+
                        dy1*(ps[y2*src_w+x1].blue*dx2+ps[y2*src_w+x2].blue*dx1));
                pd[x].green= (dy2*(ps[y1*src_w+x1].green*dx2+ps[y1*src_w+x2].green*dx1)+
                        dy1*(ps[y2*src_w+x1].green*dx2+ps[y2*src_w+x2].green*dx1));
                pd[x].red= (dy2*(ps[y1*src_w+x1].red*dx2+ps[y1*src_w+x2].red*dx1)+
                        dy1*(ps[y2*src_w+x1].red*dx2+ps[y2*src_w+x2].red*dx1));

                //nearest neighbour
                //pd[x]= ps[((int)pt.y)*src_w+(int)pt.x];
        }
        else
                Mask[y][x]= 0; //transparent pixel
    }
    pd+= dst_w;
}

如何加速这段代码,我尝试并行化这段代码,但由于内存访问模式(?)似乎没有加速。

2 个答案:

答案 0 :(得分:5)

关键是要将大部分计算作为整数进行。作为浮点数唯一需要做的就是加权。有关优质资源,请参阅here

来自同一资源:

int px = (int)x; // floor of x
int py = (int)y; // floor of y
const int stride = img->width;
const Pixel* p0 = img->data + px + py * stride; // pointer to first pixel

// load the four neighboring pixels
const Pixel& p1 = p0[0 + 0 * stride];
const Pixel& p2 = p0[1 + 0 * stride];
const Pixel& p3 = p0[0 + 1 * stride];
const Pixel& p4 = p0[1 + 1 * stride];

// Calculate the weights for each pixel
float fx = x - px;
float fy = y - py;
float fx1 = 1.0f - fx;
float fy1 = 1.0f - fy;

int w1 = fx1 * fy1 * 256.0f;
int w2 = fx  * fy1 * 256.0f;
int w3 = fx1 * fy  * 256.0f;
int w4 = fx  * fy  * 256.0f;

// Calculate the weighted sum of pixels (for each color channel)
int outr = p1.r * w1 + p2.r * w2 + p3.r * w3 + p4.r * w4;
int outg = p1.g * w1 + p2.g * w2 + p3.g * w3 + p4.g * w4;
int outb = p1.b * w1 + p2.b * w2 + p3.b * w3 + p4.b * w4;
int outa = p1.a * w1 + p2.a * w2 + p3.a * w3 + p4.a * w4;

答案 1 :(得分:1)

哇你在大多数内循环中做了很多事,比如

1.float to int conversions

  • 可以对花车做所有事情......
  • 他们这些日子很快
  • 转换正在杀死你
  • 你也在混合浮子和一起(如果我看对了),这是相同的......

2.transform(X,Y)

  • 任何不必要的调用都会导致堆垃圾丢失和速度变慢
  • 而是添加2个变量xx,yy并插入它们为你的for循环

3.如果......

  • 为什么要添加if?
  • 限制循环前的范围而不是内...
  • 背景可以在之前或之后填充其他文件