Ask Your Question
1

How to find dimensions of an object in the image

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

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

Comments

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

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

I would suggest drawing contours and finding the extreme points as shown here: https://www.pyimagesearch.com/2016/04... 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 -0600 )edit

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

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

2 answers

Sort by » oldest newest most voted
2

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

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);
    bitwise_not(bw,bw);
    //形态学变化
    dilate(bw,bw,Mat(11,11,CV_8UC1));
    erode(bw,bw,Mat(11,11,CV_8UC1));
    //寻找轮廓
    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 );
        //connect
        if (i+1 <contours.size())
            line(bw,mc[i],mc[i+1],Scalar(255,255,255));
    }
    contours.clear();
    hierarchy.clear();
    //寻找结果
    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
    }
    imshow("img",img);
    waitKey();
    return 0;
}
edit flag offensive delete link more

Comments

Elegant Solution !!

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

all right !

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

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 -0600 )edit
2

all right!

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

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

tibistrat gravatar image

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

  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

Stats

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

Seen: 6,096 times

Last updated: Jul 20 '18