//get the image by homography for a destination pixel x, y
float destination_pixel(float inv[9], float *im, int w, int h, int x, int y)
{
    float p[3] = {x, y, 1};
    float p1[3];
    p1[0] = p[0]*inv[0] + p[1]*inv[1] + p[2]*inv[2];
    p1[1] = p[0]*inv[3] + p[1]*inv[4] + p[2]*inv[5];
    p1[2] = p[0]*inv[6] + p[1]*inv[7] + p[2]*inv[8];
    
    return bicubic_interpolation(im, w, h, p1[0]/p1[2], p1[1]/p1[2]);
}
void apply_transformation(float *im, float *Tx, float *Ty, int w, int h, float *out)
{
    for(int i = 0 ; i < w ; i++)
        for(int j = 0 ; j < h ; j++)
        {
            float dx = Tx[j*w+i];
            float dy = Ty[j*w+i];
            out[j*w+i] = bicubic_interpolation(im, w, h, dx, dy);
        }
    
}
Пример #3
0
void mnehs_affine_warp(float *warp,
		float *h, int wh, int hh, int pd,
		float *a, int wa, int ha,
		float *b, int wb, int hb,
		double PA[8], double PB[8])
{
	for (int j = 0; j < hh; j++)
	for (int i = 0; i < wh; i++)
	{
		float vh = getsample_nan(h, wh, hh, 1, i, j, 0);
		double ijh[3] = {i, j, vh};
		double paijh[3], pbijh[3];
		apply_projection(paijh, PA, ijh);
		apply_projection(pbijh, PB, ijh);
		float va[pd], vb[pd];
		bicubic_interpolation(va, a, wa, ha, pd, paijh[0], paijh[1]);
		bicubic_interpolation(vb, b, wb, hb, pd, pbijh[0], pbijh[1]);
		for (int l = 0; l < pd; l++)
			warp[pd*(j*wh+i)+l] = va[l] - vb[l];
	}
}
Пример #4
0
// y := pull back of image x by vector field f
static void field_pull_back(float *y, float *f, float *x, int w, int h, int pd)
{
	float (*flow)[w][2] = (void*)f;
	float (*out)[w][pd] = (void*)y;

	for (int j = 0; j < h; j++)
	for (int i = 0; i < w; i++)
	{
		float p[2] = {i + flow[j][i][0], j + flow[j][i][1]};
		bicubic_interpolation(out[j][i], x, w, h, pd, p[0], p[1]);
	}
}
Пример #5
0
// v(x) := -u(x+v(x))
static void inversion_iteration(float *v, float *u, int w, int h)
{
	float (*V)[w][2] = (void*)v;

	for (int j = 0; j < h; j++)
	for (int i = 0; i < w; i++)
	{
		float p[2];
		float qx = i + V[j][i][0];
		float qy = j + V[j][i][1];
		bicubic_interpolation(p, u, w, h, 2, qx, qy);
		V[j][i][0] = -p[0];
		V[j][i][1] = -p[1];
	}
}
Пример #6
0
// interpolate an image at a given sub-pixelic point
static void general_interpolate(float *result,
		float *x, int w, int h, int pd, float p, float q,
		int m) // method
{
	if (m == 3) {
		bicubic_interpolation(result, x, w, h, pd, p, q);
	} else {
		int ip = floor(p);
		int iq = floor(q);
		for (int l = 0; l < pd; l++) {
			float a = getsample_0(x, w, h, pd, ip  , iq  , l);
			float b = getsample_0(x, w, h, pd, ip  , iq+1, l);
			float c = getsample_0(x, w, h, pd, ip+1, iq  , l);
			float d = getsample_0(x, w, h, pd, ip+1, iq+1, l);
			float v = interpolate_cell(a, b, c, d, p-ip, q-iq, m);
			result[l] = v;
		}
	}
}
Пример #7
0
void BLI_bicubic_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
                                    int components, float u, float v)
{
	bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
}
Пример #8
0
void BLI_bicubic_interpolation_fl(const float *buffer, float *output, int width, int height,
                                  int components, float u, float v)
{
	bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
}
Пример #9
0
/* only supports RGBA nodes now */
static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{

	if(out[0]->hasoutput==0)
		return;

	if(in[0]->data) {
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);	/* note, this returns zero'd image */
		float rad, u, v, s, c, centx, centy, miny, maxy, minx, maxx;
		int x, y, yo, xo;
		ImBuf *ibuf, *obuf;

		rad= (M_PI*in[1]->vec[0])/180.0f;

		s= sin(rad);
		c= cos(rad);
		centx= cbuf->x/2;
		centy= cbuf->y/2;

		minx= -centx;
		maxx= -centx + (float)cbuf->x;
		miny= -centy;
		maxy= -centy + (float)cbuf->y;


		ibuf=IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
		obuf=IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);

		if(ibuf && obuf){
			ibuf->rect_float=cbuf->rect;
			obuf->rect_float=stackbuf->rect;

			for(y=miny; y<maxy; y++) {
				yo= y+(int)centy;

				for(x=minx; x<maxx;x++) {
					u=c*x + y*s + centx;
					v=-s*x + c*y + centy;
					xo= x+(int)centx;

					switch(node->custom1) {
					case 0:
						neareast_interpolation(ibuf, obuf, u, v, xo, yo);
						break ;
					case 1:
						bilinear_interpolation(ibuf, obuf, u, v, xo, yo);
						break;
					case 2:
						bicubic_interpolation(ibuf, obuf, u, v, xo, yo);
						break;
					}

				}
			}

			/* rotate offset vector too, but why negative rad, ehh?? Has to be replaced with [3][3] matrix once (ton) */
			s= sin(-rad);
			c= cos(-rad);
			centx= (float)cbuf->xof; centy= (float)cbuf->yof;
			stackbuf->xof= (int)( c*centx + s*centy);
			stackbuf->yof= (int)(-s*centx + c*centy);

			IMB_freeImBuf(ibuf);
			IMB_freeImBuf(obuf);
		}

		/* pass on output and free */
		out[0]->data= stackbuf;
		if(cbuf!=in[0]->data) {
			free_compbuf(cbuf);
		}
	}
}
Пример #10
0
CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type)
{
	CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);
	ImBuf *ibuf, *obuf;
	float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
	float svec[3]= {scale, scale, scale}, loc[2]= {x, y};

	unit_m4(rmat);
	unit_m4(lmat);
	unit_m4(smat);
	unit_m4(cmat);

	/* image center as rotation center */
	cmat[3][0]= (float)cbuf->x/2.0f;
	cmat[3][1]= (float)cbuf->y/2.0f;
	invert_m4_m4(icmat, cmat);

	size_to_mat4(smat, svec);		/* scale matrix */
	add_v2_v2(lmat[3], loc);		/* tranlation matrix */
	rotate_m4(rmat, 'Z', angle);	/* rotation matrix */

	/* compose transformation matrix */
	mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);

	invert_m4(mat);

	ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
	obuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);

	if (ibuf && obuf) {
		int i, j;

		ibuf->rect_float= cbuf->rect;
		obuf->rect_float= stackbuf->rect;

		for (j=0; j<cbuf->y; j++) {
			for (i=0; i<cbuf->x;i++) {
				float vec[3]= {i, j, 0};

				mul_v3_m4v3(vec, mat, vec);

				switch(filter_type) {
					case 0:
						neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
						break;
					case 1:
						bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
						break;
					case 2:
						bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
						break;
				}
			}
		}

		IMB_freeImBuf(ibuf);
		IMB_freeImBuf(obuf);
	}

	/* pass on output and free */
	return stackbuf;
}
Пример #11
0
void rhf_multiscale(int iDWin,       // Half size of patch
                    int iDBloc,      // Half size of research window
                    float fDistance, // Max-Distance parameter
                    int knn,         // Minimum Number of Neighbors
                    int iNscales,    // Number of Scales
                    float **fhI,     // Histogram
                    float **fpI,     // Input
                    float **fpO,     // Output
                    int iChannels,   // Number of channels
                    int iWidth,      // Image width
                    int iHeight,     // Image height
                    int iBins)       // Number of bins Histogram image

