Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README.md #2

Open
wants to merge 12 commits into
base: rashmi
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions Push-relabel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
//Developer: Aastha

#include <bits/stdc++.h>
using namespace std;

struct Edge
{
int flow, capacity;
int u, v;

Edge(int flow, int capacity, int u, int v)
{
this->flow = flow;
this->capacity = capacity;
this->u = u;
this->v = v;
}
};

struct Vertex
{
int h, e_flow;

Vertex(int h, int e_flow)
{
this->h = h;
this->e_flow = e_flow;
}
};

class Graph
{
int V; // The number of vertices
vector<Vertex> ver;
vector<Edge> edge;
bool push(int u);
//Each function
void relabel(int u);
void preflow(int s);
void updateReverseEdgeFlow(int i, int flow);
public:
Graph(int V);
void addEdge(int u, int v, int w);

int getMaxFlow(int s, int t);
};

Graph::Graph(int V)
{
this->V = V;
for (int i = 0; i < V; i++)
ver.push_back(Vertex(0, 0));
}

void Graph::addEdge(int u, int v, int capacity)
{
edge.push_back(Edge(0, capacity, u, v));
}

void Graph::preflow(int s)
{
ver[s].h = ver.size();

for (int i = 0; i < edge.size(); i++)
{
if (edge[i].u == s)
{
edge[i].flow = edge[i].capacity;
ver[edge[i].v].e_flow += edge[i].flow;
edge.push_back(Edge(-edge[i].flow, 0, edge[i].v, s));
}
}
}
int overFlowVertex(vector<Vertex>& ver)
{
for (int i = 1; i < ver.size() - 1; i++)
if (ver[i].e_flow > 0)
return i;

// -1 if no overflowing Vertex (check this once)
return -1;
}

void Graph::updateReverseEdgeFlow(int i, int flow)
{
int u = edge[i].v, v = edge[i].u;

for (int j = 0; j < edge.size(); j++)
{
if (edge[j].v == v && edge[j].u == u)
{
edge[j].flow -= flow;
return;
}
}

Edge e = Edge(0, flow, u, v);
edge.push_back(e);
}


bool Graph::push(int u)
{
for (int i = 0; i < edge.size(); i++)
{
if (edge[i].u == u)
{
if (edge[i].flow == edge[i].capacity)
continue;
if (ver[u].h > ver[edge[i].v].h)
{
int flow = min(edge[i].capacity - edge[i].flow,
ver[u].e_flow);
ver[u].e_flow -= flow;

ver[edge[i].v].e_flow += flow;

edge[i].flow += flow;

updateReverseEdgeFlow(i, flow);

return true;
}
}
}
return false;
}

void Graph::relabel(int u)
{

int mh = INT_MAX;
for (int i = 0; i < edge.size(); i++)
{
if (edge[i].u == u)
{

if (edge[i].flow == edge[i].capacity)
continue;


if (ver[edge[i].v].h < mh)
{
mh = ver[edge[i].v].h;
ver[u].h = mh + 1;
}
}
}
}

int Graph::getMaxFlow(int s, int t)
{
preflow(s);

while (overFlowVertex(ver) != -1)
{
int u = overFlowVertex(ver);
if (!push(u))
relabel(u);
}

return ver.back().e_flow;
}

\
int main()
{
int V = 6;
Graph g(V);

// Take the input from a file and try -Aastha
g.addEdge(0, 1, 16);
g.addEdge(0, 2, 13);
g.addEdge(1, 2, 10);
g.addEdge(2, 1, 4);
g.addEdge(1, 3, 12);
g.addEdge(2, 4, 14);
g.addEdge(3, 2, 9);
g.addEdge(3, 5, 20);
g.addEdge(4, 3, 7);
g.addEdge(4, 5, 4);
int s = 0, t = 5;
cout << "Maximum flow is " << g.getMaxFlow(s, t);
return 0;
}
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
# EC504-Project
# EC504-Project

PROJECT NAME: Image Foreground/Background Segmentation using Network Flow

TEAM NAME: DaVincii

TEAM MEMBERS:
Aastha Anand ([email protected]) ,
Archana Bajaj ([email protected]) ,
Rashmi Agrawal ([email protected]) ,
Sarthak Jagetia ([email protected]) ,
Yijian Liu ([email protected])

BRIEF DESCRIPTION:
In computer vision, image segmentation is the process of partitioning a digital image into multiple segments (sets of pixels, also known as super-pixels). The goal of segmentation is to simplify and/or change the representation of an image into something that is more meaningful and easier to analyze. Image segmentation is typically used to locate objects and boundaries (lines, curves, etc.) in images.

