示例#1
0
// Fit model to this random selection of data points.
void
vpHomography::computeTransformation(vpColVector &x, unsigned int *ind, vpColVector &M)
{
  unsigned int i ;
  unsigned int n = x.getRows()/4 ;
  std::vector<double> xa(4), xb(4);
  std::vector<double> ya(4), yb(4);
  unsigned int n2 = n * 2;
  unsigned int ind2;
  for(i=0 ; i < 4 ; i++)
    {
      ind2 = 2 * ind[i];
      xb[i] = x[ind2] ;
      yb[i] = x[ind2+1] ;

      xa[i] = x[n2+ind2] ;
      ya[i] = x[n2+ind2+1] ;
    }

  vpHomography aHb ;
  try {
    vpHomography::HLM(xb, yb, xa, ya, true, aHb);
  }
  catch(...)
    {
      aHb.setIdentity();
    }

  M.resize(9);
  for (i=0 ; i <9 ; i++)
    {
      M[i] = aHb.data[i] ;
    }
  aHb /= aHb[2][2] ;
}
示例#2
0
void OrganizedData::process(RawData* raw, int nBlock, double pTest, int nSupport)
{
    int nData = raw->nData, nDim = raw->nDim - 1;

    this->nSupport = nSupport;
    this->nBlock   = nBlock;
    this->nDim     = nDim;

    train   = field<mat>(nBlock,2);
    test    = field<mat>(nBlock,2);
    support = field<mat>(1,2);

    mat xm(nSupport,nDim),
        ym(nSupport,1);

    vec mark(nData); mark.fill(0);

    printf("Randomly selecting %d supporting point ...\n", nSupport);

    for (int i = 0; i < nSupport; i++)
	{
		int pos = IRAND(0, nData - 1);
		while (mark[pos] > 0)
			pos = IRAND(0, nData - 1);
		mark[pos] = 1;
		for (int j = 0; j < nDim; j++)
			xm(i, j) = raw->X(pos,j);
		ym(i,0) = raw->X(pos,nDim);
	}

	support(0,0) = xm; xm.clear();
	support(0,1) = ym; ym.clear();

    cout << "Partitioning the remaining data into " << nBlock << " cluster using K-Mean ..." << endl;

    vvd _remain;

    for (int i = 0; i < nData; i++) if (!mark(i))
    {
        rowvec R = raw->X.row(i);
        _remain.push_back(r2v(R));
    }

    mat remaining = v2m(_remain);

    mark.clear();

    RawData* remain = new RawData(remaining);

    KMean* partitioner = new KMean(remain);

    Partition* clusters = partitioner->cluster(nBlock);

    cout << "Packaging training/testing data points into their respective cluster" << endl;

    for (int i = 0; i < nBlock; i++)
    {
        cout << "Processing block " << i + 1 << endl;

        int bSize   = (int) clusters->member[i].size(),
            tSize   = (int) floor(bSize * pTest),
            pos     = 0,
            counter = 0;

        mark = vec(bSize); mark.fill(0);

        if (bSize > tSize)  // if we can afford to draw tSize test points from this block without depleting it ...
        {
            mat xt(tSize,nDim),
                yt(tSize,1);

            for (int j = 0; j < tSize; j++)
            {
                pos = IRAND(0, bSize - 1);
				while (mark[pos] > 0)
					pos = IRAND(0, bSize - 1);
				mark[pos] = 1; pos = clusters->member[i][pos];

				for (int t = 0; t < nDim; t++)
					xt(j, t) = remain->X(pos,t);
				yt(j,0) = remain->X(pos,nDim);
            }

            bSize  -= tSize;
            nTest  += tSize;

            test(i,0) = xt; xt.clear();
            test(i,1) = yt; yt.clear();
        }

        nTrain += bSize;

        mat xb(bSize,nDim),
            yb(bSize,1);

        //cout << remain->X.n_rows << endl;

        for (int j = 0; j < (int)mark.n_elem; j++) if (mark[j] < 1)
        {
            for (int t = 0; t < nDim; t++) {
                xb(counter,t) = remain->X(clusters->member[i][j],t);
            }
            yb(counter++,0) = remain->X(clusters->member[i][j],nDim);
        }

        train(i,0) = xb; xb.clear();
        train(i,1) = yb; yb.clear();

        mark.clear();

        printf("Done ! nData[%d] = %d, nTrain[%d] = %d, nTest[%d] = %d .\n", i, (int) clusters->member[i].size(), i, train(i,0).n_rows, i, (int) test(i,0).n_rows);
    }
}
    /**
     * With the critical edge selection, initial kernel erstimation can be accomplished quickly.
     * Objective function: E(k) = ||∇I^s ⊗ k - ∇B||² + γ||k||²
     * 
     * @param selectionGrads  array of x and y gradients of final selected edges (∇I^s) [-1, 1]
     * @param blurredGrads    array of x and y gradients of blurred image (∇B) [-1, 1]
     * @param kernel          energy preserving kernel (k)
     */
    void fastKernelEstimation(const array<Mat,2>& selectionGrads,
                              const array<Mat,2>& blurredGrads, Mat& kernel,
                              const float weight = 1e-2) {

        assert(selectionGrads[0].rows == blurredGrads[0].rows && "matrixes have to be of same size!");
        assert(selectionGrads[0].cols == blurredGrads[0].cols && "matrixes have to be of same size!");

        // based on Perseval's theorem, perform FFT
        //                __________              __________
        //             (  F(∂_x I^s) * F(∂_x B) + F(∂_y I^s) * F(∂_y B) )
        // k = F^-1 * ( ----------------------------------------------   )
        //             (         F(∂_x I^s)² + F(∂_y I^s)² + γ          )
        // where * is pointwise multiplication
        //                   __________
        // and F(∂_x I^s)² = F(∂_x I^s) * F(∂_x I^s) ! because they mean the norm
        // 
        // here: F(∂_x I^s) = xS
        //       F(∂_x B)   = xB
        //       F(∂_y I^s) = yS
        //       F(∂_y B)   = yB
        
        // compute FFTs
        // the result are stored as 2 channel matrices: Re(FFT(I)), Im(FFT(I))
        Mat xS, xB, yS, yB;
        deblur::dft(selectionGrads[0], xS);
        deblur::dft(blurredGrads[0], xB);
        deblur::dft(selectionGrads[1], yS);
        deblur::dft(blurredGrads[1], yB);

        complex<float> we(weight, 0.0);

        // kernel in Fourier domain
        Mat K = Mat::zeros(xS.size(), xS.type());

        // pixelwise computation of kernel
        for (int y = 0; y < K.rows; y++) {
            for (int x = 0; x < K.cols; x++) { 
                // complex entries at the current position
                complex<float> xs(xS.at<Vec2f>(y, x)[0], xS.at<Vec2f>(y, x)[1]);
                complex<float> ys(yS.at<Vec2f>(y, x)[0], yS.at<Vec2f>(y, x)[1]);

                complex<float> xb(xB.at<Vec2f>(y, x)[0], xB.at<Vec2f>(y, x)[1]);
                complex<float> yb(yB.at<Vec2f>(y, x)[0], yB.at<Vec2f>(y, x)[1]);


                // kernel entry in the Fourier space
                complex<float> k = (conj(xs) * xb + conj(ys) * yb) /
                                   (conj(xs) * xs + conj(ys) * ys + we);
                                   // (abs(xs) * abs(xs) + abs(ys) * abs(ys) + we); // equivalent
                
                K.at<Vec2f>(y, x) = { real(k), imag(k) };
            }
        }

        // only use the real part of the complex output
        Mat kernelBig;
        dft(K, kernelBig, DFT_INVERSE | DFT_REAL_OUTPUT);

        // FIXME: find kernel inside image (kind of bounding box) instead of force user to
        // approximate a correct kernel-width (otherwise some information are lost)

        // cut of kernel in middle of the temporary kernel
        int x = kernelBig.cols / 2 - kernel.cols / 2;
        int y = kernelBig.rows / 2 - kernel.rows / 2;
        swapQuadrants(kernelBig);
        Mat kernelROI = kernelBig(Rect(x, y, kernel.cols, kernel.rows));

        // copy the ROI to the kernel to avoid that some OpenCV functions accidently
        // uses the information outside of the ROI (like copyMakeBorder())
        kernelROI.copyTo(kernel);

        // threshold kernel to erease negative values
        threshold(kernel, kernel, 0.0, -1, THRESH_TOZERO);

        // // kernel has to be energy preserving
        // // this means: sum(kernel) = 1
        kernel /= sum(kernel)[0];
    }