Ask Your Question

How to find dimensions of an object in the image

asked 2018-07-17 01:23:36 -0500

papabiceps gravatar image

I want to find the length of an object in the image (image length not the real physical length). My first idea is was to use boundingRect to find the dimensions, but some of the masks I have split in between them so the boundingRect method fails. Can someone suggest me a robust method to find the length of the object in the given mask

Example mask with split: Mask with split

edit retag flag offensive close merge delete


I have got a simple solution for this problem, I will update tomorrow.

papabiceps gravatar imagepapabiceps ( 2018-07-17 07:51:29 -0500 )edit

I would suggest drawing contours and finding the extreme points as shown here: Then you can just do simple subtracting of the extreme x or y coordinates found to get image length.

accdev gravatar imageaccdev ( 2018-07-18 13:05:04 -0500 )edit

where is the solution,please give a url,3q

jsxyhelu gravatar imagejsxyhelu ( 2018-07-20 07:30:20 -0500 )edit

2 answers

Sort by » oldest newest most voted

answered 2018-07-20 08:04:40 -0500

In my opinion,the point of the problem is "In facet, there is just one contour in the pictures" and there is my solution,I have erct the two region to show the result,you can get the width or height from the code also

image description

int main( int argc, char** argv )
    Mat img = imread("e:/sandbox/1234.png");
    Mat bw;
    bool dRet;
    cvtColor(img, bw, COLOR_BGR2GRAY);
    threshold(bw, bw, 150, 255, CV_THRESH_BINARY);
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    /// 计算矩
    vector<Moments> mu(contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        mu[i] = moments( contours[i], false ); 
    ///  计算中心矩:
    vector<Point2f> mc( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); 
    //connect all contours into ONE
    for (int i = 0; i < contours.size(); ++i)
        Scalar color = Scalar( rng12345.uniform(0, 255), rng12345.uniform(0,255), rng12345.uniform(0,255) );
        drawContours( img, contours, i, color, 2, 8, hierarchy, 0, Point() );
        circle( img, mc[i], 4, color, -1, 8, 0 );
        if (i+1 <contours.size())
    findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    for (int i = 0;i<contours.size();i++)
        RotatedRect minRect = minAreaRect( Mat(contours[i]) );
        Point2f rect_points[4];
        minRect.points( rect_points ); 
        for( int j = 0; j < 4; j++ )
            line( img, rect_points[j], rect_points[(j+1)%4],Scalar(255,255,0),2);
        float fshort = std::min(minRect.size.width,minRect.size.height); //short
        float flong = std::max(minRect.size.width,minRect.size.height);  //long
    return 0;
edit flag offensive delete link more


Elegant Solution !!

papabiceps gravatar imagepapabiceps ( 2018-07-20 12:30:52 -0500 )edit

all right !

jsxyhelu gravatar imagejsxyhelu ( 2018-07-20 18:53:22 -0500 )edit

Thanks for the solution, just in the future, avoid Chinese comments, since this is an English forum.

StevenPuttemans gravatar imageStevenPuttemans ( 2018-07-24 05:03:03 -0500 )edit

all right!

jsxyhelu gravatar imagejsxyhelu ( 2018-07-24 05:26:23 -0500 )edit

answered 2018-07-17 02:39:28 -0500

tibistrat gravatar image

updated 2018-07-17 02:40:32 -0500

  1. You could use cv::findContours to get all the exterior contours of your objects. A contour is in fact a vector of cv::Point, so you could write a function that analyzes contour pairs, looking for the closest 2 points on those contours. You could then use cv::line to draw a small line segment in the image, between those 2 points, on condition that they're not too far from each other. In the end, you re-extract the contours. You can play with the functions in Structural Analysis and Shape Descriptors, like cv::boxPoints to extract interesting properties.

  2. You can dilate the image (cv::dilate) with a radial kernel large enough to bridge the gaps. Then you extract the contours and/or connected components, and when estimating the length, you can subtract the kernel size from whatever measure you obtain.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2018-07-17 01:23:36 -0500

Seen: 4,984 times

Last updated: Jul 20 '18