DGtalTools 2.1.0
Loading...
Searching...
No Matches
volAddNoise.cpp
1
27#include <DGtal/base/Common.h>
28#include "DGtal/io/readers/GenericReader.h"
29#include "DGtal/io/writers/GenericWriter.h"
30#include "DGtal/images/ImageContainerBySTLVector.h"
31#include "DGtal/images/ImageSelector.h"
32#include <DGtal/geometry/volumes/KanungoNoise.h>
33#include <DGtal/images/IntervalForegroundPredicate.h>
34
35#include "CLI11.hpp"
36
37// Max component option
38#include <boost/pending/disjoint_sets.hpp>
39
40#include <vector>
41#include <string>
42#include <climits>
43
44using namespace DGtal;
45
46
95void missingParam( const std::string &param )
96{
97 trace.error() << " Parameter: " << param << " is required..";
98 trace.info() << std::endl;
99 exit( 1 );
100}
101
102typedef ImageSelector<Z3i::Domain, unsigned char>::Type MyImage;
103
104int main( int argc, char ** argv )
105{
106
107 // parse command line using CLI ----------------------------------------------
108 CLI::App app;
109 std::string inputFileName;
110 std::string outputFileName {"result.vol"};
111 double noise {0.5};
112 bool MaxFlag {false};
113
114 app.description("Adds Kanungo noise to a binary object with 0 values as "
115 "background points and values >0 for the foreground ones.\n Basic usage:\n \t volAddNoi0se [options] --input <imageName> --output <outputImage> -noise 0.3 \n");
116 app.add_option("-i,--input,1", inputFileName, "input image file name (any 3D image format accepted by DGtal::GenericReader)" )
117 ->required()
118 ->check(CLI::ExistingFile);
119 app.add_option("-o,--output,2", outputFileName, "output image file name (any 3D image format accepted by DGtal::GenericWriter)");
120
121 app.add_option("--noise,-n", noise, "Kanungo noise level in ]0,1[ (default 0.5)\n");
122 app.add_flag("--max,-m", MaxFlag, "Extract only the largest 6-connected component.");
123
124 app.get_formatter()->column_width(40);
125 CLI11_PARSE(app, argc, argv);
126 // END parse command line using CLI ----------------------------------------------
127
128
129 typedef functors::IntervalForegroundPredicate<MyImage> Binarizer;
130 MyImage image = GenericReader<MyImage>::import( inputFileName );
131 trace.info() << "Input image: " << image << std::endl;
132 Binarizer predicate( image, 0, 255 );
133
134 KanungoNoise<Binarizer, Z3i::Domain> kanungo( predicate, image.domain(),
135 noise );
136
137 MyImage result( image.domain() );
138 for ( Z3i::Domain::ConstIterator it = image.domain().begin(),
139 itend = image.domain().end();
140 it != itend; ++it )
141 {
142 if ( kanungo( *it ) )
143 result.setValue( *it, 255 );
144 else
145 result.setValue( *it, 0 );
146 }
147
148 // Exporting
149 if ( !MaxFlag )
150 {
151 result >> outputFileName;
152 }
153 else
154 {
155 trace.beginBlock( "Extracting the largest 6-connected component" );
156 typedef std::map<Z3i::Point, std::size_t> Rank; // => order on Element
157 typedef std::map<Z3i::Point, Z3i::Point> Parent;
158 Rank rankMap;
159 Parent parentMap;
160 boost::associative_property_map<Rank> rankPMap( rankMap );
161 boost::associative_property_map<Parent> parentPMap( parentMap );
162 boost::disjoint_sets<boost::associative_property_map<Rank>,
163 boost::associative_property_map<Parent>>
164 dsets( rankPMap, parentPMap );
165
166 trace.beginBlock( "Initial disjoint sets construction" );
167 for ( auto e : result.domain() )
168 {
169 if ( result( e ) != 0 )
170 dsets.make_set( e );
171 }
172 trace.endBlock();
173
174 trace.beginBlock( "Merging neighboring sets" );
175 typename Z3i::Point decx( 1, 0, 0 );
176 typename Z3i::Point decy( 0, 1, 0 );
177 typename Z3i::Point decz( 0, 0, 1 );
178
179 // Merging process
180 for ( auto e : result.domain() )
181 {
182 if ( result( e ) != 0 )
183 {
184 if ( result.domain().isInside( e + decx ) &&
185 ( result( e ) == result( e + decx ) ) )
186 dsets.union_set( e, e + decx );
187
188 if ( result.domain().isInside( e + decy ) &&
189 ( result( e ) == result( e + decy ) ) )
190 dsets.union_set( e, e + decy );
191
192 if ( result.domain().isInside( e + decz ) &&
193 ( result( e ) == result( e + decz ) ) )
194 dsets.union_set( e, e + decz );
195 }
196 }
197 trace.endBlock();
198
199 trace.beginBlock( "Counting component sizes" );
200 // counting
201 std::map<Z3i::Point, unsigned int> sizes;
202 for ( auto p : result.domain() )
203 {
204 if ( result( p ) != 0 )
205 {
206 Z3i::Point ref = dsets.find_set( p );
207 sizes[ ref ]++;
208 }
209 }
210 unsigned int maxElement = 0;
211 Z3i::Point maxP;
212 for ( auto i : sizes )
213 {
214 if ( maxElement < i.second )
215 {
216 maxElement = i.second;
217 maxP = i.first;
218 }
219 }
220 trace.info() << "Largest component has " << maxElement << " voxels."
221 << std::endl;
222 trace.endBlock();
223
224 trace.beginBlock( "Cleaning up" );
225 // Cleaning
226 // Merging process
227 Z3i::Point largest = dsets.find_set( maxP );
228 trace.info() << "Largest ref point: " << largest << std::endl;
229 for ( auto e : result.domain() )
230 {
231 if ( result( e ) != 0 )
232 {
233 if ( dsets.find_set( e ) != largest )
234 result.setValue( e, 0 );
235 }
236 }
237 trace.endBlock();
238 trace.endBlock();
239 result >> outputFileName;
240 }
241 return 0;
242}
Definition ATu0v1.h:57