c++image-processingcomputer-visionmeasurementdiplib

diplib circle measurement


I am trying to measure diameter of holes on the button with DIPlib image processing library. I use GreyDimensionsEllipsoid and Mass to calculate diameter.

GreyDimensionsEllipsoid gave very precise results for hole diameters but Mass gave incorrect measurement results What am I doing wrong? You can see below my code

enter image description here

std::string fname = "/Users/tcc/Documents/ilk/ilk/cam1/125.jpg";
dip::Image img = dip::ImageReadJPEG(fname);

dip::ColorSpaceManager csm;
csm.Convert(img, img, "grey");

dip::Image binary;
dip::FixedThreshold(img, binary, 70, 0, 1);
dip::BinaryAreaOpening(binary, binary, 10000);
binary = ~binary;

dip::Image holes;
dip::EdgeObjectsRemove(binary, holes);

dip::Image labeledHoles;
dip::uint holeQty = dip::Label(holes, labeledHoles);

holes.Convert(dip::DT_UINT8);

dip::ChainCodeArray holeContours = dip::GetImageChainCodes(labeledHoles);

dip::MeasurementTool measurementTool;
auto holeMsr = measurementTool.Measure(
    labeledHoles, labeledHoles,
    { "Mass", "Gravity", "GreyDimensionsEllipsoid", "Circularity" } );

for (dip::uint i = 1; i <= holeQty; i++)
{
    double holeArea = holeMsr[ i ][ "Mass" ][ 0 ] ;
    double holeDiameter = 2 * std::sqrt( holeArea / dip::pi );
    double holeCentroidX = holeMsr[ i ][ "Gravity" ][ 0 ];
    double holeCentroidY = holeMsr[ i ][ "Gravity" ][ 1 ];
    double holeMajorAxis = holeMsr[ i ][ "GreyDimensionsEllipsoid" ][ 0 ]/2;
    double holeMinorAxis = holeMsr[ i ][ "GreyDimensionsEllipsoid" ][ 1 ]/2;
    double holeRoundness = holeMsr[ i ][ "Circularity" ][ 0 ];

    // Output hole measurements

    std::cout << i << " Diplib area base hole diameter : " << std::setprecision(15) << std::sqrt( holeArea / dip::pi ) * 2 << std::endl;
    std::cout << i << " Diplib FitEllips base hole average diameter : " << std::setprecision(15) << (holeMinorAxis+holeMajorAxis) << std::endl;
}

Solution

  • To compute the area, use the “Size” feature (it counts pixels). “Mass” sums the gray-values over the area, and since you input the labeled image as the gray-scale image (the second input to measurementTool.Measure()), what you get is the area multiplied by the label number.