Beispiel #1
0
tensor2D eigenVectors(const tensor2D& t)
{
    vector2D evals(eigenValues(t));

    tensor2D evs
    (
        eigenVector(t, evals.x()),
        eigenVector(t, evals.y())
    );

    return evs;
}
Beispiel #2
0
tensor eigenVectors(const symmTensor& t)
{
    vector evals(eigenValues(t));

    tensor evs
    (
        eigenVector(t, evals.x()),
        eigenVector(t, evals.y()),
        eigenVector(t, evals.z())
    );

    return evs;
}
    TqrEigenDecomposition::TqrEigenDecomposition(const Array& diag,
                                                 const Array& sub,
                                                 EigenVectorCalculation calc,
                                                 ShiftStrategy strategy)
    : iter_(0), d_(diag),
      ev_((calc == WithEigenVector)? d_.size() :
          (calc == WithoutEigenVector)? 0 : 1, d_.size(), 0)
    {
        Size n = diag.size();

        QL_REQUIRE(n == sub.size()+1, "Wrong dimensions");

        Array e(n, 0.0);
        std::copy(sub.begin(),sub.end(),e.begin()+1);
        Size i;
        for (i=0; i < ev_.rows(); ++i) {
            ev_[i][i] = 1.0;
        }

        for (Size k=n-1; k >=1; --k) {
            while (!offDiagIsZero(k, e)) {
                Size l = k;
                while (--l > 0 && !offDiagIsZero(l,e));
                iter_++;

                Real q = d_[l];
                if (strategy != NoShift) {
                    // calculated eigenvalue of 2x2 sub matrix of
                    // [ d_[k-1] e_[k] ]
                    // [  e_[k]  d_[k] ]
                    // which is closer to d_[k+1].
                    // FLOATING_POINT_EXCEPTION
                    const Real t1 = std::sqrt(
                                          0.25*(d_[k]*d_[k] + d_[k-1]*d_[k-1])
                                          - 0.5*d_[k-1]*d_[k] + e[k]*e[k]);
                    const Real t2 = 0.5*(d_[k]+d_[k-1]);

                    const Real lambda =
                        (std::fabs(t2+t1 - d_[k]) < std::fabs(t2-t1 - d_[k]))?
                        t2+t1 : t2-t1;

                    if (strategy == CloseEigenValue) {
                        q-=lambda;
                    } else {
                        q-=((k==n-1)? 1.25 : 1.0)*lambda;
                    }
                }

                // the QR transformation
                Real sine = 1.0;
                Real cosine = 1.0;
                Real u = 0.0;

                bool recoverUnderflow = false;
                for (Size i=l+1; i <= k && !recoverUnderflow; ++i) {
                    const Real h = cosine*e[i];
                    const Real p = sine*e[i];

                    e[i-1] = std::sqrt(p*p+q*q);
                    if (e[i-1] != 0.0) {
                        sine = p/e[i-1];
                        cosine = q/e[i-1];

                        const Real g = d_[i-1]-u;
                        const Real t = (d_[i]-g)*sine+2*cosine*h;

                        u = sine*t;
                        d_[i-1] = g + u;
                        q = cosine*t - h;

                        for (Size j=0; j < ev_.rows(); ++j) {
                            const Real tmp = ev_[j][i-1];
                            ev_[j][i-1] = sine*ev_[j][i] + cosine*tmp;
                            ev_[j][i] = cosine*ev_[j][i] - sine*tmp;
                        }
                    } else {
                        // recover from underflow
                        d_[i-1] -= u;
                        e[l] = 0.0;
                        recoverUnderflow = true;
                    }
                }

                if (!recoverUnderflow) {
                    d_[k] -= u;
                    e[k] = q;
                    e[l] = 0.0;
                }
            }
        }

        // sort (eigenvalues, eigenvectors),
        // code taken from symmetricSchureDecomposition.cpp
        std::vector<std::pair<Real, std::vector<Real> > > temp(n);
        std::vector<Real> eigenVector(ev_.rows());
        for (i=0; i<n; i++) {
            if (ev_.rows() > 0)
                std::copy(ev_.column_begin(i),
                          ev_.column_end(i), eigenVector.begin());
            temp[i] = std::make_pair(d_[i], eigenVector);
        }
        std::sort(temp.begin(), temp.end(),
                  std::greater<std::pair<Real, std::vector<Real> > >());
        // first element is positive
        for (i=0; i<n; i++) {
            d_[i] = temp[i].first;
            Real sign = 1.0;
            if (ev_.rows() > 0 && temp[i].second[0]<0.0)
                sign = -1.0;
            for (Size j=0; j<ev_.rows(); ++j) {
                ev_[j][i] = sign * temp[i].second[j];
            }
        }
    }
