Ask Your Question
0

Moment and Archlength return values - confused

asked 2015-08-07 02:53:46 -0500

zms gravatar image

updated 2015-08-12 03:00:15 -0500

Hello, I had used the moment coding together with the arch length code and found out the number do not match what I had expected. I had an image 500X500 pixel as in this C:\fakepath\ImageTest.png.

Info: Area and Contour Length

  • Contour[0] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.83 - Hu:0.00
  • Contour[1] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.00 - Hu:0.00

For the M00 it state = 0? why 0?? There should be maybe 500 pixel? and the contour found are 2, I may agree due to the two lines in the result window.

The biggest confusion is the arch length value. Why 994? if it is a straight line, it should be the size of the image which is 500 pixels. Can someone show me where should I look on?

FROM DOUBLE POST

Hello, after testing and debugging the code for ImageTest.png using this code I realized that the countours detected are two on the same white area image. This cause the calculation of moments are also 2 for the same white area. My question, why it detect two contours? C:\fakepath\ImageTest.png

Second question, I tried also another type of image which the white area are continuous until at the end of the image as in test.png. running moment code does not reflect the white area as the contour is not detected at the end of the image. Is there any method that I can use for the program to know that the white area is the area that I want to calculate even it had touched the boundary of the image? C:\fakepath\test.png

Here is the image with two white area image description

edit retag flag offensive close merge delete

Comments

Could you create an image in which you show the detected contours (e.g. different colors)

FooBar gravatar imageFooBar ( 2015-08-07 05:43:29 -0500 )edit

If I look in detail, I can see a small point somewhere above the white rectangle... What are the sizes of the contours (aka how many points do each have)?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-08-07 06:05:16 -0500 )edit

You have posted another question earlier. I have already mentioned that your image contains a white small area in the same place as the other image, please review your fake-image generator

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-08-07 06:09:21 -0500 )edit

@FooBar, @thdrksdfthmn, answer as below in the answer section because I need yo upload images... if u hv any comment let me know. I'll also then move to the new thread as per said by @thdrksdfthmn.

zms gravatar imagezms ( 2015-08-10 00:24:20 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
4

answered 2015-08-07 06:45:48 -0500

Use the following code to check what is wrong with your image

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image = imread("/data/fake.png");
    Mat work_image;
    cvtColor(image, work_image, COLOR_BGR2GRAY);
    threshold(work_image, work_image, 0, 255, THRESH_BINARY);
    imshow("binary", work_image); waitKey(0);

    vector< vector<Point> > contours;
    findContours(work_image, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(image, contours, -1, Scalar(0,0,255), 2);

    imshow("contours", image);
    waitKey(0);

    return 0;
}

Which will result into

image description

And where you will see the small dot that is resulting in an extra contour with the wrong info. Since it is closer to the top left top, it gets the first index.

To avoid this, perform a small erode-dilate operation beforehand like this:

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image = imread("/data/fake.png");
    Mat work_image;
    cvtColor(image, work_image, COLOR_BGR2GRAY);
    threshold(work_image, work_image, 0, 255, THRESH_BINARY);
    imshow("binary", work_image); waitKey(0);

    // Erode-dilate
    erode(work_image, work_image, Mat());
    dilate(work_image, work_image, Mat());

    imshow("clean binary", work_image); waitKey(0);

    vector< vector<Point> > contours;
    findContours(work_image, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(image, contours, -1, Scalar(0,0,255), 2);

    imshow("contours", image);
    waitKey(0);

    return 0;
}

And the result

image description

edit flag offensive delete link more

Comments

@StevenPuttemans, your code suggestion is correct. THe original code for my tutorial is here. The thing that I'm confused is the result of momen00 and area for the image above. Here are the result again,

  • Info: Area and Contour Length
  • Contour[0] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.00
  • Contour[1] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.00

if the line contour is only a single line, it should reflect the size of the image right? i.e. 500 pixel as my image is 500X500 size. And the moment00, why it is 0? should it calculate the white area?

Last Q- how do you do the contour drawing to be an exact square? changed my code to reflect yours but only two lines

zms gravatar imagezms ( 2015-08-10 03:15:04 -0500 )edit

I am not sure that moment M_00 is the area ... there is a seperate function for that!

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-11 02:55:09 -0500 )edit
1

