Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
Loading...
Searching...
No Matches
vpMorph.cpp
1
/*
2
* ViSP, open source Visual Servoing Platform software.
3
* Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4
*
5
* This software is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
* See the file LICENSE.txt at the root directory of this source
10
* distribution for additional information about the GNU GPL.
11
*
12
* For using ViSP with software that can not be combined with the GNU
13
* GPL, please contact Inria about acquiring a ViSP Professional
14
* Edition License.
15
*
16
* See https://visp.inria.fr for more information.
17
*
18
* This software was developed at:
19
* Inria Rennes - Bretagne Atlantique
20
* Campus Universitaire de Beaulieu
21
* 35042 Rennes Cedex
22
* France
23
*
24
* If you have questions regarding the use of this file, please contact
25
* Inria at visp@inria.fr
26
*
27
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29
*
30
* Description:
31
* Additional image morphology functions.
32
*/
33
38
39
#include <visp3/core/vpImageTools.h>
40
#include <visp3/imgproc/vpImgproc.h>
41
42
namespace
VISP_NAMESPACE_NAME
43
{
44
45
void
fillHoles
(
vpImage<unsigned char>
&I
46
#
if
USE_OLD_FILL_HOLE
47
,
48
const
vpImageMorphology::vpConnexityType
&connexity
49
#endif
50
)
51
{
52
if
(I.getSize() == 0) {
53
return
;
54
}
55
56
#if USE_OLD_FILL_HOLE
57
// Code similar to Matlab imfill(BW,'holes')
58
// Replaced by flood fill as imfill use imreconstruct
59
// and our reconstruct implementation is naive and inefficient
60
// Difference between new and old implementation:
61
// - new implementation allows to set the fill value
62
// - only background==0 is required, before it was 0 (background) / 1
63
// (foreground)
64
// - no more connexity option
65
vpImage<unsigned char>
mask(I.getHeight() + 2, I.getWidth() + 2, 255);
66
// Copy I to mask + add border padding + complement
67
for
(
unsigned
int
i = 0; i < I.getHeight(); ++i) {
68
for
(
unsigned
int
j = 0; j < I.getWidth(); ++j) {
69
mask[i + 1][j + 1] = 255 - I[i][j];
70
}
71
}
72
73
vpImage<unsigned char>
marker(I.getHeight() + 2, I.getWidth() + 2, 0);
74
// Create marker with 255 1-pixel border
75
for
(
unsigned
int
i = 0; i < marker.
getHeight
(); ++i) {
76
if
(i == 0 || i == marker.
getHeight
() - 1) {
77
for
(
unsigned
int
j = 0; j < marker.
getWidth
(); ++j) {
78
marker[i][j] = 255;
79
}
80
}
81
else
{
82
marker[i][0] = 255;
83
marker[i][marker.
getWidth
() - 1] = 255;
84
}
85
}
86
87
vpImage<unsigned char>
I_reconstruct;
88
reconstruct
(marker, mask, I_reconstruct, connexity);
89
90
for
(
unsigned
int
i = 0; i < I.getHeight(); ++i) {
91
for
(
unsigned
int
j = 0; j < I.getWidth(); ++j) {
92
I[i][j] = 255 - I_reconstruct[i + 1][j + 1];
93
}
94
}
95
#else
96
// Create flood fill mask
97
vpImage<unsigned char>
flood_fill_mask(I.getHeight() + 2, I.getWidth() + 2, 0);
98
// Copy I to mask + add border padding
99
unsigned
int
i_height = I.getHeight();
100
for
(
unsigned
int
i = 0; i < i_height; ++i) {
101
memcpy(flood_fill_mask[i + 1] + 1, I[i],
sizeof
(
unsigned
char
) * I.
getWidth
());
102
}
103
104
// Perform flood fill
105
const
unsigned
char
newVal = 255;
106
floodFill
(flood_fill_mask,
vpImagePoint
(0, 0), 0, newVal);
107
108
// Get current mask
109
vpImage<unsigned char>
mask(I.getHeight(), I.getWidth());
110
unsigned
int
mask_height = mask.
getHeight
();
111
for
(
unsigned
int
i = 0; i < mask_height; ++i) {
112
memcpy(mask[i], flood_fill_mask[i + 1] + 1,
sizeof
(
unsigned
char
) * mask.
getWidth
());
113
}
114
115
// Get image with holes filled
116
vpImage<unsigned char>
I_white(I.getHeight(), I.getWidth(), 255), I_holes;
117
vpImageTools::imageSubtract
(I_white, mask, I_holes);
118
vpImageTools::imageAdd
(I, I_holes, I,
true
);
119
#endif
120
}
121
122
void
reconstruct
(
const
vpImage<unsigned char>
&marker,
const
vpImage<unsigned char>
&mask,
123
vpImage<unsigned char>
&h_kp1
/*alias I */
,
const
vpImageMorphology::vpConnexityType
&connexity)
124
{
125
if
((marker.
getHeight
() != mask.
getHeight
()) || (marker.
getWidth
() != mask.
getWidth
())) {
126
std::cerr <<
"marker.getHeight() != mask.getHeight() || "
127
"marker.getWidth() != mask.getWidth()"
128
<< std::endl;
129
return
;
130
}
131
132
if
(marker.
getSize
() == 0) {
133
std::cerr <<
"Input images are empty!"
<< std::endl;
134
return
;
135
}
136
137
vpImage<unsigned char>
h_k = marker;
138
h_kp1 = h_k;
139
140
bool
h_kp1_eq_h_k =
false
;
141
do
{
142
// Dilatation
143
vpImageMorphology::dilatation<unsigned char>
(h_kp1, connexity);
144
145
// Keep min
146
unsigned
int
h_kp1_height = h_kp1.
getHeight
();
147
unsigned
int
h_kp1_width = h_kp1.
getWidth
();
148
for
(
unsigned
int
i = 0; i < h_kp1_height; ++i) {
149
for
(
unsigned
int
j = 0; j < h_kp1_width; ++j) {
150
h_kp1[i][j] = std::min<unsigned char>(h_kp1[i][j], mask[i][j]);
151
}
152
}
153
154
if
(h_kp1 == h_k) {
155
h_kp1_eq_h_k =
true
;
156
// break
157
}
158
else
{
159
h_k = h_kp1;
160
}
161
}
while
(h_kp1_eq_h_k ==
false
);
162
}
163
164
}
// namespace
vpImageMorphology::dilatation
static void dilatation(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
Definition
vpImageMorphology.h:304
vpImageMorphology::vpConnexityType
vpConnexityType
Definition
vpImageMorphology.h:74
vpImagePoint
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition
vpImagePoint.h:82
vpImageTools::imageSubtract
static void imageSubtract(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Ires, bool saturate=false)
Definition
vpImageTools.cpp:358
vpImageTools::imageAdd
static void imageAdd(const vpImage< unsigned char > &I1, const vpImage< unsigned char > &I2, vpImage< unsigned char > &Ires, bool saturate=false)
Definition
vpImageTools.cpp:315
vpImage
Definition of the vpImage class member functions.
Definition
vpImage.h:131
vpImage::getWidth
unsigned int getWidth() const
Definition
vpImage.h:242
vpImage::getSize
unsigned int getSize() const
Definition
vpImage.h:221
vpImage::getHeight
unsigned int getHeight() const
Definition
vpImage.h:181
VISP_NAMESPACE_NAME::floodFill
VISP_EXPORT void floodFill(VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I, const VISP_NAMESPACE_ADDRESSING vpImagePoint &seedPoint, const unsigned char oldValue, const unsigned char newValue, const VISP_NAMESPACE_ADDRESSING vpImageMorphology::vpConnexityType &connexity=VISP_NAMESPACE_ADDRESSING vpImageMorphology::CONNEXITY_4)
VISP_NAMESPACE_NAME::fillHoles
VISP_EXPORT void fillHoles(VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &I)
VISP_NAMESPACE_NAME::reconstruct
VISP_EXPORT void reconstruct(const VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &marker, const VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &mask, VISP_NAMESPACE_ADDRESSING vpImage< unsigned char > &h_kp1, const VISP_NAMESPACE_ADDRESSING vpImageMorphology::vpConnexityType &connexity=VISP_NAMESPACE_ADDRESSING vpImageMorphology::CONNEXITY_4)
VISP_NAMESPACE_NAME
Definition
vpEigenConversion.h:44
modules
imgproc
src
vpMorph.cpp
Generated by
1.17.0