Beispiel #4
0
void CVDataFilter::Paint(CVPipeline * pipe)
{
	if (returnType == CVReturnType::QUADS)
	{
		// Draw quads.
		if (!pipe->quads.Size())
			return;
		// Copy original input
		pipe->initialInput.copyTo(pipe->output);
		// Convert to color if needed.
		int channelsBefore = pipe->output.channels();
		if (channelsBefore == 1)
		{
		//	pipe->output.convertTo(pipe->output, CV_8UC3);
			cv::cvtColor(pipe->output, pipe->output, CV_GRAY2RGB);
		}
		int channelsAfter = pipe->output.channels();
		// o.o Paste!
		for (int i = 0; i < pipe->quads.Size(); ++i)
		{
			Quad quad = pipe->quads[i];
	#define RGB(r,g,b) cv::Scalar(b,g,r)
			rng = cv::RNG(1344);
			cv::Scalar color = RGB(rng.uniform(0, 255),rng.uniform(0, 255),rng.uniform(0, 255));
		//	cv::Mat rectImage = cv::Mat::zeros(pipe->output.size(), CV_8UC3);
			cv::rectangle(pipe->output, cv::Point(quad.point1.x, quad.point1.y), cv::Point(quad.point3.x, quad.point3.y), color, CV_FILLED);
			float alpha = 0.2f;
			float beta = 1 - alpha;
		//	cv::addWeighted(rectImage, alpha, pipe->output, beta, 0.0, pipe->output); 
		//	rectImage.copyTo(pipe->output);		
		}
	}
	else if (returnType == CVReturnType::APPROXIMATED_POLYGONS)
	{
		// Copy original input..
		pipe->initialInput.copyTo(pipe->output);
		RenderPolygons(pipe);
	}
	else if (returnType == CVReturnType::CV_IMAGE)
	{
		// Do nothing as the image should already be in the ouput matrix of the pipeline.
	}
	else if (returnType == CVReturnType::LINES ||
		returnType == CVReturnType::CV_LINES)
	{
		// Convert the color to colors again for visualization...
		pipe->initialInput.copyTo(pipe->output);
		for( size_t i = 0; i < pipe->lines.Size(); i++ )
		{
			Line & line = pipe->lines[i];
			// Multiply the line coordinates with the last used inverted scale.
			line.start *= pipe->currentScaleInv;
			line.stop *= pipe->currentScaleInv;

			cv::line( pipe->output, cv::Point(line.start.x, line.start.y),
				cv::Point(line.stop.x, line.stop.y), cv::Scalar(0,0,255), 3, 8 );
		}
	}
	else if (returnType == CVReturnType::CV_CONTOURS)
	{
		pipe->initialInput.copyTo(pipe->output);
		RenderContours(pipe);
	}

	switch(returnType)
	{
		case CVReturnType::CV_CONTOUR_SEGMENTS:
		{
			// Render shit!
			pipe->initialInput.copyTo(pipe->output);
			RenderContourSegments(pipe);
			break;
		}
	}

	if (returnType == CVReturnType::CV_CONTOUR_ELLIPSES)
	{
		pipe->initialInput.copyTo(pipe->output);
		RenderContours(pipe);
		RenderContourBounds(pipe);
	}
	else if (returnType == CVReturnType::CV_CONVEX_HULLS)
	{
		pipe->initialInput.copyTo(pipe->output);
		RenderContours(pipe);
		RenderConvexHulls(pipe);
	}
	else if (returnType == CVReturnType::CV_CONVEXITY_DEFECTS)
	{
		pipe->initialInput.copyTo(pipe->output);
		RenderContours(pipe);
		RenderConvexHulls(pipe);
		RenderConvexityDefects(pipe);
	}
	else if (returnType == CVReturnType::HANDS)
	{
		// Convert image to RGB for easier display
		int channelsBefore = pipe->initialInput.channels();
	//	cv::cvtColor(*pipe->initialInput, pipe->output, CV_GRAY2RGB);
		pipe->initialInput.copyTo(pipe->output);
		int channelsAfter = pipe->output.channels();
		// Check if we got contour-segments, if so prioritize them.
		RenderHands(pipe);
	}
	else if (returnType == CVReturnType::FINGER_STATES)
	{
		// Render the last known one.
		pipe->initialInput.copyTo(pipe->output);
		FingerState & state = pipe->fingerStates.Last();
		cv::Scalar color(255,0,0,255);
		for (int i = 0; i < state.positions.Size(); ++i)
		{
			Vector3f pos = state.positions[i];
			cv::circle(pipe->output, cv::Point(pos.x, pos.y), 5, color, 3);
		}
	}
	else if (returnType == CVReturnType::POINT_CLOUDS)
	{
		pipe->initialInput.copyTo(pipe->output);
		for (int i = 0; i < pipe->pointClouds.Size(); ++i)
		{
			int r,g,b,a;
			r = g = b = a = 255;
			if (i % 2 == 0)
				g = 0;
			if (i % 4 == 0)
				b = 0;
			cv::Scalar color(r,g,b,a);
			
			CVPointCloud & pc = pipe->pointClouds[i];
			for (int j = 0; j < pc.points.Size(); ++j)
			{
				Vector2f & pos = pc.points[j];
				cv::circle(pipe->output, cv::Point(pos.x, pos.y), 2, color, 3);
			}

			/// Render PCA data if applicable.
			for (int j = 0; j < pc.eigenVectors.Size(); ++j)
			{
				cv::Scalar color = j == 0? CV_RGB(255, 255, 0) : CV_RGB(0, 255, 255);
				cv::Point2f eigenVector(pc.eigenVectors[j].x, pc.eigenVectors[j].y);
				float eigenValue = pc.eigenValues[j];

				cv::Point2f scaledEigenVector = eigenVector * eigenValue * 0.02;

				cv::Point2f pcaCenter(pc.pcaCenter.x, pc.pcaCenter.y);
				circle(pipe->output, pcaCenter, 3, CV_RGB(255, 0, 255), 2);
				line(pipe->output, pcaCenter, pcaCenter + scaledEigenVector, color);
			}
		}
	}
	else if (returnType == CVReturnType::CV_OPTICAL_FLOW)
	{
		// http://stackoverflow.com/questions/7693561/opencv-displaying-a-2-channel-image-optical-flow
		// Split the coordinates.
		/*
		cv::Mat xy[2];
		cv::split(pipe->opticalFlow, xy);

		cv::Mat magnitude, angle;

		// Fetch matrix from pipeline.
		cv::cartToPolar(xy[0], xy[1], magnitude, angle, true);

		double magMax;
		cv::minMaxLoc(magnitude, 0, &magMax);
		magnitude.convertTo(magnitude, -1, 1.0 / magMax);
		
		// Build HSV image?
		cv::Mat hsvChannels[3], hsv;
		hsvChannels[0] = angle;
		hsvChannels[1] = cv::Mat::ones(angle.size(), CV_32F);
		hsvChannels[2] = magnitude;
		cv::merge(hsvChannels, 3, hsv);

		// Convert to rgb and send to output.
		cv::cvtColor(hsv, pipe->output, cv::COLOR_HSV2RGB);
		*/
	}
	else if (returnType == CVReturnType::NOTHING)
	{
		// Nothing to render...
	}
	else if (returnType == -1)
	{
		// Nothing to render if error.
		std::cout<<"\nreturnType variable in filter "<<name<<" not set!";
	}
	else if (returnType == CVReturnType::RENDER)
		// Nothing to render if render.
		;
	else
		; // std::cout<<"\nCVDataFilter::Paint called. Forgot to subclass the paint-method?";
}
Beispiel #5
0
PCA&
PCA::fit( const std::vector< std::vector< double > >& data )
{
    const size_t nSamples = data.size();
    const size_t nFeatures = data.front().size();
    
    // Calculate the means vector
    arma::mat meansVector( nFeatures, 1 );
    for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) {
        double sx = 0;
        for ( size_t iSample = 0; iSample < nSamples; ++iSample ) {
            const double value = data[iSample][iFeature];
            if ( std::isnan(value) )
                throw std::runtime_error( "PCA::fit : nan value encountered at input!" );
            sx += value;
        }
        meansVector(iFeature, 0) = sx / nSamples;
    }
    
    // Construct the covariance matrix from the scatter matrix
    arma::mat covMatrix( nFeatures, nFeatures, arma::fill::zeros );
    for ( size_t iSample = 0; iSample < nSamples; ++iSample ) {
        arma::mat sampleData( data[iSample ] );
        arma::mat d = sampleData - meansVector;
        covMatrix += d * d.t();
    }
    covMatrix /= nSamples;
    
    // Now find the eigenvalues and eigenvectors
    arma::cx_vec eigval;
    arma::cx_mat eigvec;
    bool result = arma::eig_gen(eigval, eigvec, covMatrix );
    if (! result ) {
        throw std::runtime_error("PCA::fit : eigenvalue decomposition failed!");
    }
    
    // Normalise the eigenvalues
    m_eigPairs.clear();
    m_eigPairs.reserve( nFeatures );
    double eigSum = 0;
    for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) {
        const double eigMagnitude = std::abs( eigval(iFeature) );

        arma::cx_vec eigenVectorFromCalculation = eigvec.row( iFeature );
        std::vector<double> eigenVector( nFeatures, 0.0 );
        for (size_t j = 0; j < nFeatures; ++j ) eigenVector[j] = eigenVectorFromCalculation(j).real();
        
        m_eigPairs.push_back( std::make_pair( eigMagnitude,
                                             eigenVector ) );
        eigSum += eigMagnitude;
    }
    
    for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) {
        m_eigPairs[iFeature].first /= eigSum;
    }
    
    // Sort the eigenValues
    std::sort( m_eigPairs.begin(), m_eigPairs.end(),
              [] (const std::pair<double, std::vector<double> >&a,
                  const std::pair<double, std::vector<double> >&b ) { return a.first > b.first; } );
    
    return *this;
}
    SymmetricSchurDecomposition::SymmetricSchurDecomposition(const Matrix & s)
    : diagonal_(s.rows()), eigenVectors_(s.rows(), s.columns(), 0.0) {

        QL_REQUIRE(s.rows() > 0 && s.columns() > 0, "null matrix given");
        QL_REQUIRE(s.rows()==s.columns(), "input matrix must be square");

        Size size = s.rows();
        for (Size q=0; q<size; q++) {
            diagonal_[q] = s[q][q];
            eigenVectors_[q][q] = 1.0;
        }
        Matrix ss = s;

        std::vector<Real> tmpDiag(diagonal_.begin(), diagonal_.end());
        std::vector<Real> tmpAccumulate(size, 0.0);
        Real threshold, epsPrec = 1e-15;
        bool keeplooping = true;
        Size maxIterations = 100, ite = 1;
        do {
            //main loop
            Real sum = 0;
            for (Size a=0; a<size-1; a++) {
                for (Size b=a+1; b<size; b++) {
                    sum += std::fabs(ss[a][b]);
                }
            }

            if (sum==0) {
                keeplooping = false;
            } else {
                /* To speed up computation a threshold is introduced to
                   make sure it is worthy to perform the Jacobi rotation
                */
                if (ite<5) threshold = 0.2*sum/(size*size);
                else       threshold = 0.0;

                Size j, k, l;
                for (j=0; j<size-1; j++) {
                    for (k=j+1; k<size; k++) {
                        Real sine, rho, cosin, heig, tang, beta;
                        Real smll = std::fabs(ss[j][k]);
                        if(ite> 5 &&
                           smll<epsPrec*std::fabs(diagonal_[j]) &&
                           smll<epsPrec*std::fabs(diagonal_[k])) {
                                ss[j][k] = 0;
                        } else if (std::fabs(ss[j][k])>threshold) {
                            heig = diagonal_[k]-diagonal_[j];
                            if (smll<epsPrec*std::fabs(heig)) {
                                tang = ss[j][k]/heig;
                            } else {
                                beta = 0.5*heig/ss[j][k];
                                tang = 1.0/(std::fabs(beta)+
                                    std::sqrt(1+beta*beta));
                                if (beta<0)
                                    tang = -tang;
                            }
                            cosin = 1/std::sqrt(1+tang*tang);
                            sine = tang*cosin;
                            rho = sine/(1+cosin);
                            heig = tang*ss[j][k];
                            tmpAccumulate[j] -= heig;
                            tmpAccumulate[k] += heig;
                            diagonal_[j] -= heig;
                            diagonal_[k] += heig;
                            ss[j][k] = 0.0;
                            for (l=0; l+1<=j; l++)
                                jacobiRotate_(ss, rho, sine, l, j, l, k);
                            for (l=j+1; l<=k-1; l++)
                                jacobiRotate_(ss, rho, sine, j, l, l, k);
                            for (l=k+1; l<size; l++)
                                jacobiRotate_(ss, rho, sine, j, l, k, l);
                            for (l=0;   l<size; l++)
                                jacobiRotate_(eigenVectors_,
                                                  rho, sine, l, j, l, k);
                        }
                    }
                }
                for (k=0; k<size; k++) {
                    tmpDiag[k] += tmpAccumulate[k];
                    diagonal_[k] = tmpDiag[k];
                    tmpAccumulate[k] = 0.0;
                }
            }
        } while (++ite<=maxIterations && keeplooping);

        QL_ENSURE(ite<=maxIterations,
                  "Too many iterations (" << maxIterations << ") reached");


        // sort (eigenvalues, eigenvectors)
        std::vector<std::pair<Real, std::vector<Real> > > temp(size);
        std::vector<Real> eigenVector(size);
        Size row, col;
        for (col=0; col<size; col++) {
            std::copy(eigenVectors_.column_begin(col),
                      eigenVectors_.column_end(col), eigenVector.begin());
            temp[col] = std::make_pair(diagonal_[col], eigenVector);
        }
        std::sort(temp.begin(), temp.end(),
            std::greater<std::pair<Real, std::vector<Real> > >());
        Real maxEv = temp[0].first;
        for (col=0; col<size; col++) {
            // check for round-off errors
            diagonal_[col] =
                (std::fabs(temp[col].first/maxEv)<1e-16 ? 0.0 :
                                                          temp[col].first);
            Real sign = 1.0;
            if (temp[col].second[0]<0.0)
                sign = -1.0;
            for (row=0; row<size; row++) {
                eigenVectors_[row][col] = sign * temp[col].second[row];
            }
        }
    }