Как ускорить билинейную интерполяцию изображения?

Я пытаюсь повернуть изображение с интерполяцией, но оно слишком медленное в реальном времени для больших изображений.

код что-то вроде:

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;
}

Как я могу ускорить этот код, я пытаюсь распараллелить этот код, но кажется, что нет ускорения из-за схемы доступа к памяти (?).

1

Решение

Ключ должен сделать большинство ваших вычислений в виде целых чисел. Единственное, что необходимо сделать как поплавок — это взвешивание. Увидеть Вот за хороший ресурс.

Из того же ресурса:

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;
5

Другие решения

вау, вы делаете много внутри самого внутреннего цикла, как:

1. плавать в int преобразования

  • можно все делать на поплавках …
  • они в наши дни довольно быстро
  • конверсия — это то, что убивает тебя
  • также вы смешиваете float и ints вместе (если я правильно понимаю), это то же самое …

2.transform (х, у)

  • любой ненужный вызов приводит к разрушению кучи и замедлению работы
  • вместо этого добавьте 2 переменные xx, yy и интерполируйте их в цикле for

3. если ….

  • зачем, черт возьми, ты добавляешь?
  • ограничить диапазоны перед циклом, а не внутри …
  • фон может быть заполнен другими форсами до или позже
1

По вопросам рекламы [email protected]