Custom Analysis
This example shows how to set the attributes of a measurement and how to create a new measurement from a user defined formula.
Several native measurements of ImageDev can be customized by setting some parameters. For instance, the
orientation of the Feret diameters to be computed can be user-defined. By default, the Feret diameter
measurement contains 10 orientations with a pitch of 18 degrees.
This example shows first how to reduce these orientations to 0 and 90 degrees by selecting two diameters and resampling the distribution between 0 and 180 degrees. The setOrientation method can also be used for this purpose, especially if the expected distribution is not uniform.
Then, this example shows how to create a new measurement from a user-defined formula corresponding to a circularity factor. The validity of the formula is checked, and the new measurement is selected in the analysis.
See also
This example shows first how to reduce these orientations to 0 and 90 degrees by selecting two diameters and resampling the distribution between 0 and 180 degrees. The setOrientation method can also be used for this purpose, especially if the expected distribution is not uniform.
Then, this example shows how to create a new measurement from a user-defined formula corresponding to a circularity factor. The validity of the formula is checked, and the new measurement is selected in the analysis.
#include <ImageDev/ImageDev.h> #include <ioformat/IOFormat.h> #include <string.h> using namespace imagedev; using namespace ioformat; using namespace iolink; int main( int argc, char* argv[] ) { int status = 0; try { // ImageDev library initialization if not done if ( isInitialized() == false ) imagedev::init(); // Open a grayscale image from a tif file auto imageInput = readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "objects.tif" ); // Threshold and label the binary input auto imageBin = thresholdingByCriterion( imageInput, ThresholdingByCriterion::ComparisonCriterion::GREATER_THAN_OR_EQUAL_TO, 40 ); auto imageLab = labeling2d( imageBin, Labeling2d::LABEL_8_BIT, Labeling2d::CONNECTIVITY_8 ); // Change the number of Feret diameter to 2 (0 and 90 degrees) MeasurementAttributes::feret2d()->setOrientationCount( 2 ); MeasurementAttributes::feret2d()->resample(); std::cout << "FeretDiameter[0] = " + std::to_string( MeasurementAttributes::feret2d()->orientation( 0 ) ) << std::endl; std::cout << "FeretDiameter[1] = " + std::to_string( MeasurementAttributes::feret2d()->orientation( 1 ) ) << std::endl; // Create a circularity factor between 0 and 1 std::string myFormula( "4*Pi*" + NativeMeasurements::area2d->name() + "/" + NativeMeasurements::polygonePerimeter2d->name() + "**2" ); if ( !checkMeasurementFormula( myFormula ) ) // Raise an exception if the formula is not valid throw imagedev::Exception( "Invalid formula: " + myFormula ); const auto* myCircularity = AnalysisMsr::registerCustomMeasurement( "MyCircularity", myFormula, "A circularity factor between 0 and 1." ); // Define the analysis features to be computed AnalysisMsr::Ptr analysis = std::make_shared< AnalysisMsr >(); analysis->select( NativeMeasurements::feretDiameter2d ); analysis->select( myCircularity ); // Launch the feature extraction on the segmented image labelAnalysis( imageLab, imageInput, analysis ); // Export the analysis in a dataframe and save it in a csv file auto dataframe = analysis->toDataFrame(); writeView( dataframe, "T04_04_analysis.csv" ); std::cout << "This example ran successfully." << std::endl; } catch ( const imagedev::Exception& error ) { // Print potential exception in the standard output std::cerr << "T04_05_CustomAnalysis exception: " << error.what() << std::endl; status = -1; } // ImageDev library finalization imagedev::finish(); // Check if we must ask for an enter key to close the program if ( !( ( argc == 2 ) && strcmp( argv[1], "--no-stop-at-end" ) == 0 ) ) std::cout << "Press Enter key to close this window." << std::endl, getchar(); return status; }
See also