void apply_general_transformation(float *input, float *transformx, float* transformy, float *out, float bg, int order, int width, int height, int nwidth,int nheight) { float *coeffs; float *ref; float cx[12],cy[12],ak[13]; if (order!=0 && order!=1 && order!=-3 && order!=3 && order!=5 && order!=7 && order!=9 && order!=11) { printf("unrecognized interpolation order.\n"); exit(-1); } if (order>=3) { coeffs = new float[width*height]; finvspline(input,order,coeffs,width,height); ref = coeffs; if (order>3) init_splinen(ak,order); } else { coeffs = NULL; ref = input; } int xi,yi; float xp,yp; float res; int n1,n2; float p=-0.5; for(int i=0; i < nwidth; i++) for(int j=0; j < nheight; j++) { xp = (float) transformx[j*nwidth+i]; yp = (float) transformy[j*nwidth+i]; if (order == 0) { xi = (int)floor((double)xp); yi = (int)floor((double)yp); if (xi<0 || xi>=width || yi<0 || yi>=height) res = bg; else res = input[yi*width+xi]; } else { if (xp<0. || xp>(float)width || yp<0. || yp>(float)height) res=bg; else { //xp -= 0.5; yp -= 0.5; int xi = (int)floor((double)xp); int yi = (int)floor((double)yp); float ux = xp-(float)xi; float uy = yp-(float)yi; switch (order) { case 1: /* first order interpolation (bilinear) */ n2 = 1; cx[0]=ux; cx[1]=1.f-ux; cy[0]=uy; cy[1]=1.f-uy; break; case -3: /* third order interpolation (bicubic Keys' function) */ n2 = 2; keys(cx,ux,p); keys(cy,uy,p); break; case 3: /* spline of order 3 */ n2 = 2; spline3(cx,ux); spline3(cy,uy); break; default: /* spline of order >3 */ n2 = (1+order)/2; splinen(cx,ux,ak,order); splinen(cy,uy,ak,order); break; } res = 0.; n1 = 1-n2; if (xi+n1>=0 && xi+n2<width && yi+n1>=0 && yi+n2<height) { int adr = yi*width+xi; for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) res += cy[n2-dy]*cx[n2-dx]*ref[adr+width*dy+dx]; } else for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) res += cy[n2-dy]*cx[n2-dx]*v(ref,xi+dx,yi+dy,bg,width,height); } } out[j*nwidth+i] = res; } }
// Spline interpolation of given order of image im at point (x,y). // out must be an array of size the number of components. // Supported orders: 0(nn), 1(bilinear), -3(Keys's bicubic), 3, 5, 7, 9, 11. // Success means a valid order and pixel in image. bool evaluate_spline_at(float *out, float *img, int w, int h, int pd, int order, float x, float y) { float cx[12],cy[12]; /* CHECK ORDER */ if (order != 0 && order != 1 && order != -3 && order != 3 && order != 5 && order != 7 && order != 9 && order != 11) return false; float ak[13]; if (order > 3) init_splinen(ak, order); /* INTERPOLATION */ if(order == 0) { /* zero order interpolation (pixel replication) */ int xi = x; int yi = y; if (!insideP(w, h, xi, yi)) return false; float* p = img + (w*yi+xi) * pd; for(int i = 0; i < pd; i++) out[i] = p[i]; } else { /* higher order interpolations */ if (!(x>=0 && x<=w && y>=0 && y<=h)) return false; x -= 0.5; y -= 0.5; int xi = (x<0)? -1: x; int yi = (y<0)? -1: y; float ux = x - xi; float uy = y - yi; float paramKeys = -0.5; switch(order) { case 1: /* first order interpolation (bilinear) */ cx[0] = ux; cx[1] = 1-ux; cy[0] = uy; cy[1] = 1-uy; break; case -3: /* third order interpolation (bicubic Keys) */ keys(cx, ux, paramKeys); keys(cy, uy, paramKeys); break; case 3: /* spline of order 3 */ spline3(cx, ux); spline3(cy, uy); break; default: /* spline of order >3 */ splinen(cx, ux, ak, order); splinen(cy, uy, ak, order); break; } int n2 = (order == -3) ? 2 : (order+1)/2; int n1 = 1 - n2; /* this test saves computation time */ if (insideP(w, h, xi+n1, yi+n1) && insideP(w, h, xi+n1, yi+n2)) { for (int k = 0; k < pd; k++) { out[k] = 0; for (int dy = n1; dy <= n2; dy++) { int ii = xi + n1; int jj = yi + dy; float* v = img + (jj*w+ii)*pd+k; for (int dx = n1; dx <= n2; dx++) { float f = *v; out[k]+=cy[n2-dy]*cx[n2-dx] * f; v += pd; } } } } else for (int k = 0; k < pd; k++) { out[k] = 0; for (int dy = n1; dy <= n2; dy++) for (int dx = n1; dx <= n2; dx++) { int ii = xi + dx; int jj = yi + dy; getsample_t S = getsample_2; float v = S(img, w, h, pd, ii, jj, k); out[k] += cy[n2-dy] * cx[n2-dx] * v; } } } return true; }
void apply_planar_homography(float *input, int width, int height, float **H, float bg, int order, float *out, float x0, float y0, int nwidth, int nheight) { if (DEBUG) printf("width: %d height: %d ------> nwidth: %d nheight: %d \n", width, height, nwidth, nheight); /// We compute inverse transformation if (DEBUG) { printf("Matrix: \n"); print_float_matrix(H,3,3); } float **V = allocate_float_matrix(3,3); luinv(H, V, 3); if (DEBUG) { printf("Inverse Matrix: \n"); print_float_matrix(V,3,3); } float *coeffs; float *ref; float cx[12],cy[12],ak[13]; if (order!=0 && order!=1 && order!=-3 && order!=3 && order!=5 && order!=7 && order!=9 && order!=11) { printf("unrecognized interpolation order.\n"); exit(-1); } if (order>=3) { coeffs = new float[width*height]; finvspline(input,order,coeffs,width,height); ref = coeffs; if (order>3) init_splinen(ak,order); } else { coeffs = NULL; ref = input; } int xi,yi; float xp,yp; float res; int n1,n2; float p=-0.5; /// For each point in new image we compute its anti image and interpolate the new value for(int i=0; i < nwidth; i++) for(int j=0; j < nheight; j++) { float vec[3]; vec[0] = (float) i + x0; vec[1] = (float) j + y0; vec[2] = 1.0f; float vres[3]; float_vector_matrix_product(V, vec ,vres , 3); if (vres[2] != 0.0f) { vres[0] /= vres[2]; vres[1] /= vres[2]; xp = (float) vres[0]; yp = (float) vres[1]; if (order == 0) { xi = (int)floor((double)xp); yi = (int)floor((double)yp); if (xi<0 || xi>=width || yi<0 || yi>=height) res = bg; else res = input[yi*width+xi]; } else { if (xp<0. || xp>=(float)width || yp<0. || yp>=(float)height) res=bg; else { //xp -= 0.5; yp -= 0.5; int xi = (int)floor((double)xp); int yi = (int)floor((double)yp); float ux = xp-(float)xi; float uy = yp-(float)yi; switch (order) { case 1: /* first order interpolation (bilinear) */ n2 = 1; cx[0]=ux; cx[1]=1.f-ux; cy[0]=uy; cy[1]=1.f-uy; break; case -3: /* third order interpolation (bicubic Keys' function) */ n2 = 2; keys(cx,ux,p); keys(cy,uy,p); break; case 3: /* spline of order 3 */ n2 = 2; spline3(cx,ux); spline3(cy,uy); break; default: /* spline of order >3 */ n2 = (1+order)/2; splinen(cx,ux,ak,order); splinen(cy,uy,ak,order); break; } res = 0.; n1 = 1-n2; if (xi+n1>=0 && xi+n2<width && yi+n1>=0 && yi+n2<height) { int adr = yi*width+xi; for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) res += cy[n2-dy]*cx[n2-dx]*ref[adr+width*dy+dx]; } else for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) res += cy[n2-dy]*cx[n2-dx]*v(ref,xi+dx,yi+dy,bg,width,height); } } out[j*nwidth+i] = res; } } }
void apply_zoom(float *input, float *out, float zoom, int order, int width, int height) { int nwidth = (int)( zoom * (float) width); int nheight = (int)( zoom * (float) height); float *coeffs; float *ref; float cx[12],cy[12],ak[13]; // Guoshen Yu, 2010.09.22, Windows versions vector<float> input_vec, coeffs_vec, ref_vec; input_vec = vector<float>(width*height); coeffs_vec = vector<float>(width*height); ref_vec = vector<float>(width*height); for (int i = 0; i < width*height; i++) input_vec[i] = input[i]; if (order!=0 && order!=1 && order!=-3 && order!=3 && order!=5 && order!=7 && order!=9 && order!=11) { printf("unrecognized interpolation order.\n"); exit(-1); } if (order>=3) { coeffs = new float[width*height]; // Guoshen Yu, 2010.09.21, Windows version //finvspline(input,order,coeffs,width,height); finvspline(input_vec,order,coeffs_vec,width,height); for (int i = 0; i < width*height; i++) coeffs[i] = coeffs_vec[i]; ref = coeffs; if (order>3) init_splinen(ak,order); } else { coeffs = NULL; ref = input; } int xi,yi; float xp,yp; float res; int n1,n2; float bg = 0.0f; float p=-0.5; for(int i=0; i < nwidth; i++) for(int j=0; j < nheight; j++) { xp = (float) i / zoom; yp = (float) j / zoom; if (order == 0) { xi = (int)floor((double)xp); yi = (int)floor((double)yp); if (xi<0 || xi>=width || yi<0 || yi>=height) res = bg; else res = input[yi*width+xi]; } else { if (xp<0. || xp>=(float)width || yp<0. || yp>=(float)height) res=bg; else { xp -= 0.5; yp -= 0.5; int xi = (int)floor((double)xp); int yi = (int)floor((double)yp); float ux = xp-(float)xi; float uy = yp-(float)yi; switch (order) { case 1: /* first order interpolation (bilinear) */ n2 = 1; cx[0]=ux; cx[1]=1.-ux; cy[0]=uy; cy[1]=1.-uy; break; case -3: /* third order interpolation (bicubic Keys' function) */ n2 = 2; keys(cx,ux,p); keys(cy,uy,p); break; case 3: /* spline of order 3 */ n2 = 2; spline3(cx,ux); spline3(cy,uy); break; default: /* spline of order >3 */ n2 = (1+order)/2; splinen(cx,ux,ak,order); splinen(cy,uy,ak,order); break; } res = 0.; n1 = 1-n2; if (xi+n1>=0 && xi+n2<width && yi+n1>=0 && yi+n2<height) { int adr = yi*width+xi; for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) res += cy[n2-dy]*cx[n2-dx]*ref[adr+width*dy+dx]; } else // Guoshen Yu, 2010.09.21, Windows for (int i = 0; i < width*height; i++) ref_vec[i] = ref[i]; for (int dy=n1;dy<=n2;dy++) for (int dx=n1;dx<=n2;dx++) // Guoshen Yu, 2010.09.21, Windows // res += cy[n2-dy]*cx[n2-dx]*v(ref,xi+dx,yi+dy,bg,width,height); res += cy[n2-dy]*cx[n2-dx]*v(ref_vec,xi+dx,yi+dy,bg,width,height); } } out[j*nwidth+i] = res; } }