Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
f14b8b43
Commit
f14b8b43
authored
Nov 25, 2014
by
Sync-my-L2P
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update segmentation.cpp
Added detailed comments to watershed()
parent
73ba4356
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
39 additions
and
8 deletions
+39
-8
segmentation.cpp
modules/imgproc/src/segmentation.cpp
+39
-8
No files found.
modules/imgproc/src/segmentation.cpp
View file @
f14b8b43
...
...
@@ -48,7 +48,7 @@
namespace
cv
{
// A node represents a pixel to label
struct
WSNode
{
int
next
;
...
...
@@ -56,6 +56,7 @@ struct WSNode
int
img_ofs
;
};
// Queue for WSNodes
struct
WSQueue
{
WSQueue
()
{
first
=
last
=
0
;
}
...
...
@@ -86,18 +87,26 @@ allocWSNodes( std::vector<WSNode>& storage )
void
cv
::
watershed
(
InputArray
_src
,
InputOutputArray
_markers
)
{
const
int
IN_QUEUE
=
-
2
;
const
int
WSHED
=
-
1
;
// Labels for pixels
const
int
IN_QUEUE
=
-
2
;
// Pixel visited
const
int
WSHED
=
-
1
;
// Pixel belongs to watershed
// possible bit values = 2^8
const
int
NQ
=
256
;
Mat
src
=
_src
.
getMat
(),
dst
=
_markers
.
getMat
();
Size
size
=
src
.
size
();
// Vector of every created node
std
::
vector
<
WSNode
>
storage
;
int
free_node
=
0
,
node
;
// Priority queue of queues of nodes
// from high priority (0) to low priority (255)
WSQueue
q
[
NQ
];
// Non-empty queue with highest priority
int
active_queue
;
int
i
,
j
;
// Color differences
int
db
,
dg
,
dr
;
int
subs_tab
[
513
];
...
...
@@ -106,6 +115,7 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
// MIN(a,b) = a - MAX(a-b,0)
#define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ])
// Create a new node with offsets mofs and iofs in queue idx
#define ws_push(idx,mofs,iofs) \
{ \
if( !free_node ) \
...
...
@@ -122,6 +132,7 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
q[idx].last = node; \
}
// Get next node from queue idx
#define ws_pop(idx,mofs,iofs) \
{ \
node = q[idx].first; \
...
...
@@ -134,6 +145,7 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
iofs = storage[node].img_ofs; \
}
// Get highest absolute channel difference in diff
#define c_diff(ptr1,ptr2,diff) \
{ \
db = std::abs((ptr1)[0] - (ptr2)[0]);\
...
...
@@ -147,9 +159,14 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
CV_Assert
(
src
.
type
()
==
CV_8UC3
&&
dst
.
type
()
==
CV_32SC1
);
CV_Assert
(
src
.
size
()
==
dst
.
size
()
);
// Current pixel in input image
const
uchar
*
img
=
src
.
ptr
();
// Step size to next row in input image
int
istep
=
int
(
src
.
step
/
sizeof
(
img
[
0
]));
// Current pixel in mask image
int
*
mask
=
dst
.
ptr
<
int
>
();
// Step size to next row in mask image
int
mstep
=
int
(
dst
.
step
/
sizeof
(
mask
[
0
]));
for
(
i
=
0
;
i
<
256
;
i
++
)
...
...
@@ -166,7 +183,7 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
for
(
i
=
1
;
i
<
size
.
height
-
1
;
i
++
)
{
img
+=
istep
;
mask
+=
mstep
;
mask
[
0
]
=
mask
[
size
.
width
-
1
]
=
WSHED
;
mask
[
0
]
=
mask
[
size
.
width
-
1
]
=
WSHED
;
// boundary pixels
for
(
j
=
1
;
j
<
size
.
width
-
1
;
j
++
)
{
...
...
@@ -174,6 +191,7 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
if
(
m
[
0
]
<
0
)
m
[
0
]
=
0
;
if
(
m
[
0
]
==
0
&&
(
m
[
-
1
]
>
0
||
m
[
1
]
>
0
||
m
[
-
mstep
]
>
0
||
m
[
mstep
]
>
0
)
)
{
// Find smallest difference to adjacent markers
const
uchar
*
ptr
=
img
+
j
*
3
;
int
idx
=
256
,
t
;
if
(
m
[
-
1
]
>
0
)
...
...
@@ -193,6 +211,8 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
c_diff
(
ptr
,
ptr
+
istep
,
t
);
idx
=
ws_min
(
idx
,
t
);
}
// Add to according queue
assert
(
0
<=
idx
&&
idx
<=
255
);
ws_push
(
idx
,
i
*
mstep
+
j
,
i
*
istep
+
j
*
3
);
m
[
0
]
=
IN_QUEUE
;
...
...
@@ -221,6 +241,8 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
int
*
m
;
const
uchar
*
ptr
;
// Get non-empty queue with highest priority
// Exit condition: empty priority queue
if
(
q
[
active_queue
].
first
==
0
)
{
for
(
i
=
active_queue
+
1
;
i
<
NQ
;
i
++
)
...
...
@@ -231,35 +253,44 @@ void cv::watershed( InputArray _src, InputOutputArray _markers )
active_queue
=
i
;
}
// Get next node
ws_pop
(
active_queue
,
mofs
,
iofs
);
// Calculate pointer to current pixel in input and marker image
m
=
mask
+
mofs
;
ptr
=
img
+
iofs
;
t
=
m
[
-
1
];
// Check surrounding pixels for labels
// to determine label for current pixel
t
=
m
[
-
1
];
// Left
if
(
t
>
0
)
lab
=
t
;
t
=
m
[
1
];
t
=
m
[
1
];
// Right
if
(
t
>
0
)
{
if
(
lab
==
0
)
lab
=
t
;
else
if
(
t
!=
lab
)
lab
=
WSHED
;
}
t
=
m
[
-
mstep
];
t
=
m
[
-
mstep
];
// Top
if
(
t
>
0
)
{
if
(
lab
==
0
)
lab
=
t
;
else
if
(
t
!=
lab
)
lab
=
WSHED
;
}
t
=
m
[
mstep
];
t
=
m
[
mstep
];
// Bottom
if
(
t
>
0
)
{
if
(
lab
==
0
)
lab
=
t
;
else
if
(
t
!=
lab
)
lab
=
WSHED
;
}
// Set label to current pixel in marker image
assert
(
lab
!=
0
);
m
[
0
]
=
lab
;
if
(
lab
==
WSHED
)
continue
;
// Add adjacent, unlabeled pixels to corresponding queue
if
(
m
[
-
1
]
==
0
)
{
c_diff
(
ptr
,
ptr
-
3
,
t
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment