Ask Your Question
1

Can I resize a contour?

asked 2014-10-16 10:28:16 -0600

thdrksdfthmn gravatar image

updated 2015-10-05 13:24:22 -0600

I have an application that detects an object by finding its contour. Because the image where I search for the object may be at a very big scale is affecting my detection because the contour can be too long and I skip the contours longer than a threshold. For fixing this, I have thought of resizing the image larger than a maximum size to that maw size. Doing so, I am detecting the object in the smaller image, and when drawing the contour on the initial image, I am getting a "wrong detection". Is there a possibility to resize the contour?

edit retag flag offensive close merge delete

Comments

Hmm afaik contours are actually for visualisation purposes and for creating masks. Resizing them will not be that easy. How about the following approach

  1. Use the contour to make a binary mask.
  2. Apply a resize operation on that binary mask, which is possible since it is a data matrix.
  3. Now use findContours again on that binary image to change it back to an active contour.

Would this suit your needs?

StevenPuttemans gravatar imageStevenPuttemans ( 2014-10-17 04:33:51 -0600 )edit
1

If I just do the (x, y) -> (resizer * x, resizer * y) is not correct? Actually I am trying to test this. (x and y are both positive)

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-10-17 05:02:20 -0600 )edit
1

That was my first tought. But I am not sure if this will actually work for each point. You should test and report back :)

StevenPuttemans gravatar imageStevenPuttemans ( 2014-10-17 05:48:25 -0600 )edit

Great! Yeah my approach suffers from artefacts ... hadn't thought on that...

StevenPuttemans gravatar imageStevenPuttemans ( 2014-10-17 08:36:22 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
2

answered 2014-10-17 08:21:25 -0600

thdrksdfthmn gravatar image

updated 2015-10-05 14:06:23 -0600

Nice, it is working, and it is working very nice. More, your idea of resizing the mask is introducing errors, because the cv::fillPoly is introducing errors (small "stairs") and resizing it is just making the errors to appear in the new contour, and they are even bigger.

Sample code :

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;

int main( int argc, char** argv )
{
    vector<vector<Point> > contours;
    Mat img = Mat::zeros( 500, 500, CV_8UC1 );

    circle( img, Point(250,250), 100, Scalar(255) );

    findContours( img, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

    fillConvexPoly( img, Mat( contours[0] ) / 2, Scalar(255)); // draws contour resized 1x/2

    polylines( img, Mat( contours[0] ) * 2, true, Scalar(255)); // draws contour resized 2x

    imshow("result",img);
    waitKey();

    return 0;
}

result image:

image description

edit flag offensive delete link more
3

answered 2018-04-13 10:06:26 -0600

updated 2018-04-13 23:57:23 -0600

You can use the following method to resize the contour by keeping the contour center like the morphology operation.

void contourOffset(const Contour& src, Contour& dst,const cv::Point& offset) {
    dst.clear();
    dst.resize(src.size());
    for (int j = 0; j < src.size(); j++)
        dst[j] = src[j]+ offset;

}
void scaleContour(const Contour& src, Contour& dst, float scale)
{
    cv::Rect rct = cv::boundingRect(src);

    Contour dc_contour;
    cv::Point rct_offset(-rct.tl().x, -rct.tl().y);
    contourOffset(src, dc_contour,rct_offset);

    Contour dc_contour_scale(dc_contour.size());

    for (int i = 0; i < dc_contour.size(); i++)
        dc_contour_scale[i] = dc_contour[i] * scale;

    cv::Rect rct_scale = cv::boundingRect(dc_contour_scale);

    cv::Point offset((rct.width - rct_scale.width)/2, (rct.height - rct_scale.height)/2);
    offset -= rct_offset;
    dst.clear();
    dst.resize(dc_contour_scale.size());
    for (int i = 0; i < dc_contour_scale.size(); i++)
        dst[i] = dc_contour_scale[i] + offset;
}

void scaleContours(const Contours& src, Contours& dst, float scale)
{
    dst.clear();
    dst.resize(src.size());
    for (int i = 0; i < src.size(); i++)
        scaleContour(src[i], dst[i], scale);
}
    void main(){
        std::vector<std::vector<cv::Point>> src,dst;
        scaleContours(src,dst,0.95);
     }

In the sample below, the green contour is main contour and the red contour is scaled contour with a coefficient of 0.95. image description

edit flag offensive delete link more

Comments

1

nice to have you back here ;)

berak gravatar imageberak ( 2018-04-13 10:11:17 -0600 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2014-10-16 10:28:16 -0600

Seen: 5,121 times

Last updated: Apr 13