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