{
    
    //0 Scales:  1x1
    //1 Scales:  1x1, 2x2
    //2 Scales:  1x1, 2x2, 4x4
    //3 Scales:  1x1, 2x2, 4x4, 16x16
    
    //Need a buffer....
    float **fpOs_old = (float**) malloc(sizeof(float*)*iChannels);
    int nxSold,nySold;
    nxSold=nySold=-1;
    
    for (int ii=0; ii< iChannels;ii++)
        fpOs_old[ii] = (float*) malloc(sizeof(float)*iWidth * iHeight);
    
    double sigma_scale = SIGMASCALE;
    
    //Total number of samples in the whole image
    double dtotal = 0.0f;
    
    for(int ii=0;ii < iWidth*iHeight; ii++)
    {
        dtotal += fhI[iBins-1][ii];
    }
    
    for(int s=iNscales-1; s>=0; s--)
    {
        
        // Generate Image and Histogram at desired scale
        float **fpIs;// = (float**) malloc(sizeof(float*)*iChannels);
        float **fpOs = (float**) malloc(sizeof(float*)*iChannels);
        float **fhIs;// = (float**) malloc(sizeof(float*)*iBins);
        
        int nxS, nyS, nyM, nxM, nxSS, nySS;
        
        double scale = pow(0.5f,s);
        
        if(s>0) //If it is not the last scale...
        {
            fhIs = gaussian_sampler(fhI,
                                    iWidth, iHeight, iBins,
                                    &nxS, &nyS,
                                    scale, sigma_scale);
            
            //Renormalize weights to keep total number of samples
            double dtotalS = 0;
            for(int ii=0;ii < nxS*nyS; ii++)
            {
                dtotalS += fhIs[iBins-1][ii];
            }
            float samples_factor = (dtotal/dtotalS);
            
            for(int ii=0; ii < nxS*nyS; ii++)
            {
                for(int jj=0; jj< iBins; jj++)
                    fhIs[jj][ii] = samples_factor*fhIs[jj][ii];
            }
            
            fpIs = gaussian_sampler(fpI,
                                    iWidth, iHeight, iChannels,
                                    &nxS, &nyS,
                                    scale, sigma_scale);
        }
        else
        {
            fpIs = fpI;
            fhIs = fhI;
            nxS = iWidth;
            nyS = iHeight;
        }
        
        for (int ii=0; ii < iChannels; ii++)
        {
            fpOs[ii] = (float*) malloc(sizeof(float)*nxS*nyS);
        }
        
        //Filter Scale
        printf("-->Filtering Scale %d BEGIN\n",s);
        
        //In the scale 0 force a minimum number of neighbors
        int knnS = (s>0)?0:knn;
        
        if(knnS>0)
        {
            rhf_knn(iDWin,       // Half size of patch
                    iDBloc,      // Half size of research window
                    fDistance,   // Max-Distance parameter
                    knn,         // Minimum number of neighbors
                    fhIs,        // Histogram
                    fpIs,        // Input
                    fpOs,        // Output
                    iChannels, nxS, nyS, iBins);
        }
        else
        {
            rhf(iDWin,      // Half size of patch
                iDBloc,     // Half size of research window
                fDistance,  // Max-Distance parameter
                fhIs,       // Histogram
                fpIs,       // Input
                fpOs,       // Output
                iChannels, nxS, nyS, iBins);
        }
        
        printf("-->Filtering Scale %d END\n",s);
        
        if(s < iNscales - 1) //This is not the last Scale
        {
            
            float **fpOs_PosTerm; //= (float**) malloc(sizeof(float*)*iChannels);
            
            fpOs_PosTerm = bicubic_interpolation(fpOs_old, nxSold, nySold,
                                                 iChannels, nxS, nyS);
            nxM = nxS;
            nyM = nyS;
            
            float **fpOs_NegTermD; //= (float**) malloc(sizeof(float*)*iChannels);
            float **fpOs_NegTerm; //= (float**) malloc(sizeof(float*)*iChannels);
            
            fpOs_NegTermD = gaussian_sampler(fpOs,
                                             nxS, nyS, iChannels,
                                             &nxM, &nyM,
                                             0.5f,    sigma_scale);
            
            fpOs_NegTerm = bicubic_interpolation(fpOs_NegTermD, nxM, nyM,
                                                 iChannels, nxS, nyS);
            nxSS = nxS;
            nySS = nyS;
            
            nxS = MIN(nxS, nxSS);
            nyS = MIN(nyS, nySS);
            
            for(int ii=0; ii < iChannels; ii++)
                for(int x=0;x<nxS*nyS;x++)
                {
                    fpOs[ii][x] += fpOs_PosTerm[ii][x] - fpOs_NegTerm[ii][x];
                }
            
            //Cleaning
            for (int ii=0; ii < iChannels; ii++) {
                free(fpOs_NegTermD[ii]);
                free(fpOs_NegTerm[ii]);
                free(fpOs_PosTerm[ii]);
            }
            
            free(fpOs_NegTermD);
            free(fpOs_NegTerm);
            free(fpOs_PosTerm);
        }
        
        //Clean last fpOs_old and create the new one
        nxSold = nxS;
        nySold = nyS;
        
        for (int ii=0; ii < iChannels; ii++) {
            for(int x=0;x<nxS*nyS;x++)
                fpOs_old[ii][x] = fpOs[ii][x];
        }
        
        //If scale==0 copy output
        if(s==0)
        {
            for(int ii=0; ii < iChannels; ii++)
                for(int x=0;x<iWidth*iHeight;x++)
                    fpO[ii][x] = fpOs[ii][x];
            
            /*Clean*/
            for (int ii=0; ii < iChannels; ii++) {
                free(fpOs_old[ii]);
            }
            
            free(fpOs_old);
        }
        
        //Clean the Step
        if(s>0)
        {
            for (int ii=0; ii < iBins; ii++) {
                free(fhIs[ii]);
            }
            
            for (int ii=0; ii < iChannels; ii++) {
                free(fpIs[ii]);
            }
            
            free(fpIs);
            free(fhIs);
        }
        
        for (int ii=0; ii < iChannels; ii++) {
            free(fpOs[ii]);
        }
        
        free(fpOs);
        
    } //for Scales
}
Пример #12
0
// Modèle Numérique d'Élévation Horn Schunck (cas affine)
void mnehs_affine(float *out_h, float *init_h, int ow, int oh,
		float *a, int wa, int ha,
		float *b, int wb, int hb,
		double PA[8], double PB[8],
		float alpha2, int niter)
{
	// allocate temporary images
	float *h   = xmalloc(ow * oh * sizeof*h);     // h-increment
	float *Q   = xmalloc(ow * oh * sizeof*Q);      // Q
	float *amb = xmalloc(ow * oh * sizeof*amb);    // A-B (warped)
	float *ga  = xmalloc(2 * wa * ha * sizeof*ga); // grad(A)
	float *gb  = xmalloc(2 * wb * hb * sizeof*gb); // grad(B)

	// gradient of A and B
	fill_gradient(ga, a, wa, ha);
	fill_gradient(gb, b, wb, hb);

	// fill images q and amb (a minus b)
	for (int j = 0; j < oh; j++)
	for (int i = 0; i < ow; i++)
	{
		float h0 = getsample_nan(init_h, ow, oh, 1, i, j, 0);
		double ijh[3] = {i, j, h0}, paijh[3], pbijh[3];
		apply_projection(paijh, PA, ijh);
		apply_projection(pbijh, PB, ijh);
		float va, vb, vga[2], vgb[2];
		bicubic_interpolation_nans(&va, a, wa, ha, 1, paijh[0], paijh[1]);
		bicubic_interpolation_nans(&vb, b, wb, hb, 1, pbijh[0], pbijh[1]);
		bicubic_interpolation(vga, ga, wa, ha, 2, paijh[0], paijh[1]);
		bicubic_interpolation(vgb, gb, wb, hb, 2, pbijh[0], pbijh[1]);
		float gapa = vga[0] * PA[2] + vga[1] * PA[6];
		float gbpb = vgb[0] * PB[2] + vgb[1] * PB[6];
		Q  [j*ow+i] = gapa - gbpb;
		amb[j*ow+i] = va - vb;
	}

	nusavec("Q_%d.tiff", global_scale, Q, ow, oh, 1);
	nusavec("amb_%d.tiff", global_scale, amb, ow, oh, 1);

	// initialize h
	for (int i = 0; i < ow * oh; i++)
		h[i] = 0;

	// run the iterations (without warps)
	for (int iter = 0; iter < niter; iter++)
	{
		for (int j = 0; j < oh; j++)
		for (int i = 0; i < ow; i++)
		{
			int ij = j * ow + i;
			if (!isfinite(amb[ij])) continue;

			float ax = laplacian_at(h, ow, oh, i, j);
			ax -= Q[ij] * (Q[ij] * h[ij] + amb[ij]) / alpha2;
			h[ij] += TAU() * ax;
		}
	}
	nusavec("h_%d.tiff", global_scale, h, ow, oh, 1);

	// update result
	for (int i = 0; i < ow * oh; i++)
		out_h[i] = init_h[i] + h[i];
	
	// cleanup and exit
	free(h);
	free(Q);
	free(amb);
	free(ga);
	free(gb);
}