Visual Servoing Platform version 3.5.0
testImageMorphology.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Test image morphology.
33 *
34 *****************************************************************************/
35
42#include <visp3/core/vpConfig.h>
43
44#if defined(VISP_HAVE_CATCH2)
45#define CATCH_CONFIG_RUNNER
46#include <catch.hpp>
47#include <visp3/core/vpImageMorphology.h>
48#include "common.hpp"
49
50TEST_CASE("Binary image morphology", "[image_morphology]") {
51 unsigned char image_data[8 * 16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0,
52 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1,
53 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
54 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1,
55 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
56
57 vpImage<unsigned char> I(image_data, 8, 16, true);
58
59 SECTION("Dilatation")
60 {
61 SECTION("4-connexity")
62 {
64 vpImage<unsigned char> I_morpho_ref = I;
65 vpImage<unsigned char> I_morpho_tpl = I;
66 vpImage<unsigned char> I_morpho = I;
67
68 common_tools::imageDilatationRef(I_morpho_ref, connexity);
69 vpImageMorphology::dilatation(I_morpho_tpl, (unsigned char)1, (unsigned char)0, connexity);
70 vpImageMorphology::dilatation(I_morpho, connexity);
71
72 CHECK((I_morpho_ref == I_morpho_tpl));
73 CHECK((I_morpho_ref == I_morpho));
74 }
75 SECTION("8-connexity")
76 {
78 vpImage<unsigned char> I_morpho_ref = I;
79 vpImage<unsigned char> I_morpho_tpl = I;
80 vpImage<unsigned char> I_morpho = I;
81
82 common_tools::imageDilatationRef(I_morpho_ref, connexity);
83 vpImageMorphology::dilatation(I_morpho_tpl, (unsigned char)1, (unsigned char)0, connexity);
84 vpImageMorphology::dilatation(I_morpho, connexity);
85
86 CHECK((I_morpho_ref == I_morpho_tpl));
87 CHECK((I_morpho_ref == I_morpho));
88 }
89 }
90
91 SECTION("Erosion")
92 {
93 SECTION("4-connexity")
94 {
96 vpImage<unsigned char> I_morpho_ref = I;
97 vpImage<unsigned char> I_morpho_tpl = I;
98 vpImage<unsigned char> I_morpho = I;
99
100 common_tools::imageErosionRef(I_morpho_ref, connexity);
101 vpImageMorphology::erosion(I_morpho_tpl, (unsigned char)1, (unsigned char)0, connexity);
102 vpImageMorphology::erosion(I_morpho, connexity);
103
104 CHECK((I_morpho_ref == I_morpho_tpl));
105 CHECK((I_morpho_ref == I_morpho));
106 }
107
108 SECTION("8-connexity")
109 {
111 vpImage<unsigned char> I_morpho_ref = I;
112 vpImage<unsigned char> I_morpho_tpl = I;
113 vpImage<unsigned char> I_morpho = I;
114
115 common_tools::imageErosionRef(I_morpho_ref, connexity);
116 vpImageMorphology::erosion(I_morpho_tpl, (unsigned char)1, (unsigned char)0, connexity);
117 vpImageMorphology::erosion(I_morpho, connexity);
118
119 CHECK((I_morpho_ref == I_morpho_tpl));
120 CHECK((I_morpho_ref == I_morpho));
121 }
122 }
123
124 SECTION("Matlab reference")
125 {
126 SECTION("4-connexity")
127 {
129 vpImage<unsigned char> I_dilatation = I;
130 vpImageMorphology::dilatation(I_dilatation, connexity);
131
132 unsigned char image_data_dilatation[8 * 16] = {
133 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,
134 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
135 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1,
136 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 };
137 vpImage<unsigned char> I_dilatation_ref(image_data_dilatation, 8, 16, true);
138 CHECK((I_dilatation_ref == I_dilatation));
139
140 vpImage<unsigned char> I_erosion = I_dilatation;
141 vpImageMorphology::erosion(I_erosion, connexity);
142
143 unsigned char image_data_erosion[8 * 16] = {
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0,
145 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
146 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
147 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
148 vpImage<unsigned char> I_erosion_ref(image_data_erosion, 8, 16, true);
149 CHECK((I_erosion_ref == I_erosion));
150 }
151
152 SECTION("8-connexity")
153 {
155 vpImage<unsigned char> I_dilatation = I;
156 vpImageMorphology::dilatation(I_dilatation, connexity);
157
158 unsigned char image_data_dilatation[8 * 16] = {
159 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
160 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
161 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1,
162 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 };
163 vpImage<unsigned char> I_dilatation_ref(image_data_dilatation, 8, 16, true);
164 CHECK((I_dilatation_ref == I_dilatation));
165
166 vpImage<unsigned char> I_erosion = I_dilatation;
167 vpImageMorphology::erosion(I_erosion, connexity);
168
169 unsigned char image_data_erosion[8 * 16] = {
170 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0,
171 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
172 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
173 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 };
174 vpImage<unsigned char> I_erosion_ref(image_data_erosion, 8, 16, true);
175 CHECK((I_erosion_ref == I_erosion));
176 }
177 }
178}
179
180TEST_CASE("Gray image morphology", "[image_morphology]") {
182 common_tools::magicSquare(I, 17);
183
184 SECTION("Dilatation")
185 {
186 SECTION("4-connexity")
187 {
189 vpImage<unsigned char> I_morpho_ref = I;
190 vpImage<unsigned char> I_morpho = I;
191
192 common_tools::imageDilatationRef(I_morpho_ref, connexity);
193 vpImageMorphology::dilatation(I_morpho, connexity);
194
195 CHECK((I_morpho_ref == I_morpho));
196 }
197 SECTION("8-connexity")
198 {
200 vpImage<unsigned char> I_morpho_ref = I;
201 vpImage<unsigned char> I_morpho = I;
202
203 common_tools::imageDilatationRef(I_morpho_ref, connexity);
204 vpImageMorphology::dilatation(I_morpho, connexity);
205
206 CHECK((I_morpho_ref == I_morpho));
207 }
208 }
209
210 SECTION("Erosion")
211 {
212 SECTION("4-connexity")
213 {
215 vpImage<unsigned char> I_morpho_ref = I;
216 vpImage<unsigned char> I_morpho = I;
217
218 common_tools::imageErosionRef(I_morpho_ref, connexity);
219 vpImageMorphology::erosion(I_morpho, connexity);
220
221 CHECK((I_morpho_ref == I_morpho));
222 }
223
224 SECTION("8-connexity")
225 {
227 vpImage<unsigned char> I_morpho_ref = I;
228 vpImage<unsigned char> I_morpho = I;
229
230 common_tools::imageErosionRef(I_morpho_ref, connexity);
231 vpImageMorphology::erosion(I_morpho, connexity);
232
233 CHECK((I_morpho_ref == I_morpho));
234 }
235 }
236
237 SECTION("Matlab reference")
238 {
239 SECTION("4-connexity")
240 {
242 vpImage<unsigned char> I_dilatation = I;
243 vpImageMorphology::dilatation(I_dilatation, connexity);
244
245 unsigned char image_data_dilatation[17 * 17] = {
246 174, 193, 212, 231, 250, 255, 255, 255, 255, 39, 58, 77, 96, 115, 134, 153, 154, 192, 211, 230, 249,
247 255, 255, 255, 255, 38, 57, 76, 95, 114, 133, 152, 170, 172, 210, 229, 248, 255, 255, 255, 255, 37,
248 56, 75, 94, 113, 132, 151, 170, 172, 190, 228, 247, 255, 255, 255, 255, 36, 55, 74, 93, 112, 131,
249 150, 169, 187, 190, 208, 246, 255, 255, 255, 255, 51, 54, 73, 92, 111, 130, 149, 168, 187, 189, 208,
250 226, 255, 255, 255, 255, 51, 53, 72, 91, 110, 129, 148, 167, 186, 204, 207, 226, 244, 255, 255, 255,
251 50, 68, 71, 90, 109, 128, 147, 166, 185, 204, 206, 225, 244, 255, 255, 255, 49, 68, 70, 89, 108,
252 127, 146, 165, 184, 203, 221, 224, 243, 255, 255, 255, 48, 67, 85, 88, 107, 126, 145, 164, 183, 202,
253 221, 223, 242, 255, 255, 255, 47, 66, 85, 87, 106, 125, 144, 163, 182, 201, 220, 238, 241, 255, 255,
254 255, 255, 65, 84, 102, 105, 124, 143, 162, 181, 200, 219, 238, 240, 255, 255, 255, 255, 45, 83, 102,
255 104, 123, 142, 161, 180, 199, 218, 237, 255, 255, 255, 255, 255, 45, 63, 101, 119, 122, 141, 160, 179,
256 198, 217, 236, 255, 255, 255, 255, 255, 44, 63, 81, 119, 121, 140, 159, 178, 197, 216, 235, 254, 255,
257 255, 255, 255, 43, 62, 81, 99, 136, 139, 158, 177, 196, 215, 234, 253, 255, 255, 255, 255, 42, 61,
258 80, 99, 117, 138, 157, 176, 195, 214, 233, 252, 255, 255, 255, 255, 41, 60, 79, 98, 117, 135, 156,
259 175, 194, 213, 232, 251, 255, 255, 255, 255, 40, 59, 78, 97, 116, 135, 135 };
260 vpImage<unsigned char> I_dilatation_ref(image_data_dilatation, 17, 17, true);
261 CHECK((I_dilatation_ref == I_dilatation));
262
263 vpImage<unsigned char> I_erosion = I_dilatation;
264 vpImageMorphology::erosion(I_erosion, connexity);
265
266 unsigned char image_data_erosion[17 * 17] = {
267 174, 174, 193, 212, 231, 250, 255, 255, 38, 39, 39, 58, 77, 96, 115, 134, 153, 174, 192, 211, 230,
268 249, 255, 255, 37, 38, 38, 57, 76, 95, 114, 133, 152, 154, 192, 210, 229, 248, 255, 255, 36, 37,
269 37, 56, 75, 94, 113, 132, 151, 170, 172, 210, 228, 247, 255, 255, 36, 36, 36, 55, 74, 93, 112,
270 131, 150, 169, 172, 190, 228, 246, 255, 255, 51, 51, 36, 54, 73, 92, 111, 130, 149, 168, 187, 189,
271 208, 246, 255, 255, 50, 51, 51, 53, 72, 91, 110, 129, 148, 167, 186, 189, 207, 226, 255, 255, 49,
272 50, 50, 53, 71, 90, 109, 128, 147, 166, 185, 204, 206, 225, 244, 255, 48, 49, 49, 68, 70, 89,
273 108, 127, 146, 165, 184, 203, 206, 224, 243, 255, 47, 48, 48, 67, 70, 88, 107, 126, 145, 164, 183,
274 202, 221, 223, 242, 255, 255, 47, 47, 66, 85, 87, 106, 125, 144, 163, 182, 201, 220, 223, 241, 255,
275 255, 45, 47, 65, 84, 87, 105, 124, 143, 162, 181, 200, 219, 238, 240, 255, 255, 45, 45, 65, 83,
276 102, 104, 123, 142, 161, 180, 199, 218, 237, 240, 255, 255, 44, 45, 45, 83, 101, 104, 122, 141, 160,
277 179, 198, 217, 236, 255, 255, 255, 43, 44, 44, 63, 101, 119, 121, 140, 159, 178, 197, 216, 235, 254,
278 255, 255, 42, 43, 43, 62, 81, 119, 121, 139, 158, 177, 196, 215, 234, 253, 255, 255, 41, 42, 42,
279 61, 80, 99, 136, 138, 157, 176, 195, 214, 233, 252, 255, 255, 40, 41, 41, 60, 79, 98, 117, 138,
280 156, 175, 194, 213, 232, 251, 255, 255, 40, 40, 40, 59, 78, 97, 116, 135 };
281 vpImage<unsigned char> I_erosion_ref(image_data_erosion, 17, 17, true);
282 CHECK((I_erosion_ref == I_erosion));
283 }
284
285 SECTION("8-connexity")
286 {
288 vpImage<unsigned char> I_dilatation = I;
289 vpImageMorphology::dilatation(I_dilatation, connexity);
290
291 unsigned char image_data_dilatation[17 * 17] = {
292 192, 211, 230, 249, 255, 255, 255, 255, 255, 57, 76, 95, 114, 133, 152, 154, 154, 210, 229, 248, 255,
293 255, 255, 255, 255, 255, 75, 94, 113, 132, 151, 170, 172, 172, 228, 247, 255, 255, 255, 255, 255, 255,
294 74, 93, 112, 131, 150, 169, 171, 190, 190, 246, 255, 255, 255, 255, 255, 255, 73, 92, 111, 130, 149,
295 168, 187, 189, 208, 208, 255, 255, 255, 255, 255, 255, 72, 91, 110, 129, 148, 167, 186, 188, 207, 226,
296 226, 255, 255, 255, 255, 255, 71, 90, 109, 128, 147, 166, 185, 204, 206, 225, 244, 244, 255, 255, 255,
297 255, 70, 89, 108, 127, 146, 165, 184, 203, 205, 224, 243, 255, 255, 255, 255, 255, 69, 88, 107, 126,
298 145, 164, 183, 202, 221, 223, 242, 255, 255, 255, 255, 255, 85, 87, 106, 125, 144, 163, 182, 201, 220,
299 222, 241, 255, 255, 255, 255, 65, 84, 86, 105, 124, 143, 162, 181, 200, 219, 238, 240, 255, 255, 255,
300 255, 255, 83, 102, 104, 123, 142, 161, 180, 199, 218, 237, 239, 255, 255, 255, 255, 255, 255, 101, 103,
301 122, 141, 160, 179, 198, 217, 236, 255, 255, 255, 255, 255, 255, 255, 63, 119, 121, 140, 159, 178, 197,
302 216, 235, 254, 255, 255, 255, 255, 255, 255, 81, 81, 120, 139, 158, 177, 196, 215, 234, 253, 255, 255,
303 255, 255, 255, 255, 80, 99, 99, 138, 157, 176, 195, 214, 233, 252, 255, 255, 255, 255, 255, 255, 79,
304 98, 117, 117, 156, 175, 194, 213, 232, 251, 255, 255, 255, 255, 255, 255, 78, 97, 116, 135, 135, 156,
305 175, 194, 213, 232, 251, 255, 255, 255, 255, 255, 59, 78, 97, 116, 135, 135 };
306 vpImage<unsigned char> I_dilatation_ref(image_data_dilatation, 17, 17, true);
307 CHECK((I_dilatation_ref == I_dilatation));
308
309 vpImage<unsigned char> I_erosion = I_dilatation;
310 vpImageMorphology::erosion(I_erosion, connexity);
311
312 unsigned char image_data_erosion[17 * 17] = {
313 192, 192, 211, 230, 249, 255, 255, 255, 57, 57, 57, 76, 95, 114, 133, 152, 154, 192, 192, 211, 230,
314 249, 255, 255, 74, 57, 57, 57, 76, 95, 114, 133, 152, 154, 210, 210, 229, 248, 255, 255, 73, 73,
315 73, 74, 75, 94, 113, 132, 151, 170, 172, 228, 228, 247, 255, 255, 72, 72, 72, 73, 74, 93, 112,
316 131, 150, 169, 171, 190, 246, 246, 255, 255, 71, 71, 71, 72, 73, 92, 111, 130, 149, 168, 187, 189,
317 208, 255, 255, 255, 70, 70, 70, 71, 72, 91, 110, 129, 148, 167, 186, 188, 207, 226, 255, 255, 69,
318 69, 69, 70, 71, 90, 109, 128, 147, 166, 185, 204, 206, 225, 244, 255, 85, 69, 69, 69, 70, 89,
319 108, 127, 146, 165, 184, 203, 205, 224, 243, 255, 65, 65, 69, 69, 69, 88, 107, 126, 145, 164, 183,
320 202, 221, 223, 242, 255, 255, 65, 65, 84, 85, 87, 106, 125, 144, 163, 182, 201, 220, 222, 241, 255,
321 255, 255, 65, 65, 84, 86, 105, 124, 143, 162, 181, 200, 219, 238, 240, 255, 255, 63, 63, 83, 83,
322 102, 104, 123, 142, 161, 180, 199, 218, 237, 239, 255, 255, 81, 63, 63, 101, 101, 103, 122, 141, 160,
323 179, 198, 217, 236, 255, 255, 255, 80, 80, 63, 63, 119, 119, 121, 140, 159, 178, 197, 216, 235, 254,
324 255, 255, 79, 79, 79, 80, 81, 120, 120, 139, 158, 177, 196, 215, 234, 253, 255, 255, 78, 78, 78,
325 79, 80, 99, 138, 138, 157, 176, 195, 214, 233, 252, 255, 255, 59, 59, 59, 78, 79, 98, 117, 156,
326 156, 175, 194, 213, 232, 251, 255, 255, 255, 59, 59, 59, 78, 97, 116, 135 };
327 vpImage<unsigned char> I_erosion_ref(image_data_erosion, 17, 17, true);
328 CHECK((I_erosion_ref == I_erosion));
329 }
330 }
331}
332
333int main(int argc, char *argv[])
334{
335 Catch::Session session; // There must be exactly one instance
336
337 // Let Catch (using Clara) parse the command line
338 session.applyCommandLine(argc, argv);
339
340 int numFailed = session.run();
341
342 // numFailed is clamped to 255 as some unices only use the lower 8 bits.
343 // This clamping has already been applied, so just return it here
344 // You can also do any post run clean-up here
345 return numFailed;
346}
347#else
348int main()
349{
350 return 0;
351}
352#endif
static void dilatation(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
static void erosion(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)