32 #include "DGtal/base/Common.h"
33 #include "DGtal/base/BasicFunctors.h"
34 #include "DGtal/helpers/StdDefs.h"
35 #include "DGtal/io/readers/VolReader.h"
36 #include "DGtal/io/viewers/Viewer3D.h"
37 #include "DGtal/io/DrawWithDisplay3DModifier.h"
38 #include "DGtal/io/readers/PointListReader.h"
39 #include "DGtal/io/readers/MeshReader.h"
40 #include "DGtal/topology/helpers/Surfaces.h"
41 #include "DGtal/topology/SurfelAdjacency.h"
43 #include "DGtal/io/Color.h"
44 #include "DGtal/io/colormaps/GradientColorMap.h"
45 #include "DGtal/io/readers/GenericReader.h"
47 #include "DGtal/io/readers/DicomReader.h"
50 #include "DGtal/images/ImageSelector.h"
54 #include "specificClasses/Viewer3DImage.cpp"
61 using namespace DGtal;
122 int main(
int argc,
char** argv )
125 typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D;
126 typedef DGtal::ImageContainerBySTLVector<DGtal::Z2i::Domain, unsigned char > Image2D;
130 std::string inputFileName;
131 std::string inputFileNameSDP;
132 std::string inputFileNameMesh;
134 DGtal::int64_t rescaleInputMin {0};
135 DGtal::int64_t rescaleInputMax {255};
137 bool intergrid {
false};
138 bool emptyMode {
false};
139 bool displayDigitalSurface {
false};
140 bool thresholdImage {
false};
141 bool colorizeCC {
false};
142 int thresholdMin {0};
143 int thresholdMax {255};
144 std::vector<unsigned int> vectSDPIndex {0,1,2};
145 std::vector<unsigned int> colorSDP;
146 std::vector<unsigned int> colorMesh;
151 double ballRadius = {0.0};
152 unsigned char transp {255};
155 app.description(
"Displays volume file as a voxel set by using QGLviewer\n 3dImageViewer $DGtal/examples/samples/lobster.vol --thresholdImage -m 180");
157 app.add_option(
"-i,--input,1", inputFileName,
"vol file (.vol, .longvol .p3d, .pgm3d and if WITH_ITK is selected: dicom, dcm, mha, mhd). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." )
159 ->check(CLI::ExistingFile);
161 app.add_flag(
"--grid", grid ,
"draw slice images using grid mode.");
162 app.add_flag(
"--intergrid", grid ,
"draw slice images using inter grid mode.");
163 app.add_flag(
"--emptyMode", emptyMode,
"remove the default boundingbox display.");
164 app.add_flag(
"--thresholdImage", thresholdImage,
"threshold the image to define binary shape");
165 app.add_option(
"--thresholdMin", thresholdMin,
"threshold min to define binary shape",
true);
166 app.add_option(
"--thresholdMax", thresholdMax,
"threshold maw to define binary shape",
true);
167 app.add_option(
"--displaySDP,s",inputFileNameSDP,
"display a set of discrete points (.sdp)" );
168 app.add_option(
"--SDPindex", vectSDPIndex,
"specify the sdp index.")
170 app.add_option(
"--SDPball",ballRadius,
"use balls to display a set of discrete points (if not set to 0 and used with displaySDP option).",
true);
172 app.add_option(
"--displayMesh", inputFileNameMesh,
"display a Mesh given in OFF or OFS format.");
173 app.add_flag(
"--displayDigitalSurface",displayDigitalSurface,
"display the digital surface instead of display all the set of voxels (used with thresholdImage or displaySDP options)" );
175 app.add_flag(
"--colorizeCC", colorizeCC,
"colorize each Connected Components of the surface displayed by displayDigitalSurface option.");
176 app.add_option(
"--colorSDP,-c", colorSDP,
"set the color discrete points: r g b a ")
178 app.add_option(
"--colorMesh", colorMesh,
"set the color of Mesh (given from displayMesh option) : r g b a ")
181 app.add_option(
"--scaleX,-x", sx,
"set the scale value in the X direction",
true );
182 app.add_option(
"--scaleY,-y", sy,
"set the scale value in the Y direction",
true );
183 app.add_option(
"--scaleZ,-z", sy,
"set the scale value in the Z direction",
true );
184 app.add_option(
"--rescaleInputMin",rescaleInputMin,
"min value used to rescale the input intensity (to avoid basic cast into 8 bits image).",
true );
185 app.add_option(
"--rescaleInputMax",rescaleInputMax,
"max value used to rescale the input intensity (to avoid basic cast into 8 bits image).",
true );
186 app.add_option(
"--transparency,-t",transp,
"change the default transparency",
true );
189 app.get_formatter()->column_width(40);
190 CLI11_PARSE(app, argc, argv);
194 QApplication application(argc,argv);
197 string extension = inputFileName.substr(inputFileName.find_last_of(
".") + 1);
210 viewer.setWindowTitle(
"simple Volume Viewer");
212 viewer.setGLScale(sx, sy, sz);
214 typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
215 Image3D image = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
218 Domain domain = image.domain();
220 trace.info() <<
"Image loaded: "<<image<< std::endl;
221 viewer.setVolImage(&image);
224 Z3i::DigitalSet set3d(domain);
226 viewer << Viewer3D<>::updateDisplay;
228 GradientColorMap<long> gradient( thresholdMin, thresholdMax);
229 gradient.addColor(Color::Blue);
230 gradient.addColor(Color::Green);
231 gradient.addColor(Color::Yellow);
232 gradient.addColor(Color::Red);
233 for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
234 unsigned char val= image( (*it) );
235 Color c= gradient(val);
236 if(val<=thresholdMax && val >=thresholdMin)
238 if(!displayDigitalSurface)
240 viewer << CustomColors3D(Color((
float)(c.red()), (
float)(c.green()),(
float)(c.blue()), transp),
241 Color((
float)(c.red()), (
float)(c.green()),(
float)(c.blue()), transp));
251 if(inputFileNameSDP !=
"" ){
252 if(colorSDP.size()==4){
253 Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
254 viewer << CustomColors3D(c, c);
257 vector<Z3i::Point> vectVoxels;
258 if(vectSDPIndex.size()==3)
260 vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP, vectSDPIndex);
263 vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP);
265 for(
unsigned int i=0;i< vectVoxels.size(); i++)
267 if(!displayDigitalSurface)
269 if(ballRadius != 0.0)
271 viewer.addBall (vectVoxels.at(i), ballRadius);
275 viewer << vectVoxels.at(i);
280 set3d.insert(vectVoxels.at(i));
285 if(inputFileNameMesh !=
"")
287 if(colorMesh.size() != 0)
289 Color c(colorMesh[0], colorMesh[1], colorMesh[2], colorMesh[3]);
290 viewer.setFillColor(c);
292 DGtal::Mesh<Z3i::RealPoint> aMesh(colorMesh.size() == 0);
293 MeshReader<Z3i::RealPoint>::importOFFFile(inputFileNameMesh, aMesh);
297 if(displayDigitalSurface)
300 Point low = domain.lowerBound(); low[0]=low[0]-1; low[1]=low[1]-1; low[2]=low[2]-1;
301 Point upp = domain.upperBound(); upp[0]=upp[0]+1; upp[1]=upp[1]+1; upp[2]=upp[2]+1;
302 K.init(low, upp ,
true);
303 SurfelAdjacency<3> SAdj(
true );
304 vector<vector<SCell> > vectConnectedSCell;
305 trace.info() <<
"Extracting surface set ... " ;
306 Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, set3d,
true);
307 trace.info()<<
" [done] " <<std::endl;
308 GradientColorMap<long> gradient( 0, vectConnectedSCell.size());
309 gradient.addColor(DGtal::Color::Red);
310 gradient.addColor(DGtal::Color::Yellow);
311 gradient.addColor(DGtal::Color::Green);
312 gradient.addColor(DGtal::Color::Cyan);
313 gradient.addColor(DGtal::Color::Blue);
314 gradient.addColor(DGtal::Color::Magenta);
315 gradient.addColor(DGtal::Color::Red);
317 viewer << DGtal::SetMode3D(vectConnectedSCell.at(0).at(0).className(),
"Basic");
318 for(
unsigned int i= 0; i <vectConnectedSCell.size(); i++)
320 for(
unsigned int j= 0; j <vectConnectedSCell.at(i).size(); j++)
324 DGtal::Color c= gradient(i);
325 viewer << CustomColors3D(Color(250, 0,0, transp), Color(c.red(),
328 }
else if(colorSDP.size() != 0)
330 Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
331 viewer << CustomColors3D(c, c);
333 viewer << vectConnectedSCell.at(i).at(j);
338 viewer << Viewer3D<>::updateDisplay;
339 DGtal::Z3i::Point size = image.domain().upperBound() - image.domain().lowerBound();
340 DGtal::Z3i::Point center = image.domain().lowerBound()+size/2;
341 unsigned int maxDist = std::max(std::max(size[2], size[1]), size[0]);
342 viewer.camera()->setPosition(qglviewer::Vec(center[0],center[1],
343 center[2] + 2.0*maxDist));
344 viewer.camera()->setSceneCenter(qglviewer::Vec(center[0],center[1],center[2]));
345 return application.exec();