Visual Servoing Platform  version 3.4.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 
50 TEST_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 
180 TEST_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 
333 int 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
348 int 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)