Ask Your Question
2

How to compute intersections of two contours

asked 2014-07-17 03:28:19 -0600

thdrksdfthmn gravatar image

updated 2020-10-23 09:37:33 -0600

I have 2 contours and I want to compare how much the same are they, as the ratio of the area_of_c1/area_of_intersection and area_of_c2/area_of_intersection. I have done in a way of creating 2 convex contours and 2 Mats of zeros and fill them with fillConvexPoly() and doing a bitwise_and() between the two Mats for getting the intersection. Then I have counting the non zeros pixels for getting the areas and computed the ratios. Is there another more efficient way of computing the two ratios (like computing the intersection of two contours, or I do not know)?

edit retag flag offensive close merge delete

Comments

Nope, what you are doing was exactly what I would have suggested.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-17 04:16:46 -0600 )edit
1

Instead of a bitwes_and, I would suggest sum areas, with an image of 1's and an image of 2's (for example) and count 1's, 2's and 3's to get all areas in the same time. But nothing really better I'm afraid… ;-)

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2014-07-17 04:51:36 -0600 )edit

2 answers

Sort by » oldest newest most voted
2

answered 2014-07-17 04:50:49 -0600

Sounds ok. (i guess you now cv::countNonZero). If you have many(!) contours and run into speed or accuracy problems, a specialized library like CGAL https://www.cgal.org/ could help you. You compute an approximation of the intersection area whose accuracy depends on the resolution of the image in which you draw the regions. This can be perfectly fine if your regions are nice (no sharp spikes or one-Pixel regions) but if you get problems, an analytical solution (e.g. as implemented in CGAL) could help.

edit flag offensive delete link more

Comments

I do not think I need that, because I have convex contours. Is fillConvecPoly faster than fillPoly?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-07-17 06:17:22 -0600 )edit
2

http://docs.opencv.org/modules/core/doc/drawing_functions.html#fillconvexpoly

"The function fillConvexPoly draws a filled convex polygon. This function is much faster than the function fillPoly ."

FooBar gravatar imageFooBar ( 2014-07-17 08:18:58 -0600 )edit

shall I use if (cv::isContourConvex(c)) {cv::convexHull(c, cc);} or just cv::convexHull(c, cc);?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-07-17 11:06:17 -0600 )edit
1

answered 2014-07-17 04:49:16 -0600

I don't know if the fillcomplexpolly is computationally heavy or not, so I do it another (very similar) way.

I create a Mask where I draw a rectangle corresponding to the bounding box of the blob, and then use logical "and" between mask and the image with the blobs to segment the blob from everything else. The rest of the process is the same. Try it, I have no idea which method is more optimized.

This code snippet calculates the ration between contour 1 and 2 of blobImage.

    cv::findContours(blobImage, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

    cv::Mat mask1 = cv::Mat::zeros(height, width, CV_8UC1);
    cv::Mat mask2 = cv::Mat::zeros(height, width, CV_8UC1);

    cv::rectangle(mask1, cv::boundingRect(contours[0]), 255, -1, 8 ,0);
    cv::rectangle(mask2, cv::boundingRect(contours[1]), 255, -1, 8 ,0);

    cv::Mat intersection1 = (mask1 && blobImage) // binary image with only with blob 1
    cv::Mat intersection2 = (mask2 && blobImage) // binary image with only with blob 2

    cv::Scalar sum1 = cv::sum(intersection1);
    cv::Scalar sum2 = cv::sum(intersection2);

    double ratio = (sum1[0] / sum2[0]);
edit flag offensive delete link more

Question Tools

Stats

Asked: 2014-07-17 03:28:19 -0600

Seen: 24,484 times

Last updated: Jul 17 '14