Ask Your Question
0

How to Prevent drawContours() to draw strange wrong line?

asked 2018-07-01 01:51:56 -0600

eatcosmos gravatar image

updated 2018-07-01 03:38:49 -0600

image description

I have found some rule about this problem, this wrong line connects two point and do not cross any others contour points.

It seams that drawContours prefer convex shape, but I am not very sure about it.

std::vector<std::vector<Point>> collision_for_mask2_contours;

test for this variable, I have put it in bmp image in accessory file , you can get points from it for drawContours. Thank you very much!

G:\test.bmp

int  main(int argc, char* argv[]){

// test code for drawContours

std::vector<std::vector<Point>> collision_for_mask2_contours;
std::vector<Point> constours;
Mat_<uchar> testbmp = imread("G:/test.bmp", WINDOW_AUTOSIZE);
namedWindow("testbmp");
imshow("testbmp", testbmp);
waitKey(0); // need to press any key to continue
for (int y = 0; y < testbmp.rows; ++y) {
    for (int x = 0; x < testbmp.cols; ++x) {
        if (testbmp(y, x)) {
            constours.push_back(Point(x, y));
        }
    }
}
collision_for_mask2_contours.push_back(constours);
Mat_<uchar> testForDrawContours = Mat_<uchar>::zeros(testbmp.size());
// one case, can not get concave shape
drawContours(testForDrawContours, collision_for_mask2_contours, -1, Scalar(255));
namedWindow("testForDrawContours", WINDOW_AUTOSIZE);
imshow("testForDrawContours", testForDrawContours);
waitKey(0);
// one another case, also can not get concave shape
drawContours(testForDrawContours, collision_for_mask2_contours, -1, Scalar(255), -1, 8);
namedWindow("testForDrawContours2", WINDOW_AUTOSIZE);
imshow("testForDrawContours2", testForDrawContours);
waitKey(0);}
edit retag flag offensive close merge delete

Comments

I cannot reproduce your issue. Give full code and check if you can reproduce using image http://answers.opencv.org/upfiles/153...

LBerger gravatar imageLBerger ( 2018-07-01 02:42:20 -0600 )edit

HI @LBerger, I have add test code for test.bmp, and showed the problem, you can test it, thank you. drawContours(testForDrawContours, collision_for_mask2_contours, -1, Scalar(255)); It seams that drawContours treat concave shape as one line.

eatcosmos gravatar imageeatcosmos ( 2018-07-01 03:36:53 -0600 )edit

WINDOW_AUTOSIZE == 1 , wrong flag for imread() anyway. but now you have a 3 channel img,but assign it to a Mat_<uchar>

also, please use findContours() ,and avoid writing per-pixel loops.

again, there is no problem in drawContours(), it's the rest of your code, which is broken

berak gravatar imageberak ( 2018-07-01 04:32:05 -0600 )edit

a contour is not only pixel with non zero value, it is too a sorted list of point : you must follow contour :

for (int y = 0; y < testbmp.rows; ++y) {
    for (int x = 0; x < testbmp.cols; ++x) {
        if (testbmp(y, x)) {
            constours.push_back(Point(x, y)); // IT IS WRONG
        }
    }
LBerger gravatar imageLBerger ( 2018-07-01 05:42:41 -0600 )edit

imread("G:/test.bmp", 1); yes, 1 is right to get gray image.
I find drawContours must be used along with findContours, maybe I have not understand contours and its data structure.

eatcosmos gravatar imageeatcosmos ( 2018-07-01 05:54:26 -0600 )edit

no, IMREAD_GRAYSCALE (0) would be the correct flag here !

berak gravatar imageberak ( 2018-07-01 07:40:55 -0600 )edit

yes, you are right, I find Image file reading and writing

eatcosmos gravatar imageeatcosmos ( 2018-07-01 08:32:56 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-07-01 05:50:54 -0600

berak gravatar image

please use findContours() to get a contour.

your per-pixel loop may gather the same points, but they are in the wrong order (line-scan)

edit flag offensive delete link more

Comments

I understand, Thank you. Can I konw How do you know opencv contours's data structure, I find many things I do not understand and use some very ugly steps to do some things.

eatcosmos gravatar imageeatcosmos ( 2018-07-01 06:08:19 -0600 )edit

maybe looking at the tutorials is helpful

berak gravatar imageberak ( 2018-07-01 07:42:51 -0600 )edit
1

There is no magic, No more than doc and tutorial.

eatcosmos gravatar imageeatcosmos ( 2018-07-01 08:33:22 -0600 )edit

My solution for this requirement is firstly do findContours() for these points and than do drawContours() again, maybe this is time consuming.

eatcosmos gravatar imageeatcosmos ( 2018-07-01 08:36:34 -0600 )edit

Question Tools

Stats

Asked: 2018-07-01 01:51:56 -0600

Seen: 446 times

Last updated: Jul 01 '18