Exemplo n.º 1
0
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	if (!(nlhs==1))
	{
    	mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");
    }
    if (!(nrhs==2 || nrhs==3))
    {
    	mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Two double matrix and one optional structure are required.");
    }

	int i = 1;
	float tau     = PAR_DEFAULT_TAU;
	float lambda  = PAR_DEFAULT_LAMBDA;
	float theta   = PAR_DEFAULT_THETA;
	int   nscales = PAR_DEFAULT_NSCALES;
	float zfactor = PAR_DEFAULT_ZFACTOR;
	int   nwarps  = PAR_DEFAULT_NWARPS;
	float epsilon = PAR_DEFAULT_EPSILON;
	int   verbose = PAR_DEFAULT_VERBOSE;
	if (nrhs==3)
    {
      int tmp=0;
      double* ptr;
      for( tmp=0; tmp<mxGetNumberOfFields(prhs[2]);tmp++)
      {
        if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"tau")==0)
        {
          if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
          {
              mexErrMsgTxt("A double argument was expected.");
          }
          if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
          {
            mexErrMsgTxt("Only one value was expected.");
          }
          ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
          if (ptr[0]> 0 && ptr[0]< 0.25)
          {
            tau=ptr[0];
          }
          else
          {
              mexErrMsgTxt("The tau value is not acceptable. For more information, type \"help tvl1\"");
          }
        }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"lambda")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  lambda=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The lambda value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"theta")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  theta=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The theta value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"nscales")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  nscales=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The nscales value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"zfactor")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  zfactor=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The zfactor value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"nwarps")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  nwarps=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The nwarps value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"epsilon")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  epsilon=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The epsilon value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
      }
	}

	if (tau <= 0 || tau > 0.25) {
		tau = PAR_DEFAULT_TAU;
		if (verbose) mexPrintf("warning: "
				"tau changed to %g\n", tau);
	}
	if (lambda <= 0) {
		lambda = PAR_DEFAULT_LAMBDA;
		if (verbose) mexPrintf("warning: "
				"lambda changed to %g\n", lambda);
	}
	if (theta <= 0) {
		theta = PAR_DEFAULT_THETA;
		if (verbose) mexPrintf("warning: "
				"theta changed to %g\n", theta);
	}
	if (nscales <= 0) {
		nscales = PAR_DEFAULT_NSCALES;
		if (verbose) mexPrintf("warning: "
				"nscales changed to %d\n", nscales);
	}
	if (zfactor <= 0 || zfactor >= 1) {
		zfactor = PAR_DEFAULT_ZFACTOR;
		if (verbose) mexPrintf( "warning: "
				"zfactor changed to %g\n", zfactor);
	}
	if (nwarps <= 0) {
		nwarps = PAR_DEFAULT_NWARPS;
		if (verbose) mexPrintf( "warning: "
				"nwarps changed to %d\n", nwarps);
	}
	if (epsilon <= 0) {
		epsilon = PAR_DEFAULT_EPSILON;
		if (verbose) mexPrintf("warning: "
				"epsilon changed to %f\n", epsilon);
	}
    
	int    nx = mxGetN(prhs[0]);
	int    ny = mxGetM(prhs[0]);
	int    nx2 = mxGetN(prhs[1]);
	int    ny2 = mxGetM(prhs[1]);
	float *I0=malloc(nx*ny*sizeof(float));
	int tmpx, tmpy;
   for (tmpx=0; tmpx<nx; tmpx++) 
      for (tmpy=0; tmpy<ny; tmpy++) 
		   I0[tmpx+tmpy*nx] = (float)(mxGetPr(prhs[0]))[tmpy+tmpx*ny];

	float *I1=malloc(nx2*ny2*sizeof(float));
   for (tmpx=0; tmpx<nx2; tmpx++) 
      for (tmpy=0; tmpy<ny2; tmpy++) 
		   I1[tmpx+tmpy*nx] = (float)(mxGetPr(prhs[1]))[tmpy+tmpx*ny];

		if (nx == nx2 && ny == ny2)
	{

		const float N = 1 + log(hypot(nx, ny)/16.0) / log(1/zfactor);
		if (N < nscales)
			nscales = N;
		if (verbose)
		{
			mexPrintf(
				"tau=%f lambda=%f theta=%f nscales=%d "
				"zfactor=%f nwarps=%d epsilon=%g\n",
				tau, lambda, theta, nscales,
				zfactor, nwarps, epsilon);
		}

		float *u = xmalloc(2 * nx * ny * sizeof(*u));
		float *v = u + nx*ny;

		Dual_TVL1_optic_flow_multiscale(
				I0, I1, u, v, nx, ny, tau, lambda, theta,
				nscales, zfactor, nwarps, epsilon, verbose
		);
		mwSize dim = 3;
    	const mwSize dims[3]={ny,nx,2};
    	plhs[0]=mxCreateNumericArray(dim, dims,mxDOUBLE_CLASS,mxREAL);
    	double* pointeur=(double*)mxGetPr(plhs[0]);
      for (tmpy=0; tmpy<ny; tmpy++) 
         for (tmpx=0; tmpx<nx; tmpx++) 
         {
        	   pointeur[tmpy+tmpx*ny + 0    ]=(double)u[tmpx+tmpy*nx];
        	   pointeur[tmpy+tmpx*ny + nx*ny]=(double)v[tmpx+tmpy*nx];
         }
		free(I0);
		free(I1);
		free(u);
	} 
	else
	{
		mexErrMsgTxt("ERROR: input images size mismatch ");
	}
}
Exemplo n.º 2
0
/**
 *
 *  Main program:
 *   This program reads the following parameters from the console and
 *   then computes the optical flow:
 *   I_1 		  Previous image to I0
 *   I0          first image
 *   I1          second image
 *   I0_Smoothed Image for using with function g
 *   out         name of the output flow field
 *   outOcc      name of the output occlusion map
 *   nprocs      number of threads to use (OpenMP library)
 *   tauEta      Time step in the primal-dual scheme for eta variable
 *   tauChi      Time step in the primal-dual scheme for chi variable
 *   lambda      Data term weight parameter
 *   alpha       Length term weight parameter (in the occlusion region)
 *   beta		  Negative divergence data Term
 *   theta       tightness parameter
 *   nscales     number of scales in the pyramidal structure
 *   zfactor     downsampling factor for creating the scales
 *   nwarps      number of warps per scales
 *   epsilon     stopping criterion threshold for the iterative process
 *   verbose     switch on/off messages
 *
 */
