Revision: 3211
http://hugin.svn.sourceforge.net/hugin/?rev=3211&view=rev
Author: fmannan
Date: 2008-07-20 01:24:33 +0000 (Sun, 20 Jul 2008)
Log Message:
-----------
+LazySnapping fixed but needs improvement
+minor UI update
Modified Paths:
--------------
hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.h
hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdClientWnd.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdEditWnd.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.h
hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdPrefDlg.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/data/Thumbs.db
hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_menubar.xrc
hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_toolbar.xrc
hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.cpp
hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.h
hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/maxflow/graph.h
hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/polyed_basic/PolyEd_Basic.cpp
Added Paths:
-----------
hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/data/roi.png
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -87,6 +87,11 @@
return m_segmentation_options;
}
+int MaskMgr::getSegmentationOptionSelected() const
+{
+ return m_segmentation_index;
+}
+
void MaskMgr::loadImage(const string &filename)
{
ImageCache::getInstance().getImage(filename);
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.h
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.h 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/core/MaskMgr.h 2008-07-20 01:24:33 UTC (rev 3211)
@@ -48,6 +48,7 @@
ISegmentation* getSegmentation(int index); //get the segmentation instance used for a particular input image
ISegmentation* getSegmentation(const std::string &filename);
std::vector<std::string> getSegmentationOptions();
+ int getSegmentationOptionSelected() const;
void loadPTOFile(const std::string &filename);
void loadImages(const std::vector<std::string> &filesv);
void loadImage(const std::string &filename);
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdClientWnd.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdClientWnd.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdClientWnd.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -41,10 +41,11 @@
const wxString& name)
: wxSplitterWindow(parent, id, pos, size, style, name)
{
- m_MaskEdEditWnd = new MaskEdEditWnd(this);
- m_MaskEdPreviewWnd = new MaskEdPreviewWnd(this);
+ m_MaskEdEditWnd = new MaskEdEditWnd(this, wxID_ANY, wxDefaultPosition, wxSize(size.GetWidth(), size.GetHeight()*0.75));
+ m_MaskEdPreviewWnd = new MaskEdPreviewWnd(this, wxID_ANY, wxDefaultPosition, wxSize(size.GetWidth(), size.GetHeight()*0.25));
SetMinimumPaneSize(20);
+ //SetSashPosition(size.GetHeight() * 0.75);
m_MaskEdEditWnd->Show();
m_MaskEdPreviewWnd->Show();
SplitHorizontally(m_MaskEdEditWnd, m_MaskEdPreviewWnd);
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdEditWnd.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdEditWnd.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdEditWnd.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -162,11 +162,11 @@
int x,y;
x = GetScrollPos(wxSB_HORIZONTAL);
y = GetScrollPos(wxSB_VERTICAL);
- int i = 0;
+ int i = m_bimgs.size() - 1;
int lastDrawn = -1;
//dc.SetDeviceOrigin(-x, -y);
- //dc.SetUserScale(m_scale, m_scale);
- for(vector<wxBitmap*>::iterator it = m_bimgs.begin(); it != m_bimgs.end(); it++, i++)
+ dc.SetUserScale(m_scale, m_scale);
+ for(vector<wxBitmap*>::reverse_iterator it = m_bimgs.rbegin(); it != m_bimgs.rend(); it++, i--)
{
if(!m_selected[i]) continue;
dc.DrawBitmap(**it, -x + m_pos[i].x, -y + m_pos[i].y, true);
@@ -227,6 +227,7 @@
{
m_brushstroke.label = ISegmentation::FGND;
m_MaskEdCmdHist.addCommand(new BrushStrokeCmd(MaskMgr::getInstance(), m_brushstroke, m_active));
+ reloadImages();
m_brushstroke.clear();
}
else if(m_edmode == ME_POLY) {
@@ -247,6 +248,7 @@
{
m_brushstroke.label = ISegmentation::BKGND;
m_MaskEdCmdHist.addCommand(new BrushStrokeCmd(MaskMgr::getInstance(), m_brushstroke, m_active));
+ reloadImages();
m_brushstroke.clear();
}
else if(m_edmode == ME_POLY) {
@@ -270,14 +272,16 @@
{
wxClientDC dc(this);
//DoPrepareDC(dc);
+ wxPen oldpen = dc.GetPen();
wxPen *pen;
+
if(event.LeftIsDown())
pen = new wxPen(*wxRED, 1);
else
pen = new wxPen(*wxBLUE, 1);
dc.SetPen(*pen);
dc.DrawLine(m_brushstroke.pt.back() - wxPoint(x, y) + m_pos[m_active], event.GetPosition());
- dc.SetPen(wxNullPen);
+ dc.SetPen(oldpen);
}
m_brushstroke.pt.push_back(event.GetPosition() + wxPoint(x, y) - m_pos[m_active]);
}
@@ -293,7 +297,7 @@
void MaskEdEditWnd::zoom(float scale, wxRect region)
{
m_scale = scale;
- reloadImages();
+ //reloadImages();
//SetScrollbars( 1, 1, m_bimgs[0]->GetWidth()*m_scale, m_bimgs[0]->GetHeight()*m_scale);
Refresh();
}
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -20,7 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-
+#include <vector>
+#include <string>
#include "huginapp/ImageCache.h"
#include "MaskEdApp.h"
#include "MaskEdMainFrame.h"
@@ -29,6 +30,7 @@
#include <wx/filedlg.h>
#include <wx/filename.h>
+using namespace std;
using HuginBase::ImageCache;
BEGIN_EVENT_TABLE(MaskEdMainFrame, wxFrame)
@@ -54,8 +56,12 @@
EVT_BUTTON(XRCID("action_zoom_in"), MaskEdMainFrame::OnZoomIn)
EVT_MENU(XRCID("action_zoom_out"), MaskEdMainFrame::OnZoomOut)
EVT_BUTTON(XRCID("action_zoom_out"), MaskEdMainFrame::OnZoomOut)
+ EVT_MENU(XRCID("action_set_roi"), MaskEdMainFrame::OnSetROI)
+ EVT_BUTTON(XRCID("action_set_roi"), MaskEdMainFrame::OnSetROI)
EVT_MENU(XRCID("action_show_overlap"), MaskEdMainFrame::OnShowOverlap)
EVT_BUTTON(XRCID("action_show_overlap"), MaskEdMainFrame::OnShowOverlap)
+ EVT_COMBOBOX(XRCID("m_comboSegChoice"), MaskEdMainFrame::OnSegSelUpdate)
+ //EVT_SIZE(MaskEdMainFrame::OnSize)
END_EVENT_TABLE()
MaskEdMainFrame::MaskEdMainFrame(wxWindow *parent) : m_scale(1.0)
@@ -65,9 +71,9 @@
wxXmlResource::Get()->LoadFrame(this, parent, wxT("MaskEdMainFrame"));
SetMenuBar(wxXmlResource::Get()->LoadMenuBar(this, wxT("main_menubar")));
+ wxToolBar *tb = wxXmlResource::Get()->LoadToolBar(this, wxT("main_toolbar"));
+ SetToolBar(tb);
- SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("main_toolbar")));
-
#ifdef __WXMSW__
wxIcon appIcon(MaskEdApp::getMaskEdApp()->getXRCPath() + wxT("data/mask_editor_icon_48x48.ico"), wxBITMAP_TYPE_ICO);
#else
@@ -76,15 +82,23 @@
SetIcon(appIcon);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
+ wxSize sz = GetClientSize();
+ m_MaskEdClientWnd = new MaskEdClientWnd(this, wxID_ANY, wxDefaultPosition,sz);
- m_MaskEdClientWnd = new MaskEdClientWnd(this);
-
topSizer->Add(m_MaskEdClientWnd, 1, wxEXPAND | wxALL | wxFIXED_MINSIZE);
SetSizerAndFit(topSizer);
MaskMgr::getInstance()->setSegmentationOption(0);
-
+ wxWindow *pWnd = tb;
+#ifdef __WXMSW__
+ pWnd = this;
+#endif
+ vector<string> options = MaskMgr::getInstance()->getSegmentationOptions();
+ for(vector<string>::iterator it = options.begin(); it != options.end(); it++)
+ XRCCTRL(*pWnd, "m_comboSegChoice", wxComboBox)->Append(wxString(it->c_str(), wxConvUTF8));
+ XRCCTRL(*pWnd, "m_comboSegChoice", wxComboBox)->SetValue(wxString(options[0].c_str(), wxConvUTF8));
+
CreateStatusBar();
SetStatusText(wxT("Ready"));
}
@@ -96,6 +110,13 @@
//delete ImageCache::getInstance();
}
+void MaskEdMainFrame::OnSize(wxSizeEvent &event)
+{
+ wxSize sz = event.GetSize();
+ if(m_MaskEdClientWnd)
+ m_MaskEdClientWnd->SetSashPosition(sz.GetHeight()*0.75);
+}
+
void MaskEdMainFrame::OnNewProject(wxCommandEvent &event)
{
@@ -201,7 +222,22 @@
m_MaskEdClientWnd->zoom(m_scale);
}
+void MaskEdMainFrame::OnSetROI(wxCommandEvent &event)
+{
+
+}
+
void MaskEdMainFrame::OnShowOverlap(wxCommandEvent &event)
{
m_MaskEdClientWnd->toggleShowOverlappedRect();
}
+
+void MaskEdMainFrame::OnSegSelUpdate(wxCommandEvent &event)
+{
+ wxWindow *pWnd = GetToolBar();
+#ifdef __WXMSW__
+ pWnd = this;
+#endif
+ int ichoice = XRCCTRL(*pWnd, "m_comboSegChoice", wxComboBox)->GetSelection();
+ MaskMgr::getInstance()->setSegmentationOption(ichoice);
+}
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.h
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.h 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdMainFrame.h 2008-07-20 01:24:33 UTC (rev 3211)
@@ -53,8 +53,11 @@
void OnAbout(wxCommandEvent& event);
void OnZoomIn(wxCommandEvent& event);
void OnZoomOut(wxCommandEvent& event);
+ void OnSetROI(wxCommandEvent& event);
void OnShowOverlap(wxCommandEvent& event);
+ void OnSegSelUpdate(wxCommandEvent& event);
+ void OnSize(wxSizeEvent& event);
void OnMotion(wxMouseEvent& event);
//void OnPaint(wxPaintEvent& event);
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdPrefDlg.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdPrefDlg.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/MaskEdPrefDlg.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -37,7 +37,8 @@
vector<string> options = MaskMgr::getInstance()->getSegmentationOptions();
for(vector<string>::iterator it = options.begin(); it != options.end(); it++)
XRCCTRL(*this, "m_comboSegChoice", wxComboBox)->Append(wxString(it->c_str(), wxConvUTF8));
- XRCCTRL(*this, "m_comboSegChoice", wxComboBox)->SetValue(wxString(options.front().c_str(), wxConvUTF8));
+ int index = MaskMgr::getInstance()->getSegmentationOptionSelected();
+ XRCCTRL(*this, "m_comboSegChoice", wxComboBox)->SetValue(wxString(options[index].c_str(), wxConvUTF8));
}
MaskEdPrefDlg::~MaskEdPrefDlg() {}
Property changes on: hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/data/roi.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_menubar.xrc
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_menubar.xrc 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_menubar.xrc 2008-07-20 01:24:33 UTC (rev 3211)
@@ -64,6 +64,10 @@
<help>Zoom Out</help>
</object>
<object class="separator" />
+ <object class="wxMenuItem" name="action_set_roi">
+ <label>Set &ROI</label>
+ <help>Set Region of Interest</help>
+ </object>
<object class="wxMenuItem" name="action_show_overlap">
<label>&Show Overlap</label>
<help>Show overlapped region between selected images</help>
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_toolbar.xrc
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_toolbar.xrc 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/gui/xrc/main_toolbar.xrc 2008-07-20 01:24:33 UTC (rev 3211)
@@ -57,11 +57,23 @@
<bitmap>data/poly.png</bitmap>
</object>
<object class="separator" />
+ <object class="tool" name="action_set_roi">
+ <label>tool</label>
+ <tooltip>Set Region of Interest</tooltip>
+ <longhelp></longhelp>
+ <bitmap>data/roi.png</bitmap>
+ </object>
<object class="tool" name="action_show_overlap">
<label>tool</label>
<tooltip>Show overlapped region between selected images</tooltip>
<longhelp></longhelp>
<bitmap>data/rectoverlap.png</bitmap>
</object>
+ <object class="separator" />
+ <object class="wxComboBox" name="m_comboSegChoice">
+ <style>wxCB_DROPDOWN|wxCB_READONLY</style>
+ <value></value>
+ <content />
+ </object>
</object>
</resource>
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -27,13 +27,14 @@
#include "KMlocal/KMlocal.h"
#include "watershed.cxx"
+#define INF 1000000
using namespace std;
using HuginBase::ImageCache;
#define SAFE_DELETE(x) { if(x) delete x; x = 0; }
#define SAFE_DELETE_ARRAY(x) { if(x) delete [] x; x = 0; }
-double SQR(double x) { return x * x; }
+inline double SQR(double x) { return x * x; }
/**
* General utility functions
*/
@@ -46,19 +47,17 @@
return true;
}
/**
- *
+ * LazySnapping Implementation
*/
LazySnapping::LazySnapping()
: m_mask(0), m_data(0), m_nodes(0), m_graph(0), m_lambda(LAMBDA), m_sigma(SIGMA),
-m_nclusters(NCLUSTERS), m_K(-1), m_width(0), m_height(0), m_depth(0), m_cnodes(0),
-m_cluster_asgn(0)
+m_nclusters(NCLUSTERS), m_K(-1), m_width(0), m_height(0), m_depth(0), m_cnodes(0)
{
m_name = "LazySnapping";
}
LazySnapping::LazySnapping(const string &filename)
: m_mask(0), m_data(0), m_nodes(0), m_graph(0), m_lambda(LAMBDA), m_sigma(SIGMA),
-m_nclusters(NCLUSTERS), m_K(-1), m_width(0), m_height(0), m_depth(0), m_cnodes(0),
-m_cluster_asgn(0)
+m_nclusters(NCLUSTERS), m_K(-1), m_width(0), m_height(0), m_depth(0), m_cnodes(0)
{
m_name = "LazySnapping";
setImage(filename);
@@ -73,6 +72,8 @@
if(m_width > 0 && m_height > 0)
{
m_mask = new wxBitmap(m_width, m_height, 1);
+ /*SAFE_DELETE(m_tmp_bmp);
+ m_tmp_bmp = new wxBitmap(m_width, m_height, 1);*/
preprocess();
buildGraph();
wxMemoryDC dc(*m_mask);
@@ -92,7 +93,6 @@
SAFE_DELETE_ARRAY(m_nodes);
SAFE_DELETE(m_graph);
SAFE_DELETE_ARRAY(m_data);
- SAFE_DELETE_ARRAY(m_cluster_asgn);
}
void LazySnapping::getRC(int p, int *r, int *c) const
@@ -101,80 +101,28 @@
*c = p%m_width;
}
+int LazySnapping::getIndex(int r, int c) const
+{
+ return r * m_width + c;
+}
+
void LazySnapping::preprocess()
{
- int i,j;
- //create clusters
m_cnodes = m_width * m_height;
- ClusterCoordType *data = new ClusterCoordType[m_cnodes * CLUSTERCOORDDIM];
- //assert(m_depth == 3);
- //for(i = 0; i < m_cnodes; i++)
- //{
- // *(data + i * CLUSTERCOORDDIM) = (ClusterCoordType) *(m_data + i * m_depth);
- // *(data + i * CLUSTERCOORDDIM + 1) = (ClusterCoordType) *(m_data + i * m_depth + 1);
- // *(data + i * CLUSTERCOORDDIM + 2) = (ClusterCoordType) *(m_data + i * m_depth + 2);
- // //*(data + i * CLUSTERCOORDDIM + 3) = (ClusterCoordType) r;
- // //*(data + i * CLUSTERCOORDDIM + 4) = (ClusterCoordType) c;
- //}
-
- /*KMeans<ClusterCoordType> kmeans(data, m_width * m_height, CLUSTERCOORDDIM, m_nclusters);
- ClusterCoordType *clusters = 0;
- kmeans.doClustering(&clusters, &m_cluster_asgn);
- m_clusters.clear();
- for(i = 0; i < m_nclusters; i++)
- {
- m_clusters.push_back(
- make_pair(
- ClusterCoord<ClusterCoordType,CLUSTERCOORDDIM>((clusters + i * CLUSTERCOORDDIM)),
- NOLABEL)
- );
- }*/
- KMterm term(100, 0, 0, 0, 0.10, 0.10, 3, 0.50, 10, 0.95);
- KMdata dataPts(CLUSTERCOORDDIM, m_cnodes);
- //kmUniformPts(dataPts.getPts(), m_cnodes, CLUSTERCOORDDIM);
- KMpointArray pa = dataPts.getPts();
- //fillup the points
- int r, c;
- for(i = 0; i < m_cnodes; i++)
- {
- pa[i][0] = (KMcoord) *(m_data + i * m_depth);
- pa[i][1] = (KMcoord) *(m_data + i * m_depth + 1);
- pa[i][2] = (KMcoord) *(m_data + i * m_depth + 2);
- getRC(i, &r, &c);
- pa[i][3] = (KMcoord) r;
- pa[i][4] = (KMcoord) c;
- }
- dataPts.buildKcTree();
- KMfilterCenters ctrs(m_nclusters, dataPts);
- KMlocalLloyds kmAlg(ctrs, term);
- ctrs = kmAlg.execute();
- m_cluster_asgn = new int[m_cnodes];
- m_cluster_sqDist = new double[m_cnodes];
- ctrs.getAssignments(m_cluster_asgn, m_cluster_sqDist);
- KMcenterArray pctrs = ctrs.getCtrPts();
- m_clusters.clear();
- for(i = 0; i < m_nclusters; i++)
- {
- m_clusters.push_back(
- make_pair(
- ClusterCoord<ClusterCoordType,CLUSTERCOORDDIM>(pctrs[i]),
- NOLABEL)
- );
- }
}
PixelColor LazySnapping::getPixelValue(int p) const
{
PixelColor color;
- color.r = m_data[p];
- color.g = m_data[p + 1];
- color.b = m_data[p + 2];
+ color.r = *(m_data + p * m_depth);
+ color.g = *(m_data + p * m_depth + 1);
+ color.b = *(m_data + p * m_depth + 2);
return color;
}
PixelColor LazySnapping::getPixelValue(int r, int c) const
{
- return getPixelValue( (r * m_width + c) * m_depth );
+ return getPixelValue( (r * m_width + c) );
}
PixelColor LazySnapping::getPixelValue(wxPoint pt) const
@@ -218,7 +166,7 @@
1, 1,
1, 0,
1, -1,
- /*0, -1,
+ /*0, -1,
-1, -1,
-1, 0,
-1, 1,*/};
@@ -236,8 +184,7 @@
{
//return exp(-getDistSqrPixelIntensity(p, q)/(2*m_sigma*m_sigma)) * (1.0/getDistPixel(p,q));
double d = getDistSqrPixelIntensity(p, q);
- if(fabs(d) < 1e-16) return 255*2; //
- return 1.0/d;
+ return 1.0/(d + 1.0);
}
void LazySnapping::computeLikelihood(int p, captype &f, captype &b)
@@ -251,18 +198,20 @@
PixelColor clr = getPixelValue(p);
//ClusterCoordType pp[CLUSTERCOORDDIM] = {clr.r, clr.g, clr.b};
ClusterCoord<ClusterCoordType> cc(clr, r, c);
- for(tCluster::iterator it = m_clusters.begin(); it != m_clusters.end(); it++)
+ for(tCluster::iterator it = m_fgnd_clusters.begin(); it != m_fgnd_clusters.end(); it++)
{
//d = getDistSqrPixel(it->first, pp);
//d = EuclideanDistSqr<ClusterCoord<ClusterCoordType>, double>(&(it->first), &cc, CLUSTERCOORDDIM);
- d = cc.getDistSqr(it->first);
- if(it->second == FGND) {
- if(df < 0 || d < df)
- df = d;
- } else if(db < 0 || d < db) {
- db = d;
- }
+ d = cc.getDistSqr(*it);
+ if(df < 0 || d < df)
+ df = d;
}
+ for(tCluster::iterator it = m_bkgnd_clusters.begin(); it != m_bkgnd_clusters.end(); it++)
+ {
+ d = cc.getDistSqr(*it);
+ if(db < 0 || d < db)
+ db = d;
+ }
//df = sqrt(df);
//db = sqrt(db);
f = df/(df + db);
@@ -281,24 +230,72 @@
m_nodes[i] = m_graph->add_node();
captype cap, rev_cap;
+ m_K = -1;
for(i = 0; i < m_cnodes; i++)
for(n = 0; n < 4; n++)
if((j = getNeighbor(i, n)) > -1)
{
- cap = rev_cap = computePrior(i, j);
+ cap = rev_cap = m_lambda * computePrior(i, j);
if(m_K < 0 || cap > m_K)
m_K = cap;
m_graph->add_edge(m_nodes[i], m_nodes[j], cap, rev_cap);
}
}
+void LazySnapping::getPixelsOnLine(const vector<PixelCoord> coords, vector<PixelCoord> &line)
+{
+ wxPoint pa,pb;
+ int dx, dy;
+ float m, t;
+ vector<PixelCoord>::const_iterator it = coords.begin();
+ pa = *it;
+ for(it++; it != coords.end(); it++)
+ {
+ line.push_back(pa);
+ pb = *it;
+ //DDA line drawing algorithm
+ pa.y = m_height - pa.y;
+ pb.y = m_height - pb.y;
+ dx = pb.x - pa.x;
+ dy = pb.y - pa.y; // y coord: m_height - y;
+ t = 0.5;
+ if(abs(dx) > abs(dy)) {
+ m = dy /(float) dx;
+ dx = dx < 0 ? -1 : 1;
+ m *= dx;
+ t += pa.y;
+ while(pa.x != pb.x)
+ {
+ pa.x += dx;
+ t += m;
+ line.push_back(wxPoint(pa.x, m_height - t));
+ }
+ } else if(dy != 0) {
+ m = dx /(float) dy;
+ dy = dy < 0 ? -1 : 1;
+ m *= dy;
+ t += pa.x;
+ while(pa.y != pb.y)
+ {
+ pa.y += dy;
+ t += m;
+ line.push_back(wxPoint(t, m_height - pa.y));
+ }
+ }
+ //
+ pa = pb;
+ }
+}
+
void LazySnapping::markPixels(vector<PixelCoord> coords, Label label)
{
+ vector<PixelCoord> newcoords;
for(vector<PixelCoord>::iterator it = coords.begin(); it != coords.end(); it++)
{
if(m_seeds.find(*it) == m_seeds.end()) //if the pixel wasn't previously marked
{
m_seeds[*it] = label;
+ newcoords.push_back(*it);
//update stats
PixelColor p = getPixelValue(*it);
if(label == BKGND) {
@@ -313,25 +310,84 @@
m_fgnd[p] = 0;
}
//mark clusters
- markCluster(*it, label); /*pc = findCluster(*it);*/
+ //markCluster(*it, label); /*pc = findCluster(*it);*/
}
- }
+ }
+ //update cluster
+ updateCluster(newcoords, label);
+
+ if(m_fgnd_seeds.empty() || m_bkgnd_seeds.empty()) return;
+
//update graph
- updateGraph(coords, label);
+ updateGraph(newcoords, label);
//perform segmentation
segment();
}
-void LazySnapping::markCluster(PixelCoord p, Label label)
+void LazySnapping::assignPoints(KMdata &dataPts, const vector<PixelCoord> &seeds)
{
- int i = p.y * m_width + p.x;
- if(m_clusters[m_cluster_asgn[i]].second == NOLABEL)
- m_clusters[m_cluster_asgn[i]].second = label;
- else if(m_clusters[m_cluster_asgn[i]].second != label)
- assert(0);
+ KMpointArray pa = dataPts.getPts();
+ int i,j;
+ i = 0;
+ for(vector<PixelCoord>::const_iterator it = seeds.begin(); it != seeds.end(); it++, i++)
+ {
+ j = it->y * m_width + it->x;
+ pa[i][0] = (KMcoord) *(m_data + j * m_depth);
+ pa[i][1] = (KMcoord) *(m_data + j * m_depth + 1);
+ pa[i][2] = (KMcoord) *(m_data + j * m_depth + 2);
+ if(CLUSTERCOORDDIM == 5) {
+ pa[i][3] = (KMcoord) it->y;
+ pa[i][4] = (KMcoord) it->x;
+ }
+ }
}
+void LazySnapping::updateCluster(vector<PixelCoord> coords, Label label)
+{
+ if(label == FGND) {
+ copy(coords.begin(), coords.end(), back_insert_iterator<vector<PixelCoord> >(m_fgnd_seeds));
+ updateCluster(m_fgnd_seeds, m_fgnd_clusters);
+ } else {
+ copy(coords.begin(), coords.end(), back_insert_iterator<vector<PixelCoord> >(m_bkgnd_seeds));
+ updateCluster(m_bkgnd_seeds, m_bkgnd_clusters);
+ }
+}
+
+void LazySnapping::updateCluster(std::vector<PixelCoord> &seeds, LazySnapping::tCluster &clusters)
+{
+ if(seeds.empty())
+ return;
+ KMterm term(100, 0, 0, 0, 0.10, 0.10, 3, 0.50, 10, 0.95);
+
+ KMdata dataPts(CLUSTERCOORDDIM, seeds.size());
+
+ //fillup the points
+ assignPoints(dataPts, seeds);
+
+ dataPts.buildKcTree();
+
+ KMfilterCenters ctrs(m_nclusters, dataPts);
+
+ KMlocalLloyds kmAlg(ctrs, term);
+
+ ctrs = kmAlg.execute();
+
+ //m_cluster_asgn = new int[m_cnodes];
+ //m_cluster_sqDist = new double[m_cnodes];
+ //ctrs.getAssignments(m_cluster_asgn, m_cluster_sqDist);
+
+ clusters.clear();
+
+ KMcenterArray pctrs = ctrs.getCtrPts();
+
+ for(int i = 0; i < m_nclusters; i++)
+ {
+ clusters.push_back(
+ ClusterCoord<ClusterCoordType,CLUSTERCOORDDIM>(pctrs[i]));
+ }
+}
+
void LazySnapping::updateGraph(vector<PixelCoord> coords, Label label)
{
captype f, b;
@@ -340,9 +396,9 @@
{
i = (*it).y * m_width + (*it).x;
if(label == FGND) {
- m_graph->add_tweights(m_nodes[i], m_K, 0);
+ m_graph->set_tweights(m_nodes[i], INF, 0);
} else {
- m_graph->add_tweights(m_nodes[i], 0, m_K);
+ m_graph->set_tweights(m_nodes[i], 0, INF);
}
}
@@ -352,7 +408,7 @@
PixelCoord p(c, r);
if(m_seeds.find(p) == m_seeds.end()) { //if current pixel is not marked as seed
computeLikelihood(i, f, b);
- m_graph->add_tweights(m_nodes[i], f, b);
+ m_graph->add_tweights(m_nodes[i], b, f);
}
}
}
@@ -360,7 +416,7 @@
void LazySnapping::segment()
{
Graph::flowtype flow = m_graph->maxflow();
- //go through each node and find out what segment it is in
+ //go through each node and find out the segment it is in
for(int i = 0; i < m_cnodes; i++)
{
if(m_graph->what_segment(m_nodes[i]) == Graph::SOURCE) {
@@ -376,16 +432,37 @@
int r, c;
getRC(node, &r, &c);
wxMemoryDC dc(*m_mask);
- if(label == BKGND)
+ assert(dc.IsOk());
+ wxPen pen = dc.GetPen();
+ wxBrush brush = dc.GetBrush();
+ if(label == FGND) {
dc.SetPen(*wxBLACK);
- else
+ dc.SetBrush(*wxBLACK);
+ }else {
dc.SetPen(*wxWHITE);
+ dc.SetBrush(*wxWHITE);
+ }
dc.DrawPoint(c, r);
+ //dc.DrawCircle(c, r, 5);
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
assert(dc.IsOk());
}
void LazySnapping::setRegion(vector<PixelCoord> coords, Label label)
-{}
+{
+ wxMemoryDC dc(*m_mask);
+ assert(dc.IsOk());
+
+ if(label == ISegmentation::FGND)
+ dc.SetBrush(*wxBLACK_BRUSH);
+ else
+ dc.SetBrush(*wxWHITE_BRUSH);
+ wxPoint *coords_pt = new wxPoint[coords.size()];
+ copy(coords.begin(), coords.end(), coords_pt);
+ dc.DrawPolygon(coords.size(), coords_pt);
+ delete []coords_pt;
+}
void LazySnapping::setImage(unsigned char* data, int row, int col, int depth)
{
reset();
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.h
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.h 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/LazySnapping.h 2008-07-20 01:24:33 UTC (rev 3211)
@@ -30,8 +30,8 @@
#include "KMlocal/KMlocal.h"
const double SIGMA = 2.0f;
-const double LAMBDA = 1.0f;
-const int NCLUSTERS = 64;
+const double LAMBDA = 66.0f;
+const int NCLUSTERS = 8; //64
const int CLUSTERCOORDDIM = 5; // 3:RGB, 5:RGB + (r,c)
class LazySnapping : public ISegmentation
@@ -39,6 +39,7 @@
typedef float captype;
wxBitmap *m_mask;
+ //wxBitmap *m_tmp_bmp; //used for drawing lines and getting all pixel from it
HuginBase::ImageCache::ImageCacheRGB8Ptr m_img;
unsigned char *m_data;
std::vector<wxPoint> m_outline;
@@ -53,6 +54,7 @@
typedef std::map<PixelColor, int> tObjColorMap;
tSeed m_seeds;
tObjColorMap m_fgnd, m_bkgnd;
+ std::vector<PixelCoord> m_fgnd_seeds, m_bkgnd_seeds;
typedef KMcoord ClusterCoordType;
template<typename T, int CDIM = CLUSTERCOORDDIM>
@@ -111,11 +113,12 @@
}
};
//typedef std::map<ClusterCoord<ClusterCoordType>, ISegmentation::Label> tCluster;
- typedef std::vector<std::pair<ClusterCoord<ClusterCoordType>, ISegmentation::Label> > tCluster;
- tCluster m_clusters; //centers of clusters
- int *m_cluster_asgn; //datapoint assignment to a cluster
+ //typedef std::vector<std::pair<ClusterCoord<ClusterCoordType>, ISegmentation::Label> > tCluster;
+ typedef std::vector<ClusterCoord<ClusterCoordType> > tCluster;
+ tCluster m_fgnd_clusters, m_bkgnd_clusters; //centers of clusters
+ //int *m_cluster_asgn; //datapoint assignment to a cluster
int m_nclusters;
- double *m_cluster_sqDist;
+ //double *m_cluster_sqDist;
void watershed();
void preprocess();
@@ -124,9 +127,10 @@
void segment(); //perform segmentation
void setMask(int node, Label label);
- //int findCluster(int p); //finds the cluster that contains pixel p
- //ClusterCoord findCluster(ClusterCoord p);
- void markCluster(PixelCoord p, Label label); //mark the cluster containing pixel p with label l
+ void updateCluster(vector<PixelCoord> coords, Label label);
+ void updateCluster(vector<PixelCoord> &seeds, tCluster &cluster);
+ void assignPoints(KMdata &dataPts, const std::vector<PixelCoord> &seeds);
+ void getPixelsOnLine(const vector<PixelCoord> coords, vector<PixelCoord> &line);
void buildGraph();
void updateGraph(std::vector<PixelCoord> coords, Label label);
@@ -135,6 +139,7 @@
double getDistSqrPixel(int p, int q) const;
double getDistPixel(int p, int q) const;
double getDistSqrPixelIntensity(int p, int q) const;
+ int getIndex(int r, int c) const;
void getRC(int p, int *r, int *c) const;
PixelColor getPixelValue(int p) const;
PixelColor getPixelValue(int r, int c) const;
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/maxflow/graph.h
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/maxflow/graph.h 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/lazysnapping/maxflow/graph.h 2008-07-20 01:24:33 UTC (rev 3211)
@@ -66,9 +66,11 @@
/* Type of edge weights.
Can be changed to char, int, float, double, ... */
- typedef short captype;
+ //typedef short captype;
+ typedef float captype;
/* Type of total flow */
- typedef int flowtype;
+ //typedef int flowtype;
+ typedef float flowtype;
typedef void * node_id;
Modified: hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/polyed_basic/PolyEd_Basic.cpp
===================================================================
--- hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/polyed_basic/PolyEd_Basic.cpp 2008-07-19 01:25:43 UTC (rev 3210)
+++ hugin/branches/gsoc2008_masking/src/maskeditor/segmentation/polyed_basic/PolyEd_Basic.cpp 2008-07-20 01:24:33 UTC (rev 3211)
@@ -58,7 +58,7 @@
wxPoint *coords_pt = new wxPoint[coords.size()];
copy(coords.begin(), coords.end(), coords_pt);
dc.DrawPolygon(coords.size(), coords_pt);
- delete coords_pt;
+ delete []coords_pt;
}
void PolyEd_Basic::setImage(unsigned char* data, int row, int col, int depth)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|