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; } } } }
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(); }
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); }
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); }
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; }