int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s I_1 I0 I1 [I0_Smoothed out "
				//              0   1   2  3      4        5
				"outOcc nproc lambda alpha beta theta nscales zfactor nwarps epsilon "
				// 6      7      8   9    10    11        12     13     14     15
				"verbose  ]\n", *argv);
				// 16
		return EXIT_FAILURE;
	}
	// Variable Declaration
	double *u1=NULL, *u2=NULL; //field
	double *chi=NULL;	 	   //Occlussion map

	double *I_1=NULL, *I0=NULL, *I1=NULL;  // Previous (I_1), current (I0) and next image (I1)
	double *filtI0=NULL;                   //Filtered image used in function g

	int nx_1, ny_1, nx, ny, nx1, ny1, nxf, nyf; //Image sizes

	//read the parameters
	int i = 1;
	char* image_1_name = argv[i]; i++; //1
	char* image1_name  = argv[i]; i++; //2
	char* image2_name  = argv[i]; i++; //3
	char* image1_Smooth_name = (argc>i) ? argv[i] : argv[2]; i++; //4 If there is no I0_Smoothed, then it will be I0
	const char* outfile = (argc>i)? argv[i]: PAR_DEFAULT_OUTFLOW;       i++; //5
	const char* outOccFile = (argc>i)? argv[i]: PAR_DEFAULT_OUT_OCC;       i++; //6
	int   nproc   = (argc>i)? atoi(argv[i]): PAR_DEFAULT_NPROC;   i++; //7
	double lambda  = (argc>i)? atof(argv[i]): PAR_DEFAULT_LAMBDA;  i++; //8
	double alpha   = (argc>i)? atof(argv[i]): PAR_DEFAULT_ALPHA;   i++; //9
	double betaW   = (argc>i)? atof(argv[i]): PAR_DEFAULT_BETA;    i++; //10
	double theta   = (argc>i)? atof(argv[i]): PAR_DEFAULT_THETA;   i++; //11
	int   nscales = (argc>i)? atoi(argv[i]): PAR_DEFAULT_NSCALES; i++; //12
	double zfactor = (argc>i)? atof(argv[i]): PAR_DEFAULT_ZFACTOR; i++; //13
	int   nwarps  = (argc>i)? atoi(argv[i]): PAR_DEFAULT_NWARPS;  i++; //14
	double epsilon = (argc>i)? atof(argv[i]): PAR_DEFAULT_EPSILON; i++; //15
	int   verbose = (argc>i)? atoi(argv[i]): PAR_DEFAULT_VERBOSE; i++; //16

	//check parameters
	if (nproc < 0) {
		nproc = PAR_DEFAULT_NPROC;
		fprintf(stderr, "warning: "
				"nproc changed to %d\n", nproc);
	}
	if (lambda <= 0) {
		lambda = PAR_DEFAULT_LAMBDA;
		fprintf(stderr, "warning: "
				"lambda changed to %g\n", lambda);
	}
	if (alpha <= 0) {
		alpha = PAR_DEFAULT_ALPHA;
		fprintf(stderr, "warning: "
				"alpha changed to %g\n", alpha);
	}
	if (betaW <= 0) {
		betaW = PAR_DEFAULT_BETA;
		fprintf(stderr, "warning: "
				"beta changed to %g\n", betaW);
	}
	if (theta <= 0) {
		theta = PAR_DEFAULT_THETA;
		if (verbose) fprintf(stderr, "warning: "
				"theta changed to %g\n", theta);
	}
	if (nscales <= 0) {
		nscales = PAR_DEFAULT_NSCALES;
		fprintf(stderr, "warning: "
				"nscales changed to %d\n", nscales);
	}
	if (zfactor <= 0 || zfactor >= 1) {
		zfactor = PAR_DEFAULT_ZFACTOR;
		fprintf(stderr, "warning: "
				"zfactor changed to %g\n", zfactor);
	}
	if (nwarps <= 0) {
		nwarps = PAR_DEFAULT_NWARPS;
		fprintf(stderr, "warning: "
				"nwarps changed to %d\n", nwarps);
	}
	if (epsilon <= 0) {
		epsilon = PAR_DEFAULT_EPSILON;
		fprintf(stderr, "warning: "
				"epsilon changed to %f\n", epsilon);
	}