As to the drawing, the code is right there!

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-11 02:55:41 -0500 )edit
1

@StevenPuttemans thanks!! i think i understand the code by referring to your example. The moment code had cause some unexpected output compare to yours. Final question before i close the thread. 1) If the white area obtained are two spots, which one will be detected first? From my own image that i have here, the spots lower from the first one will be detected first. Is this correct? I put the image at my question.

Thanks so much!!!

zms gravatar imagezms ( 2015-08-12 02:56:57 -0500 )edit

This python tutorial describes very detailed in what order contours are being returned.

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-12 03:32:31 -0500 )edit
0

answered 2015-08-10 00:21:05 -0500

zms gravatar image

@FooBar, here are the images. For a square you can't see it clearly due to the overlapping contours. But for a circle, you can see it.C:\fakepath\result.JPG. Here is the square.C:\fakepath\result2.JPG. FYI, I had removed the small the white rectangle and still the result is the same, which I'm confused

@thdrksdfthmn, in the result for circle the coutour area size are in the windows. For the square, I jot down the 4 coordinate squares A(115,60), B(373,160), C(373,345),D(115,345). There is no effect on the small white area.

edit flag offensive delete link more

Comments

1

Please, the reason why this is failing has been completely covered in your double post, right here: http://answers.opencv.org/question/68.... I will merge both questions together so you can accept the solution.

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-10 02:13:14 -0500 )edit

Strange that you get 2 areas of almost the same size... Anyway, you should put this in the question, because it is not an answer. If I'll have a little time, I will test it ;)

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-08-10 02:22:32 -0500 )edit
1

Please add your code. I am convinced you are doing something wrong, because even with the new samples, my code works perfectly fine here....

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-10 02:47:46 -0500 )edit

@StevenPuttemans here is the code ...

zms gravatar imagezms ( 2015-08-10 04:31:20 -0500 )edit
2

First remark, the code uses findContours( canny_output, contours, hierarchy, **CV_RETR_TREE**, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); which means that it calculates the hierarchy and inlier and outlier contours. Do you need that? Look at the difference with my code. Nevertheless, I am not convinced that you are doing exactly the same. Can you supply us wit hthe original circle and rectangle image that you use?

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-10 04:35:00 -0500 )edit

@StevenPuttemans, the code that you had shared is correct!! tested and only one contour available. No doubt on that :). The other question remains which had confused me are. I'm using the code shared, edited into the moment code to find contours. 1) The result of the moment and archlegth are not as Iexpected. Im using the same image C:\fakepath\ImageTest.png as above. * Contour[0] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.00 - Hu:0.00 * Contour[1] - Area (M_00) = 0.00 - Area OpenCV: 0.00 - Length: 994.00 - Hu:0.00

I) Is the M_00 must be inside a closed contour? From the ImageTest white area, how can we close the contour? Your code above worked, but once edited into moment, it does not. Only 2 lines.

ii) Why archlength is 994? My image size is 500X500. Should it only ~500?

zms gravatar imagezms ( 2015-08-11 00:02:04 -0500 )edit

@StevenPuttemans In this answer/comment thread, I could not send you the file. May I know how can I do that?

zms gravatar imagezms ( 2015-08-11 00:07:40 -0500 )edit
2

Add it to your original post by the edit button. As to your problems. you are mixing stuff up. Moments is NOT the same as area and lengths....

StevenPuttemans gravatar imageStevenPuttemans ( 2015-08-11 02:56:39 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2015-08-07 02:53:46 -0500

Seen: 521 times

Last updated: Aug 12 '15