IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit
// main.cpp:
// ---------
//
//
// --- IPSDK includes
// ------------------
// used to initialize IPSDK environment
#include <IPSDKCore/Config/LibraryInitializer.h>
// used to process shape 3d analysis
#include <IPSDKIPL/IPSDKIPLShapeAnalysis/Measure/Geometry/Basic/HolesBasicPolicyMsrParams.h>
#include <IPSDKIPL/IPSDKIPLShapeAnalysis/Measure/Geometry/FormFactor/MaxFeretDiameter/MaxFeretDiameterMsrParams.h>
#include <IPSDKIPL/IPSDKIPLShapeAnalysis/Measure/Geometry/FormFactor/MinFeretDiameter/MinFeretDiameterMsrParams.h>
#include <IPSDKBaseShapeAnalysis/Measure/BaseMeasure.h>
#include <IPSDKBaseShapeAnalysis/Measure/Result/ValueMeasureResult.h>
#include <IPSDKBaseShapeAnalysis/Measure/Info/MeasureInfoSet.h>
#include <IPSDKBaseShapeAnalysis/Measure/MeasureSet.h>
#include <IPSDKBaseShapeSegmentation/Entity/3d/Shape3dColl.h>
// used to manage exceptions possibly thrown by algoritms functions
#include <IPSDKBaseProcessing/Logger/IPSDKBaseProcessingException.h>
// used to catch exceptions potentially thrown by functions loadTiffImageFile and saveTiffImageFile
#include <IPSDKImageFile/Logger/IPSDKImageFileException.h>
// used to read/write an image from/to a TIFF file:
// used to retrieve usual folders (IPSDK temporary folder, root development folder, etc.)
// used to display log messages
// --- third-party boost includes
// ------------------------------
// boost/filesystem/*: contains functions and classes providing facilities to
// manipulate files and directories, and associated paths
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
// boost/program_options/*: contains functions and classes used to manage and
// interpret arguments of command line
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
// --- third-party log4cplus include
// ---------------------------------
// used to add console as output support of logs
#include <log4cplus/consoleappender.h>
// --- STL include
// ---------------
// for std::cout
#include <iostream>
using namespace boost::filesystem;
using namespace boost::program_options;
using namespace ipsdk;
using namespace ipsdk::geom;
using namespace ipsdk::shape::analysis;
using namespace ipsdk::image;
using namespace ipsdk::image::file;
using namespace ipsdk::imaproc;
using namespace ipsdk::imaproc::advmorpho;
using namespace ipsdk::sample;
bool
readCmdArguments(int argc, char* argv[],
boost::filesystem::path& inputGreyImgPath,
boost::filesystem::path& inputBinImgPath,
boost::filesystem::path& outputCsvResultPath);
int
main(int argc, char* argv[])
{
// add console appender for application logs
log4cplus::SharedAppenderPtr pConsole(new log4cplus::ConsoleAppender);
log4cplus::Logger::getRoot().addAppender(pConsole);
log4cplus::Logger::getRoot().setLogLevel(log4cplus::INFO_LOG_LEVEL);
// initialize IPSDK environment (first call to be done before calling any
// function or using any entity of IPSDK environment)
switch(initRes.getResult().value()) {
case ipsdk::core::eLibInitStatus::eLIS_Warn:
// IPSDK library is initialized but there were warnings;
// notify the user by displaying a message
% initRes.getMsg());
break;
case ipsdk::core::eLibInitStatus::eLIS_Failed:
// IPSDK library initialization; notify the user and exit
return -1;
break;
default:
break;
}
// read program options from command line, and, if appropriate,
// initialize input images files and output csv results paths
boost::filesystem::path inputGreyImgPath, inputBinImgPath, outputCsvResultPath;
if(!readCmdArguments(argc, argv, inputGreyImgPath, inputBinImgPath, outputCsvResultPath))
return -1;
// display a log message in "INFO" level, to notify the user of the current
// step
% inputGreyImgPath.string());
// opening grey level input image
ImagePtr pInGreyImg3d = loadTiffImageFile(inputGreyImgPath, eTiffDirectoryMode::eTDM_Volume);
// display a log message in "INFO" level, to notify the user of the current
// step
% inputBinImgPath.string());
// opening binary input image
ImagePtr pInBinImg3d = loadTiffImageFile(inputBinImgPath, eTiffDirectoryMode::eTDM_Volume);
// connected components analysis
ImagePtr pInLabelImg3d = connectedComponent3dImg(pInBinImg3d);
// extract contours from connected component (label) image
Shape3dCollPtr pShape3dColl = labelShapeExtraction3d(pInLabelImg3d);
// define a measure info set
MeasureInfoSetPtr pMeasureInfoSet = MeasureInfoSet::create3dInstance();
createMeasureInfo(pMeasureInfoSet, "AreaMinusHoles", "Area3dMsr", createHolesBasicPolicyMsrParams(true));
createMeasureInfo(pMeasureInfoSet, "AreaWithHoles", "Area3dMsr", createHolesBasicPolicyMsrParams(false));
createMeasureInfo(pMeasureInfoSet, "VolumeMinusHoles", "Volume3dMsr", createHolesBasicPolicyMsrParams(true));
createMeasureInfo(pMeasureInfoSet, "VolumeWithHoles", "Volume3dMsr", createHolesBasicPolicyMsrParams(false));
createMeasureInfo(pMeasureInfoSet, "EquivalentRay", "EquivalentRayMsr");
createMeasureInfo(pMeasureInfoSet, "SumMsr");
createMeasureInfo(pMeasureInfoSet, "Convexity", "ConvexityMsr", createHolesBasicPolicyMsrParams(true));
// compute measure on extracted data
MeasureSetPtr pOutMeasureSet = shapeAnalysis3d(pInGreyImg3d, pShape3dColl, pMeasureInfoSet);
// retrieve area 3d results for 'minus holes' parametrization for example
const MeasureConstPtr& pAreaMinusHolesOutMsr = pOutMeasureSet->getMeasure("AreaMinusHoles");
const std::vector<ipReal64>& pAreaMinusHolesRes = extractValueResults<ipReal64>(pAreaMinusHolesOutMsr);
// display a log message in "INFO" level, to notify the user of the current
// step
% outputCsvResultPath.string());
// save all analysis results to output csv file
BoolResult bWritten = saveCsvMeasureFile(outputCsvResultPath, *pOutMeasureSet);
if (bWritten == false) {
% outputCsvResultPath.string() % bWritten.getMsg());
return -1;
}
// clearing IPSDK environment features; should be called before exiting
// program
return 0;
}
bool
readCmdArguments(int argc, char* argv[],
boost::filesystem::path& inputGreyImgPath,
boost::filesystem::path& inputBinImgPath,
boost::filesystem::path& outputCsvResultPath)
{
// list of allowed program options
boost::program_options::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("inputGreyImgPath", value<path>(),
"input grey image file path (optional; only TIFF format is accepted)")
("inputBinImgPath", value<path>(),
"input binary image file path (optional; only TIFF format is accepted)")
("outputCsvResultPath", value<path>(),
"output csv result file path (optional)")
;
// vm stores options found in command line
boost::program_options::variables_map vm;
try {
boost::program_options::store(parse_command_line(argc, argv, desc), vm);
} catch(const std::exception& e) {
% e.what());
return false;
}
boost::program_options::notify(vm);
// if the user typed "<app_name>.exe --help"...
if (vm.count("help")) {
// ... the application displays help message
std::cout << desc << "\n";
return false;
}
// initialize input grey image file path with a default file path
inputGreyImgPath = getIPSDKDirectory(eInternalDirectory::eID_Images) / "blobs3d_483x348x31_UInt8.tif";
// if the user specified his own input image file path as argument...
if(vm.count("inputGreyImgPath"))
// ... replace the default one by his own
inputGreyImgPath = vm["inputGreyImgPath"].as<path>();
// initialize input image file path with a default file path
const boost::filesystem::path binRelToRootDir =
path("data") / "Sample" / "images" / "blobs3d_483x348x31_Binary.tif";
// initialize input binary image file path with a default file path
inputBinImgPath = getProjectRootDirectory() / binRelToRootDir;
if(!boost::filesystem::exists(inputBinImgPath))
inputBinImgPath = getIPSDKRootDirectory() / binRelToRootDir;
// if the user specified his own input image file path as argument...
if(vm.count("inputBinImgPath"))
// ... replace the default one by his own
inputBinImgPath = vm["inputBinImgPath"].as<path>();
// initialize output csv results path with a default file path
outputCsvResultPath = getProjectRootDirectory() / binRelToRootDir;
if(vm.count("outputCsvResultPath"))
// ... replace the default one by his own
outputCsvResultPath = vm["outputCsvResultPath"].as<path>();
else {
// ... otherwise, output image will be saved in temporary user directory
const path outputDir =
getIPSDKDefaultDirectory(eDefaultExternalDirectory::eDED_Tmp) /
"Sample";
// if output directory does not exist, we try to create it
if(!boost::filesystem::exists(outputDir)) {
try {
boost::filesystem::create_directories(outputDir);
} catch(const std::exception& e) {
% outputDir % e.what());
}
}
// initialize output csv result path with a default file path
outputCsvResultPath = outputDir / "shapeAnalysis3d.csv";
}
return true;
}