|
|
|
@@ -110,8 +110,8 @@ static void resize_bilinear_image(const Mat& src, Mat& dst) |
|
|
|
} |
|
|
|
|
|
|
|
// loop body |
|
|
|
Mat rowsbuf0(w + 1); |
|
|
|
Mat rowsbuf1(w + 1); |
|
|
|
Mat rowsbuf0(w); |
|
|
|
Mat rowsbuf1(w); |
|
|
|
float* rows0 = rowsbuf0; |
|
|
|
float* rows1 = rowsbuf1; |
|
|
|
|
|
|
|
@@ -192,6 +192,302 @@ static void resize_bilinear_image(const Mat& src, Mat& dst) |
|
|
|
delete[] buf; |
|
|
|
} |
|
|
|
|
|
|
|
static inline void interpolate_cubic(float fx, float* coeffs) |
|
|
|
{ |
|
|
|
const float A = -0.75f; |
|
|
|
|
|
|
|
float fx0 = fx + 1; |
|
|
|
float fx1 = fx; |
|
|
|
float fx2 = 1 - fx; |
|
|
|
// float fx3 = 2 - fx; |
|
|
|
|
|
|
|
coeffs[0] = A * fx0*fx0*fx0 - 5*A * fx0*fx0 + 8*A * fx0 - 4*A; |
|
|
|
coeffs[1] = (A+2) * fx1*fx1*fx1 - (A+3) * fx1*fx1 + 1; |
|
|
|
coeffs[2] = (A+2) * fx2*fx2*fx2 - (A+3) * fx2*fx2 + 1; |
|
|
|
coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2]; |
|
|
|
} |
|
|
|
|
|
|
|
static void resize_bicubic_image(const Mat& src, Mat& dst) |
|
|
|
{ |
|
|
|
int w = dst.w; |
|
|
|
int h = dst.w; |
|
|
|
|
|
|
|
double scale_x = (double)src.w / w; |
|
|
|
double scale_y = (double)src.h / h; |
|
|
|
|
|
|
|
int* buf = new int[w + h + w*4 + h*4]; |
|
|
|
|
|
|
|
int* xofs = buf;//new int[w]; |
|
|
|
int* yofs = buf + w;//new int[h]; |
|
|
|
|
|
|
|
float* alpha = (float*)(buf + w + h);//new float[w * 4]; |
|
|
|
float* beta = (float*)(buf + w + h + w*4);//new float[h * 4]; |
|
|
|
|
|
|
|
float fx; |
|
|
|
float fy; |
|
|
|
int sx; |
|
|
|
int sy; |
|
|
|
|
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
fx = (float)((dx + 0.5) * scale_x - 0.5); |
|
|
|
sx = floor(fx); |
|
|
|
fx -= sx; |
|
|
|
|
|
|
|
interpolate_cubic(fx, alpha + dx*4); |
|
|
|
|
|
|
|
if (sx <= -1) |
|
|
|
{ |
|
|
|
sx = 1; |
|
|
|
alpha[dx*4 +0] = alpha[dx*4 +0] + alpha[dx*4 +1] + alpha[dx*4 +2]; |
|
|
|
alpha[dx*4 +1] = alpha[dx*4 +3]; |
|
|
|
alpha[dx*4 +2] = 0.f; |
|
|
|
alpha[dx*4 +3] = 0.f; |
|
|
|
} |
|
|
|
if (sx == 0) |
|
|
|
{ |
|
|
|
sx = 1; |
|
|
|
alpha[dx*4 +0] = alpha[dx*4 +0] + alpha[dx*4 +1]; |
|
|
|
alpha[dx*4 +1] = alpha[dx*4 +2]; |
|
|
|
alpha[dx*4 +2] = alpha[dx*4 +3]; |
|
|
|
alpha[dx*4 +3] = 0.f; |
|
|
|
} |
|
|
|
if (sx == src.w - 2) |
|
|
|
{ |
|
|
|
sx = src.w - 3; |
|
|
|
alpha[dx*4 +3] = alpha[dx*4 +2] + alpha[dx*4 +3]; |
|
|
|
alpha[dx*4 +2] = alpha[dx*4 +1]; |
|
|
|
alpha[dx*4 +1] = alpha[dx*4 +0]; |
|
|
|
alpha[dx*4 +0] = 0.f; |
|
|
|
} |
|
|
|
if (sx >= src.w - 1) |
|
|
|
{ |
|
|
|
sx = src.w - 3; |
|
|
|
alpha[dx*4 +3] = 1.f - alpha[dx*4 +0]; |
|
|
|
alpha[dx*4 +2] = alpha[dx*4 +0]; |
|
|
|
alpha[dx*4 +1] = 0.f; |
|
|
|
alpha[dx*4 +0] = 0.f; |
|
|
|
} |
|
|
|
|
|
|
|
xofs[dx] = sx; |
|
|
|
} |
|
|
|
|
|
|
|
for (int dy = 0; dy < h; dy++) |
|
|
|
{ |
|
|
|
fy = (float)((dy + 0.5) * scale_y - 0.5); |
|
|
|
sy = floor(fy); |
|
|
|
fy -= sy; |
|
|
|
|
|
|
|
interpolate_cubic(fy, beta + dy*4); |
|
|
|
|
|
|
|
if (sy <= -1) |
|
|
|
{ |
|
|
|
sy = 1; |
|
|
|
beta[dy*4 +0] = beta[dy*4 +0] + beta[dy*4 +1] + beta[dy*4 +2]; |
|
|
|
beta[dy*4 +1] = beta[dy*4 +3]; |
|
|
|
beta[dy*4 +2] = 0.f; |
|
|
|
beta[dy*4 +3] = 0.f; |
|
|
|
} |
|
|
|
if (sy == 0) |
|
|
|
{ |
|
|
|
sy = 1; |
|
|
|
beta[dy*4 +0] = beta[dy*4 +0] + beta[dy*4 +1]; |
|
|
|
beta[dy*4 +1] = beta[dy*4 +2]; |
|
|
|
beta[dy*4 +2] = beta[dy*4 +3]; |
|
|
|
beta[dy*4 +3] = 0.f; |
|
|
|
} |
|
|
|
if (sy == src.h - 2) |
|
|
|
{ |
|
|
|
sy = src.h - 3; |
|
|
|
beta[dy*4 +3] = beta[dy*4 +2] + beta[dy*4 +3]; |
|
|
|
beta[dy*4 +2] = beta[dy*4 +1]; |
|
|
|
beta[dy*4 +1] = beta[dy*4 +0]; |
|
|
|
beta[dy*4 +0] = 0.f; |
|
|
|
} |
|
|
|
if (sy >= src.h - 1) |
|
|
|
{ |
|
|
|
sy = src.h - 3; |
|
|
|
beta[dy*4 +3] = 1.f - beta[dy*4 +0]; |
|
|
|
beta[dy*4 +2] = beta[dy*4 +0]; |
|
|
|
beta[dy*4 +1] = 0.f; |
|
|
|
beta[dy*4 +0] = 0.f; |
|
|
|
} |
|
|
|
|
|
|
|
yofs[dy] = sy; |
|
|
|
} |
|
|
|
|
|
|
|
// loop body |
|
|
|
Mat rowsbuf0(w); |
|
|
|
Mat rowsbuf1(w); |
|
|
|
Mat rowsbuf2(w); |
|
|
|
Mat rowsbuf3(w); |
|
|
|
float* rows0 = rowsbuf0; |
|
|
|
float* rows1 = rowsbuf1; |
|
|
|
float* rows2 = rowsbuf2; |
|
|
|
float* rows3 = rowsbuf3; |
|
|
|
|
|
|
|
int prev_sy1 = -3; |
|
|
|
|
|
|
|
for (int dy = 0; dy < h; dy++ ) |
|
|
|
{ |
|
|
|
int sy = yofs[dy]; |
|
|
|
|
|
|
|
if (sy == prev_sy1) |
|
|
|
{ |
|
|
|
// reuse all rows |
|
|
|
} |
|
|
|
else if (sy == prev_sy1 + 1) |
|
|
|
{ |
|
|
|
// hresize one row |
|
|
|
float* rows0_old = rows0; |
|
|
|
rows0 = rows1; |
|
|
|
rows1 = rows2; |
|
|
|
rows2 = rows3; |
|
|
|
rows3 = rows0_old; |
|
|
|
const float* S3 = src.row(sy+2); |
|
|
|
|
|
|
|
const float* alphap = alpha; |
|
|
|
float* rows3p = rows3; |
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
int sx = xofs[dx]; |
|
|
|
const float* S3p = S3 + sx; |
|
|
|
|
|
|
|
float a0 = alphap[0]; |
|
|
|
float a1 = alphap[1]; |
|
|
|
float a2 = alphap[2]; |
|
|
|
float a3 = alphap[3]; |
|
|
|
rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3; |
|
|
|
|
|
|
|
alphap += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (sy == prev_sy1 + 2) |
|
|
|
{ |
|
|
|
// hresize two rows |
|
|
|
float* rows0_old = rows0; |
|
|
|
float* rows1_old = rows1; |
|
|
|
rows0 = rows2; |
|
|
|
rows1 = rows3; |
|
|
|
rows2 = rows0_old; |
|
|
|
rows3 = rows1_old; |
|
|
|
const float* S2 = src.row(sy+1); |
|
|
|
const float* S3 = src.row(sy+2); |
|
|
|
|
|
|
|
const float* alphap = alpha; |
|
|
|
float* rows2p = rows2; |
|
|
|
float* rows3p = rows3; |
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
int sx = xofs[dx]; |
|
|
|
const float* S2p = S2 + sx; |
|
|
|
const float* S3p = S3 + sx; |
|
|
|
|
|
|
|
float a0 = alphap[0]; |
|
|
|
float a1 = alphap[1]; |
|
|
|
float a2 = alphap[2]; |
|
|
|
float a3 = alphap[3]; |
|
|
|
rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3; |
|
|
|
rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3; |
|
|
|
|
|
|
|
alphap += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (sy == prev_sy1 + 3) |
|
|
|
{ |
|
|
|
// hresize three rows |
|
|
|
float* rows0_old = rows0; |
|
|
|
float* rows1_old = rows1; |
|
|
|
float* rows2_old = rows2; |
|
|
|
rows0 = rows3; |
|
|
|
rows1 = rows0_old; |
|
|
|
rows2 = rows1_old; |
|
|
|
rows3 = rows2_old; |
|
|
|
const float* S1 = src.row(sy); |
|
|
|
const float* S2 = src.row(sy+1); |
|
|
|
const float* S3 = src.row(sy+2); |
|
|
|
|
|
|
|
const float* alphap = alpha; |
|
|
|
float* rows1p = rows1; |
|
|
|
float* rows2p = rows2; |
|
|
|
float* rows3p = rows3; |
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
int sx = xofs[dx]; |
|
|
|
const float* S1p = S1 + sx; |
|
|
|
const float* S2p = S2 + sx; |
|
|
|
const float* S3p = S3 + sx; |
|
|
|
|
|
|
|
float a0 = alphap[0]; |
|
|
|
float a1 = alphap[1]; |
|
|
|
float a2 = alphap[2]; |
|
|
|
float a3 = alphap[3]; |
|
|
|
rows1p[dx] = S1p[-1]*a0 + S1p[0]*a1 + S1p[1]*a2 + S1p[2]*a3; |
|
|
|
rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3; |
|
|
|
rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3; |
|
|
|
|
|
|
|
alphap += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// hresize four rows |
|
|
|
const float* S0 = src.row(sy-1); |
|
|
|
const float* S1 = src.row(sy); |
|
|
|
const float* S2 = src.row(sy+1); |
|
|
|
const float* S3 = src.row(sy+2); |
|
|
|
|
|
|
|
const float* alphap = alpha; |
|
|
|
float* rows0p = rows0; |
|
|
|
float* rows1p = rows1; |
|
|
|
float* rows2p = rows2; |
|
|
|
float* rows3p = rows3; |
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
int sx = xofs[dx]; |
|
|
|
const float* S0p = S0 + sx; |
|
|
|
const float* S1p = S1 + sx; |
|
|
|
const float* S2p = S2 + sx; |
|
|
|
const float* S3p = S3 + sx; |
|
|
|
|
|
|
|
float a0 = alphap[0]; |
|
|
|
float a1 = alphap[1]; |
|
|
|
float a2 = alphap[2]; |
|
|
|
float a3 = alphap[3]; |
|
|
|
rows0p[dx] = S0p[-1]*a0 + S0p[0]*a1 + S0p[1]*a2 + S0p[2]*a3; |
|
|
|
rows1p[dx] = S1p[-1]*a0 + S1p[0]*a1 + S1p[1]*a2 + S1p[2]*a3; |
|
|
|
rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3; |
|
|
|
rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3; |
|
|
|
|
|
|
|
alphap += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
prev_sy1 = sy; |
|
|
|
|
|
|
|
// vresize |
|
|
|
float b0 = beta[0]; |
|
|
|
float b1 = beta[1]; |
|
|
|
float b2 = beta[2]; |
|
|
|
float b3 = beta[3]; |
|
|
|
|
|
|
|
float* rows0p = rows0; |
|
|
|
float* rows1p = rows1; |
|
|
|
float* rows2p = rows2; |
|
|
|
float* rows3p = rows3; |
|
|
|
float* Dp = dst.row(dy); |
|
|
|
for (int dx = 0; dx < w; dx++) |
|
|
|
{ |
|
|
|
// D[x] = rows0[x]*b0 + rows1[x]*b1 + rows2[x]*b2 + rows3[x]*b3; |
|
|
|
*Dp++ = *rows0p++ * b0 + *rows1p++ * b1 + *rows2p++ * b2 + *rows3p++ * b3; |
|
|
|
} |
|
|
|
|
|
|
|
beta += 4; |
|
|
|
} |
|
|
|
|
|
|
|
delete[] buf; |
|
|
|
} |
|
|
|
|
|
|
|
int Interp::forward(const Mat &bottom_blob, Mat &top_blob, const Option& opt) const |
|
|
|
{ |
|
|
|
int h = bottom_blob.h; |
|
|
|
@@ -233,7 +529,7 @@ int Interp::forward(const Mat &bottom_blob, Mat &top_blob, const Option& opt) co |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
if (resize_type == 1)//nearest |
|
|
|
if (resize_type == 1)// nearest |
|
|
|
{ |
|
|
|
#pragma omp parallel for num_threads(opt.num_threads) |
|
|
|
for (int q = 0; q < c; ++q) |
|
|
|
@@ -266,6 +562,19 @@ int Interp::forward(const Mat &bottom_blob, Mat &top_blob, const Option& opt) co |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
else if (resize_type == 3)// bicubic |
|
|
|
{ |
|
|
|
#pragma omp parallel for num_threads(opt.num_threads) |
|
|
|
for (int q = 0; q < c; ++q) |
|
|
|
{ |
|
|
|
const Mat src = bottom_blob.channel(q); |
|
|
|
Mat dst = top_blob.channel(q); |
|
|
|
|
|
|
|
resize_bicubic_image(src, dst); |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fprintf(stderr, "unsupported resize type %d %d %d\n", resize_type, oh, ow); |
|
|
|
|