-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathGraphCut.cpp
125 lines (107 loc) · 2.68 KB
/
GraphCut.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* GraphCut.cpp
*
* Created on: Dec 13, 2014
* Author: Karim Tarek
*/
#include "GraphCut.h"
/**
* GraphCut an image into
* Binary image
*
* @param image The Source image
* @param neighboursWeight Neighbours influence
* @param windowSize Neighbours range
*
*
* @return Segmented Image
*/
Mat GRAPHCUT::graphCut(Mat img, float neighboursWeight, int windowSize)
{
Mat segmentedImg;
GCGraph<float> graph((img.rows * img.cols), (img.rows * img.cols * 8));
img2graph(graph, img, neighboursWeight, windowSize);
graph.maxFlow();
segmentedImg = graph2img(graph, img.rows, img.cols);
return segmentedImg;
}
/**
* Convert a Graph
* into an image
*
* @param graph The Source graph
* @param rows Image Height
* @param cols Image Width
*
*
* @return Converted Image
*/
Mat GRAPHCUT::graph2img(GCGraph<float>& graph, int rows, int cols)
{
Mat img(rows, cols, CV_32F);
for (int r = 0; r < rows; r++)
for (int c = 0; c < cols; c++)
img.at<float>(r, c) = graph.inSourceSegment(c + img.cols * r);
return img;
}
/**
* Convert an Image
* into a Graph
*
* @param graph The graph pointer
* @param img The Source image
* @param neighboursWeight Neighbours influence
* @param windowSize Neighbours range
*
*
* @return Updates the graph
*/
void GRAPHCUT::img2graph(GCGraph<float>& graph, Mat& img, float neighboursWeight, int windowSize)
{
cvtColor(img, img, CV_BGR2GRAY);
normalize(img, img, 0, 1, NORM_MINMAX, CV_32F);
addVertices(graph, img);
addEdges(graph, img, neighboursWeight, windowSize);
}
/**
* Add each pixel as
* a node in a graph
*
* @param graph The graph pointer
* @param img The Source image
*
*
* @return Updates the graph
*/
void GRAPHCUT::addVertices(GCGraph<float>& graph, Mat& img)
{
for (int r = 0; r < img.rows; r++)
for (int c = 0; c < img.cols; c++)
{
graph.addVtx();
graph.addTermWeights(c + img.cols * r, img.at<float>(r, c), 1 - img.at<float>(r, c));
}
}
/**
* Add edges between
* nodes in a graph
*
* @param graph The graph pointer
* @param img The Source image
* @param neighboursWeight Neighbours influence
* @param windowSize Neighbours range
*
* @return Updates the graph
*/
void GRAPHCUT::addEdges(GCGraph<float>& graph, Mat& img, float neighboursWeight, int windowSize)
{
for (int r = windowSize; r < img.rows - windowSize; r++)
for (int c = windowSize; c < img.cols - windowSize; c++)
for (int i = -windowSize; i <= windowSize; i++)
for (int j = -windowSize; j <= windowSize; j++)
if (i != 0 || j != 0)
{
float v = abs(img.at<float>(r, c) - img.at<float>(r + i, c + j)) * neighboursWeight;
graph.addEdges(c + img.cols * r, (c + j) + img.cols * (r + i), v, v);
}
}