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