void
DistanceTransformFInv(vector<float>& D, 
					  const vector<unsigned char>& L, 
					  int mode,
					  int ndim, 
					  const int* dims) {

  vector<unsigned char> invL(L.size());
  int i;
  for(i=0; i<L.size(); ++i) {
    if(L[i]==0)
      invL[i]=1;
    else
      invL[i]=0;
  }

  DistanceTransformF(D,invL,mode,ndim,dims);
}
bool EllipseFitting(POINT* rgPoints, int nPoints, double &a, double &b, double &c, double &d, double &e, double &f)
{
	int		i, j;
	int		np = nPoints;
	int		nrot=0;

	Matrix<double>	D(np+1,7);	//Design matrix
	Matrix<double>	S(7,7);		//Scatter matrix
	Matrix<double>	Const(7,7);	//Constraint matrix
	Matrix<double>	temp(7,7);
	Matrix<double>	L(7,7);		//The lower triangular matrix L * L' = S
	Matrix<double>	C(7,7);
	Matrix<double>	invL(7,7);	//Inverse matrix of L
	Matrix<double>	V(7,7);		//The eigen vectors
	Matrix<double>	sol(7,7);	//The GVE solution

	double	ev[7];		//The eigen value
	double	pvec[7];

	if (np < 6)
	{
		return false;
	}

	//Build design matrix D
	for (i = 0; i < np; i++)
	{ 
		D[i][1]	= rgPoints[i].x * rgPoints[i].x;
		D[i][2] = rgPoints[i].x * rgPoints[i].y;
		D[i][3] = rgPoints[i].y * rgPoints[i].y;
		D[i][4] = rgPoints[i].x;
		D[i][5] = rgPoints[i].y;
		D[i][6] = 1.0;
	}

	//Build Scatter matrix S
	A_TperB(D, D, S, np, 6, np, 6);

	//Build 6*6 constraint matrix
	Const[1][3] = -2;
	Const[2][2] = 1;
	Const[3][1] = -2;

	//Sovle generalized eigen system
	choldc(S, 6, L);
	if (!inverse(L, invL, 6))
	{
		return false;
	}
	AperB_T(Const, invL, temp, 6, 6, 6, 6);
	AperB(invL, temp, C, 6, 6, 6, 6);
	jacobi(C, 6, ev, V, nrot);
	A_TperB(invL, V, sol, 6, 6, 6, 6);

	//Normalize the solution
	for (j = 1; j <= 6; j++)
	{
		double mod = 0.0;

		for (i = 1; i <= 6; i++)
		{
			mod += sol[i][j] * sol[i][j];
		}

		mod = sqrt(mod);

		for (i = 1 ; i <= 6; i++)
		{
		 	sol[i][j] /= mod;
		}
	}

	double	zero	= 10e-20;
	int		solind	= 0;

	//Find the only negative eigen value
	for (i = 1; i <= 6; i++)
	{
		if ((ev[i] < 0) && (fabs(ev[i]) > zero))
		{
			solind = i;
		}
	}

	//Get the fitted parameters
	for (j = 1; j <= 6; j++)
	{
		pvec[j] = sol[j][solind];
	}		

	a = pvec[1];
	b = pvec[2];
	c = pvec[3];
	d = pvec[4];
	e = pvec[5];
	f = pvec[6];

	return true;
}
    ThinPlateSpline(std::vector<boost::array<WorkingType, PosDim> > positions,
        std::vector<boost::array<WorkingType, ValDim> > values)
    {
      boost::numeric::ublas::matrix<WorkingType> L;

      refPositions = positions;

      const int numPoints((int)refPositions.size());
      const int WaLength(numPoints + PosDim + 1);

      L = boost::numeric::ublas::matrix<WorkingType> (WaLength, WaLength);

      // Calculate K and store in L
      for(int i(0); i < numPoints; i++)
      {
        L(i,i) = 0.0;
        // K is symmetrical so no point in calculating things twice
        int j(i + 1);
        for(; j < numPoints; ++j)
        {

          L(i,j) = L(j,i) = radialbasis<WorkingType, WorkingType, PosDim>(refPositions[i], refPositions[j]);
        }

        // construct P and store in K
        L(j,i) = L(i,j) = 1.0;
        ++j;
        for(int posElm(0); j < WaLength; ++posElm, ++j)
          L(j,i) = L(i,j) = positions[i][posElm];
      }

      // O
      for(int i(numPoints); i < WaLength; i++)
        for(int j(numPoints); j < WaLength; j++)
          L(i,j) = 0.0;

      // Solve L^-1 Y = W^T

      typedef boost::numeric::ublas::permutation_matrix<std::size_t> pmatrix;

      boost::numeric::ublas::matrix<WorkingType> A(L);
      pmatrix pm(A.size1());
      int res = (int)lu_factorize(A, pm);
      if(res != 0)
	  {
        ;//TODO catch this error
	  }

      boost::numeric::ublas::matrix<WorkingType> invL(boost::numeric::ublas::identity_matrix<WorkingType>(A.size1()));
      lu_substitute(A, pm, invL);


      Wa = boost::numeric::ublas::matrix<WorkingType>(WaLength, ValDim );

      boost::numeric::ublas::matrix<WorkingType> Y(WaLength, ValDim);
      int i(0);
      for(; i < numPoints; i++)
        for(int j(0); j < ValDim; ++j)
          Y(i, j) = values[i][j];

      for(; i < WaLength; i++)
        for(int j(0); j < ValDim; ++j)
          Y(i, j) = 0.0;

      Wa = prod(invL,Y);

    }