Esempio n. 1
0
void drwnLBPFilterBank::regionFeatures(const drwnSuperpixelContainer& regions, 
    const std::vector<cv::Mat>& response, vector<vector<double> >& features)
{
    DRWN_ASSERT(!response.empty() && (response[0].rows == regions.height()) &&
        (response[0].cols == regions.width()));

    cv::Mat codewords = response[0].clone();
    float multiplier = 2.0;
    for (unsigned i = 1; i < response.size(); i++) {
        codewords += multiplier * response[i];
        multiplier *= 2.0f;
    }

    // accumulate histograms
    features.clear();
    features.resize(regions.size(), vector<double>((int)multiplier, 0.0));

    for (int c = 0; c < regions.channels(); c++) {
        for (int y = 0; y < regions.height(); y++) {
            const int *segId = regions[c].ptr<int>(y);
            const float *p = codewords.ptr<const float>(y);
            for (int x = 0; x < regions.width(); x++) {
                if (segId[x] < 0) continue;
                features[segId[x]][(int)p[x]] += 1.0;
            }
        }
    }
    
    // normalize histograms
    for (unsigned segId = 0; segId < features.size(); segId++) {
        double Z = 0.0;
        for (unsigned i = 0; i < features[segId].size(); i++) {
            Z += features[segId][i];
        }
        if (Z > 0.0) {
            for (unsigned i = 0; i < features[segId].size(); i++) {
                features[segId][i] /= Z;
            }
        }
    }
}
Esempio n. 2
0
void drwnOptionsEditor::onDClick(wxGridEvent& event)
{
    unsigned indx = (unsigned)event.GetRow();
    DRWN_ASSERT(indx < _copy.numProperties());

    bool bReadOnly = _copy.isReadOnly(indx);
    if (_copy.getPropertyType(indx) == DRWN_MATRIX_PROPERTY) {
        drwnMatrixEditor dlg(this, &_copy.getMatrixProperty(indx), bReadOnly);
        if ((dlg.ShowModal() == wxID_OK) && !bReadOnly) {
            Eigen::MatrixXd m = dlg.getMatrix();
            _copy.setProperty(indx, m);
            _grid->SetCellValue(indx, 0, _copy.getPropertyAsString(indx));
        }
    } else if (_copy.getPropertyType(indx) == DRWN_VECTOR_PROPERTY) {
        drwnMatrixEditor dlg(this, &_copy.getVectorProperty(indx), bReadOnly);
        if ((dlg.ShowModal() == wxID_OK) && !bReadOnly) {
            Eigen::VectorXd v = dlg.getCol();
            _copy.setProperty(indx, v);
            _grid->SetCellValue(indx, 0, _copy.getPropertyAsString(indx));
        }
    } else if (_copy.getPropertyType(indx) == DRWN_FILENAME_PROPERTY) {
        wxFileDialog dlg(this, string("Choose a file for ") + _copy.getPropertyName(indx),
            "", _grid->GetCellValue(indx, 0), "*.*", wxFD_OPEN);
        if (dlg.ShowModal() == wxID_OK) {
            _grid->SetCellValue(indx, 0, dlg.GetPath());
        }
    } else if (_copy.getPropertyType(indx) == DRWN_DIRECTORY_PROPERTY) {
        wxDirDialog dlg(this, string("Choose a directory for ") + _copy.getPropertyName(indx),
            _grid->GetCellValue(indx, 0), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
        if (dlg.ShowModal() == wxID_OK) {
            _grid->SetCellValue(indx, 0, dlg.GetPath());
        }
    }

    event.Skip();    
}
Esempio n. 3
0
drwnMatrixEditor::drwnMatrixEditor(wxWindow *parent, const Eigen::MatrixXd *m, bool bFixed) :
    wxDialog(parent, wxID_ANY, "Matrix Editor", wxDefaultPosition,wxDefaultSize,
        wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW),
    _fixedRows(bFixed), _fixedCols(bFixed), _grid(NULL), _text(NULL)
{
    DRWN_ASSERT(m != NULL);
    wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
    mainSizer->SetMinSize(wxSize(120, 160));
    wxBoxSizer *buttons;

    // add rows and column button
    if (!bFixed) {
        buttons = new wxBoxSizer(wxHORIZONTAL);
        buttons->Add(new wxStaticText(this, wxID_ANY, "&rows"), 0, wxALL, 10);
        buttons->Add(new wxSpinCtrl(this, ROWS_SPIN_CTRL,
            toString(m->rows()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1024), 0, wxALL, 10);
        buttons->Add(new wxStaticText(this, wxID_ANY, "&cols"), 0, wxALL, 10);
        buttons->Add(new wxSpinCtrl(this, COLS_SPIN_CTRL,
            toString(m->cols()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1024), 0, wxALL, 10);
        buttons->Add(new wxToggleButton(this, EDIT_TEXT_MODE, "&Text Mode"), 0, wxALL, 10);
        mainSizer->Add(buttons, 0, wxALIGN_RIGHT);
    }

    // add grid input
    _grid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
        wxEXPAND | wxWANTS_CHARS);

    _grid->CreateGrid(m->rows(), m->cols());
    for (int i = 0; i < m->rows(); i++) {
        for (int j = 0; j < m->cols(); j++) {
            _grid->SetCellValue(i, j, toString((*m)(i, j)));

            // color cell
            _grid->SetCellBackgroundColour(i, j, 
                wxColour(0xff, (i % 2 == 0) ? 0xff : 0xe0, (j % 2 == 0) ? 0xff : 0xe0));
        }
    }

    mainSizer->Add(_grid, 1, wxEXPAND | wxALL, 10);

    // add text input
    _text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize,
        wxEXPAND | wxWANTS_CHARS | wxTE_DONTWRAP | wxTE_MULTILINE | wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB);
    _text->Show(false);
    mainSizer->Add(_text, 1, wxEXPAND | wxALL, 10);

    // TODO: change to CreateButtonSizer?
    buttons = new wxBoxSizer(wxHORIZONTAL);
#if 0
    // TODO: wxWidgets version problem?
    buttons->Add(new wxButton(this, wxID_OK, "OK"),
        wxSizerFlags(0).Align().Border(wxALL, 10));
    buttons->Add(new wxButton( this, wxID_CANCEL, "Cancel" ),
        wxSizerFlags(0).Align().Border(wxALL, 10));
#else
    buttons->Add(new wxButton(this, wxID_OK, "OK"), 0, wxALL, 10);
    buttons->Add(new wxButton(this, wxID_CANCEL, "Cancel"), 0, wxALL, 10);
#endif

    mainSizer->Add(buttons, 0, wxALIGN_CENTER);

    // implement the sizer
    SetSizer(mainSizer);
    mainSizer->SetSizeHints(this);
}
Esempio n. 4
0
void drwnTextonFilterBank::filter(const cv::Mat& img, std::vector<cv::Mat>& response) const
{
    // check input
    DRWN_ASSERT(img.data != NULL);
    if (response.empty()) {
        response.resize(NUM_FILTERS);
    }
    DRWN_ASSERT((int)response.size() == NUM_FILTERS);
    DRWN_ASSERT((img.channels() == 3) && (img.depth() == CV_8U));
    for (int i = 0; i < NUM_FILTERS; i++) {
        if ((response[i].rows != img.rows) || (response[i].cols != img.cols)) {
            response[i] = cv::Mat(img.rows, img.cols, CV_32FC1);
	}
        DRWN_ASSERT((response[i].channels() == 1) && (response[i].depth() == CV_32F));
    }

    int k = 0;

    // color convert
    DRWN_LOG_DEBUG("Color converting image...");
    cv::Mat imgCIELab8U(img.rows, img.cols, CV_8UC3);
    cv::cvtColor(img, imgCIELab8U, CV_BGR2Lab);
    cv::Mat imgCIELab(img.rows, img.cols, CV_32FC3);
    imgCIELab8U.convertTo(imgCIELab, CV_32F, 1.0 / 255.0);

    cv::Mat greyImg(img.rows, img.cols, CV_32FC1);
    const int from_to[] = {0, 0};
    cv::mixChannels(&imgCIELab, 1, &greyImg, 1, from_to, 1);

    // gaussian filter on all color channels
    DRWN_LOG_DEBUG("Generating gaussian filter responses...");
    cv::Mat gImg32f(img.rows, img.cols, CV_32FC3);
    for (double sigma = 1.0; sigma <= 4.0; sigma *= 2.0) {
        const int h = 2 * (int)(_kappa * sigma) + 1;
        cv::GaussianBlur(imgCIELab, gImg32f, cv::Size(h, h), 0);
        cv::split(gImg32f, &response[k]);
        k += 3;
    }

    // derivatives of gaussians on just greyscale image
    DRWN_LOG_DEBUG("Generating derivative of gaussian filter responses...");
    for (double sigma = 2.0; sigma <= 4.0; sigma *= 2.0) {
        // x-direction
        cv::Sobel(greyImg, response[k++], CV_32F, 1, 0, 1);
        cv::GaussianBlur(response[k - 1], response[k - 1],
            cv::Size(2 * (int)(_kappa * sigma) + 1, 2 * (int)(3.0 * _kappa * sigma) + 1), 0);

        // y-direction
        cv::Sobel(greyImg, response[k++], CV_32F, 0, 1, 1);
        cv::GaussianBlur(response[k - 1], response[k - 1],
            cv::Size(2 * (int)(3.0 * _kappa * sigma) + 1, 2 * (int)(_kappa * sigma) + 1), 0);
    }

    // laplacian of gaussian on just greyscale image
    DRWN_LOG_DEBUG("Generating laplacian of gaussian filter responses...");
    cv::Mat tmpImg(img.rows, img.cols, CV_32FC1);
    for (double sigma = 1.0; sigma <= 8.0; sigma *= 2.0) {
        const int h = 2 * (int)(_kappa * sigma) + 1;
        cv::GaussianBlur(greyImg, tmpImg, cv::Size(h, h), 0);
        cv::Laplacian(tmpImg, response[k++], CV_32F, 3);
    }

    DRWN_ASSERT_MSG(k == NUM_FILTERS, k << " != " << NUM_FILTERS);
}
Esempio n. 5
0
double drwnAlphaExpansionInference::inference(drwnFullAssignment& mapAssignment)
{
    // check factor graph is pairwise
    for (int i = 0; i < _graph.numFactors(); i++) {
        DRWN_ASSERT(_graph[i]->size() <= 2);
    }

    // initialize MAP assignment
    const drwnVarUniversePtr pUniverse(_graph.getUniverse());
    const int nVariables = pUniverse->numVariables();
    mapAssignment.resize(nVariables, 0);
    double bestEnergy = _graph.getEnergy(mapAssignment);
    const int maxAlpha = pUniverse->maxCardinality();
    if (maxAlpha == 1) return bestEnergy;

    drwnFullAssignment assignment(mapAssignment);

    drwnMaxFlow *g = new drwnBKMaxFlow(nVariables);
    g->addNodes(nVariables);

    // iterate until convergence
    bool bChanged = true;
    int lastChanged = -1;
    int nonSubmodularMoves = 0;
    for (int nCycle = 0; bChanged; nCycle += 1) {
        bChanged = false;
        for (int alpha = 0; alpha < maxAlpha; alpha++) {
            if (alpha == lastChanged)
                break;

            // construct graph
            bool bNonSubmodularMove = false;
            g->reset();
            for (int i = 0; i < _graph.numFactors(); i++) {
                const drwnTableFactor *phi = _graph[i];
                if (phi->size() == 1) {
                    // unary
                    const int u = phi->varId(0);
                    const double A = (*phi)[mapAssignment[u]];
                    const double B = (*phi)[alpha % pUniverse->varCardinality(u)];
                    g->addSourceEdge(u, A);
                    g->addTargetEdge(u, B);
                } else if (phi->size() == 2) {
                    // pairwise
                    const int u = phi->varId(0);
                    const int v = phi->varId(1);

                    const int uAlpha = alpha % pUniverse->varCardinality(u);
                    const int vAlpha = alpha % pUniverse->varCardinality(v);

                    if ((uAlpha == mapAssignment[u]) && (vAlpha == mapAssignment[v]))
                        continue;

                    double A = (*phi)[phi->indexOf(v, mapAssignment[v], phi->indexOf(u, mapAssignment[u]))];
                    double B = (*phi)[phi->indexOf(v, vAlpha, phi->indexOf(u, mapAssignment[u]))];
                    double C = (*phi)[phi->indexOf(v, mapAssignment[v], phi->indexOf(u, uAlpha))];
                    double D = (*phi)[phi->indexOf(v, vAlpha, phi->indexOf(u, uAlpha))];

                    if (uAlpha == mapAssignment[u]) {
                        g->addSourceEdge(v, A);
                        g->addTargetEdge(v, B);
                    } else if (vAlpha == mapAssignment[v]) {
                        g->addSourceEdge(u, A);
                        g->addTargetEdge(u, C);
                    } else {
                        // check for submodularity
                        if (A + D > C + B) {
                            // truncate non-submodular functions
                            bNonSubmodularMove = true;
                            const double delta = A + D - C - B;
                            A -= delta / 3 - DRWN_EPSILON;
                            C += delta / 3 + DRWN_EPSILON;
                            B = A + D - C + DRWN_EPSILON;
                        }

                        g->addSourceEdge(u, A);
                        g->addTargetEdge(u, D);

                        B -= A; C -= D; B += DRWN_EPSILON; C += DRWN_EPSILON;
                        DRWN_ASSERT_MSG(B + C >= 0, "B = " << B << ", C = " << C);
                        if (B < 0) {
                            g->addTargetEdge(v, B);
                            g->addTargetEdge(u, -B);
                            g->addEdge(v, u, 0.0, B + C);
                        } else if (C < 0) {
                            g->addTargetEdge(v, -C);
                            g->addTargetEdge(u, C);
                            g->addEdge(v, u, B + C, 0.0);
                        } else {
                            g->addEdge(v, u, B, C);
                        }
                    }
                }
            }

            // run inference
            if (bNonSubmodularMove) {
                nonSubmodularMoves += 1;
            }

            g->solve();
            for (int i = 0; i < nVariables; i++) {
                assignment[i] = (g->inSetS(i) ? alpha % pUniverse->varCardinality(i) : mapAssignment[i]);
            }
            double e = _graph.getEnergy(assignment);

            DRWN_LOG_DEBUG("...cycle " << nCycle << ", iteration " << alpha << " has energy " << e);
            if (e < bestEnergy) {
                bestEnergy = e;
                mapAssignment = assignment;
                lastChanged = alpha;
                bChanged = true;
            }
        }
    }

    // free graph
    delete g;

    DRWN_LOG_DEBUG("..." << nonSubmodularMoves << " non-submodular moves");
    return bestEnergy;
}