Segmentation is generally treated as a clustering problem, where the pixels are clustered into two groups (foreground or background). We will be using network flow as a method to solve the segmentation problem efficiently in the case of two segments. We will set up the flow network for the segmentation problem and then find the minimum capacity cut for this graph after which we will have an optimal algorithm in our model of foreground/background segmentation.

For the implementation of our algorithm, we will label each pixel in an image belonging to either the foreground of the scene or the background. This can be done with the help of any clustering algorithm based on the color (e.g., RGB values) of the pixels. We plan to use k-means clustering algorithm for our project.

Covering the optional requirements for the project, we plan to do add the following two parts:
Extend the image segmentation beyond two segments to k segments.
Develop an interactive GUI through which the user can select a part of the image he/she wishes to segment

APPLICATIONS OF THE PROJECT:
Some practical examples of image segmentation include:-
Recognition tasks: face recognition, fingerprint recognition, iris recognition
Medical Imaging: surgery planning, measure tissue volumes, locate tumors
Content-based image retrieval
Object detection: Locate objects in satellite images (roads,forests,crops)

REFERENCES:
Siddheswar Ray and Rose H. Turi: Determination of number of Clusters in K-means Clustering and Application in Color Image Segmentation.
Foreground Detection: https://en.wikipedia.org/wiki/Foreground_detection
Dorit S. Hochbaum: An Efficient Algorithm for Image Segmentation, Markov Random Fields and Related Problems.
Caroline Pantofaru and Martial Hebert: A Comparison of Image Segmentation Algorithms
Ying Yin: Binary Image Segmentation Using Graph Cuts
Yuri Boykov: Graph Cuts and Efficient N-D Image Segmentation


SCHEDULE:

Task
Deadline
Implement the binary segmentation
04/10/17
Make improvements(interactive application)
04/30/17
Prepare report and presentation
05/05/17
135 changes: 135 additions & 0 deletions dinic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// C++ implementation of Dinic's Algorithm
#include<bits/stdc++.h>
using namespace std;

struct Edge
{
int v ;
int flow ;
int C;

int rev ;
};

// The Residual Graph construction
class Graph
{
int V;
int *level ;
vector< Edge > *adj;
public :
Graph(int V)
{
adj = new vector<Edge>[V];
this->V = V;
level = new int[V];
}

void addEdge(int u, int v, int C)
{
Edge a{v, 0, C, adj[v].size()};
Edge b{u, 0, 0, adj[u].size()};
adj[u].push_back(a);
adj[v].push_back(b);
}

bool BFS(int s, int t);
int sendFlow(int s, int flow, int t, int ptr[]);
int DinicMaxflow(int s, int t);
};

bool Graph::BFS(int s, int t)
{
for (int i = 0 ; i < V ; i++)
level[i] = -1;

level[s] = 0;
list< int > q;
q.push_back(s);

vector<Edge>::iterator i ;
while (!q.empty())
{
int u = q.front();
q.pop_front();
for (i = adj[u].begin(); i != adj[u].end(); i++)
{
Edge &e = *i;
if (level[e.v] < 0 && e.flow < e.C)
{
level[e.v] = level[u] + 1;

q.push_back(e.v);
}
}
}

return level[t] < 0 ? false : true ;
}

int Graph::sendFlow(int u, int flow, int t, int start[])
{
// Sink reached
if (u == t)
return flow;
for ( ; start[u] < adj[u].size(); start[u]++)
{
Edge &e = adj[u][start[u]];

if (level[e.v] == level[u]+1 && e.flow < e.C)
{
int curr_flow = min(flow, e.C - e.flow);
int temp_flow = sendFlow(e.v, curr_flow, t, start);
if (temp_flow > 0)
{
e.flow += temp_flow;
adj[e.v][e.rev].flow -= temp_flow;
return temp_flow;
}
}
}

return 0;
}

int Graph::DinicMaxflow(int s, int t)
{

if (s == t)
return -1;

int total = 0;

while (BFS(s, t) == true)
{

int *start = new int[V+1];

while (int flow = sendFlow(s, INT_MAX, t, start))

total += flow;
}

// return maximum flow
return total;
}


int main()
{

// Check from text-file input -Aastha
Graph g(6);
g.addEdge(0, 1, 16 );
g.addEdge(0, 2, 13 );
g.addEdge(1, 2, 10 );
g.addEdge(1, 3, 12 );
g.addEdge(2, 1, 4 );
g.addEdge(2, 4, 14);
g.addEdge(3, 2, 9 );
g.addEdge(3, 5, 20 );
g.addEdge(4, 3, 7 );
g.addEdge(4, 5, 4);
cout << "Maximum flow " << g.DinicMaxflow(0, 5);
return 0;
}
Loading