Пример #1
0
void RPCA::fit(const cv::Mat1f & descr)
{
    // make data zero mean
    cv::reduce(descr, mean, 0, CV_REDUCE_AVG);
    cv::Mat1f X(descr.rows, descr.cols);

#ifdef USE_TBB
    tbb::parallel_for(int32_t(0), X.rows, [&](int32_t y) {
        X.row(y) = descr.row(y) - mean;
    }
    );
#else
    for( int32_t y = 0; y < X.rows; y++){
        X.row(y) = descr.row(y) - mean;
    }
#endif

    cv::Mat1f U, S, V;
    cv::SVD::compute(X, S, U, V);
    cv::pow(S, 2, variance);
    variance /= X.rows;
    if (n_components <= 0) {
        n_components = X.cols;
    }

    components = V.rowRange(0, n_components);
    if(variance.rows < n_components) {
        whiten = false;
    } else {
        variance = variance.rowRange(0, n_components);
    }

    this->dataLoaded = true;
}
Пример #2
0
void RPCA::transform(const cv::Mat1f & descr,
                     cv::Mat1f & out) const
{
    if(descr.cols != mean.cols) {
        std::stringstream s;
        s << "Input and mean data missmatch." << std::endl;
        s << "Input: " << descr.size() << " Mean: " << mean.size() << std::endl;
        throw pl::DimensionalityReductionError(s.str(), currentMethod, currentLine);
    } else if(descr.cols != components.cols) {
        std::stringstream s;
        s << "Input and transformation data missmatch." << std::endl;
        s << "Input: " << descr.size() << " Transform: " << components.size() << std::endl;
        throw pl::DimensionalityReductionError(s.str(), currentMethod, currentLine);
    }
    // make data zero-mean
    cv::Mat1f X(descr.rows,descr.cols);
#ifdef USE_TBB
        tbb::parallel_for(int32_t(0), X.rows, [&](int32_t i) {
            X.row(i) = descr.row(i) - mean;
        }
        );
#else
    for( int32_t y = 0; y < X.rows; y++){
        X.row(y) = descr.row(y) - mean;
    }
#endif
    // the actual transformation
    X = X * components.t();

    // whiten the data
    if ( whiten ) {
        cv::Mat1f var_reg = variance.clone();
        var_reg = var_reg.reshape(1, 1);
        if ( reg > 0.0 )
            var_reg += reg;
        cv::sqrt(var_reg, var_reg);
#ifdef USE_TBB
        tbb::parallel_for(int32_t(0), X.rows, [&](int32_t i) {
            cv::Mat1f row = X.row(i);
            row /= var_reg;
        }
        );
#else
        for( int32_t i = 0; i < X.rows; i++ ) {
            cv::Mat1f row = X.row(i);
            row /= var_reg;
        }
#endif
    }
    out = X;
}