#ifdef _OPENMP
	if (nproc > 0)
		omp_set_num_threads(nproc);
#endif//DISABLE_OMP

	// read the input images
	I_1    = read_image(image_1_name, &nx_1, &ny_1);
	I0     = read_image(image1_name, &nx, &ny);
	I1     = read_image(image2_name, &nx1, &ny1);
	filtI0 = read_image(image1_Smooth_name, &nxf, &nyf);

	if(nx==nx_1 && nx==nx1 && nx==nxf &&
			ny==ny_1 && ny==ny1 && ny==nyf)
	{
		//Set the number of scales according to the size of the
		//images.  The value N is computed to assure that the smaller
		//images of the pyramid don't have a size smaller than 16x16

		const int N = floor(log((float)MIN(nx, ny)/16.0)/log(1./zfactor)) + 1;

		if (N < nscales)
			nscales = N;

		if (verbose)
			fprintf(stderr,
					" nproc=%d   \n lambda=%f \n alpha=%f \n"
					" beta=%f \n theta=%f \n nscales=%d \n zfactor=%f\n nwarps=%d \n epsilon=%g\n",
					nproc, lambda, alpha, betaW, theta, nscales,
					zfactor, nwarps, epsilon);

		//allocate memory for the flow
		u1  = (double *)xmalloc( nx * ny * sizeof(double));
		u2  = (double *)xmalloc( nx * ny * sizeof(double));

		//and the occlusion map
		chi = (double *)xmalloc( nx * ny * sizeof(double));


		for(int i=0; i<nx*ny; i++)
		{
			chi[i] = 0.0;
			u1[i]  = 0.0;
			u2[i]  = 0.0;
		}


		//compute the optical flow
		Dual_TVL1_optic_flow_multiscale(
				I_1, I0, I1, filtI0, u1, u2, chi, nx, ny, lambda, alpha, betaW,  theta,
				nscales, zfactor, nwarps, epsilon, verbose);

		//write_flow(u1, u2, nx, ny); //<----Eliminar en la version fina a entregar. Solo esta para propositos de depuraci—n.

		//save the optical flow

		float *f = (float *)malloc(sizeof(float) * nx * ny * 2);
		for (int i = 0; i < nx * ny; i++)
		{
			f[2*i] = (float)u1[i];   //Avoid the cast!
			f[2*i+1] = (float)u2[i]; //Avoid the cast!
		}
		iio_save_image_float_vec((char *)outfile, f, nx, ny, 2);

		free(f);

		//save the occlusions
/*		int iv=0;
		FILE * fid=fopen(outOccFile, "w");
		for (int i=0; i<ny; i++)
		{
			for (int j=0; j<nx; j++)
			{
				fprintf(fid, " %f", chi[iv]);
				iv++;
			}
			fprintf(fid, " \n");
		}
		fclose(fid);*/
		//iio_save_image_double((char *)outOccFile, chi, nx, ny);

		float *fOcc = (float *)malloc(sizeof(float) * nx * ny );
		for (int i = 0; i < nx * ny; i++)
		{
			fOcc[i] = (float)chi[i]*255;   //Avoid the cast!
		}
		iio_save_image_float((char *)outOccFile, fOcc, nx, ny);

		free(fOcc);
	}
	//delete allocated memory
	free(I0);
	free(I1);
	free(u1);
	free(u2);
	free(filtI0);
	free(chi);

	return EXIT_SUCCESS;
}