# Upsample bicubic interpolation

Hi

I implemented Upsample bicubic baseline code with my custom input as same as how its implemented in API code…

But i am getting wrong results…please help me here…

I attached my code below

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))

static const int64_t kTableSize = (1 << 10);
const float* coeffs_tab;
//printf(“%d”,kTableSize);

float* InitCoeffsTable() {
// Allocate and initialize coefficients table using Bicubic
// convolution algorithm.
// Bicubic interpolation - Wikipedia
//float* coeffs_tab = (float*)malloc(sizeof(float) * (kTableSize + 1) * 2);
float* coeffs_tab = (float*)malloc((kTableSize + 1) * 2 * sizeof(float));
static const double A = -0.75;
for (int i = 0; i <= kTableSize; ++i) {
float x = i * 1.0 / kTableSize;
coeffs_tab[i * 2] = ((A + 2) * x - (A + 3)) * x * x + 1;
x += 1.0;
coeffs_tab[i * 2 + 1] = ((A * x - 5 * A) * x + 8 * A) * x - 4 * A;
}
return coeffs_tab;
}

float* GetCoeffsTable() {
// Static so that we initialize it on first use
float* coeffs_tab = InitCoeffsTable();
return coeffs_tab;
}

// Used in the baseline implementation
int64_t Bound(int64_t val, int64_t limit) {
return min(limit - 1, max(0, val));
//return (val < 0) ? 0 : ( val >= limit) ? limit - 1 : val;
}

// Used in the baseline implementation
void GetWeightsAndIndices(float scale, int64_t out_loc, int64_t limit,
float *weights, int64_t indices) {
int64_t in_loc = scale * out_loc;
float delta = scale * out_loc - in_loc;
int64_t offset = lrintf(delta * kTableSize);
float
coeffs_tab = GetCoeffsTable();
weights[0] = coeffs_tab[offset * 2 + 1];
weights[1] = coeffs_tab[offset * 2];
weights[2] = coeffs_tab[(kTableSize - offset) * 2];
weights[3] = coeffs_tab[(kTableSize - offset) * 2 + 1];
indices[0] = Bound(in_loc - 1, limit);
indices[1] = Bound(in_loc, limit);
indices[2] = Bound(in_loc + 1, limit);
indices[3] = Bound(in_loc + 2, limit);
}

// Used in the baseline implementation
float Interpolate1D(float weights[4], float values[4]) {
return values[0] * weights[0] + values[1] * weights[1] +
values[2] * weights[2] + values[3] * weights[3];
}

void ResizeBicubicBaseline(float* images, float* output,
int batch_size, int in_height, int in_width,
int channels, int out_height, int out_width){
const float height_scale = in_height / (float)out_height;
const float width_scale = in_width / (float)out_width;

float coeff[4] = {0.0f, 0.0f, 0.0f, 0.0f};
for (int b = 0; b < batch_size; ++b) {
for (int y = 0; y < out_height; ++y) {
float y_weights[4];
int64_t y_indices[4];
GetWeightsAndIndices(height_scale, y, in_height, y_weights,
y_indices);
int g = 0;
printf(“%d\n”,y_indices[g]);
printf(“\n------------------------------------\n”);
printf(“%f\n”,y_weights[g]);
for (int x = 0; x < out_width; ++x) {
float x_weights[4];
int64_t x_indices[4];
GetWeightsAndIndices(width_scale, x, in_width, x_weights,
x_indices);
for (int c = 0; c < channels; ++c) {
// Use a 4x4 patch to compute the interpolated output value at
// (b, y, x, c).
for (int i = 0; i < 4; ++i) {
float values[4] = {
images[((b * in_height + y_indices[i]) * in_width + x_indices[0]) * channels + c],
images[((b * in_height + y_indices[i]) * in_width + x_indices[1]) * channels + c],
images[((b * in_height + y_indices[i]) * in_width + x_indices[2]) * channels + c],
images[((b * in_height + y_indices[i]) * in_width + x_indices[3]) * channels + c]
};
coeff[i] = Interpolate1D(x_weights, values);
}
output[((b * out_height + y) * out_width + x) * channels + c] =
Interpolate1D(y_weights, coeff);
}
}
}
}
}

int main() {
// Create input tensor
float images[] = {1.0, 2.0, 3.0,4.0};
// Create output tensor
float output[16];

// Call resize function
ResizeBicubicBaseline(images, output,1,2,2,1,4,4);
int batch = 1;
int out_height = 4;
int out_width = 4;
int channels = 1;

printf(“\n---------------------------------------------OUTPUT---------------------------------------\n”);
// Print output tensor
for (int b = 0; b < batch; ++b) {
for (int i = 0; i < out_height; ++i) {
for (int j = 0; j < out_width; ++j) {
for (int c = 0; c < channels; ++c) {
const int index = ((b * out_height + i) * out_width + j) * channels + c;
printf(“%f “, output[index]);
}
printf(”\n”);
}
printf(“\n”);
}
}
}

expected results:

0.7352942 1.0306723 1.6163868 1.9117651 1.3260506 1.6214286 2.2071428
2.502521 2.4974794 2.7928574 3.3785717 3.67395 3.0882356 3.3836138
3.9693282 4.2647066

actual results i am getting:

1.000000
1.500000
2.000000
2.093750

2.000000
2.500000
3.000000
3.093750

3.000000
3.500000
4.000000
4.093750

3.187500
3.687500
4.187500
4.281250

Thanks for the kind help…