# Calc the Seconds moments of area of huge number of countours

Hello! Finally I was able to properly fit he mesh with the layer. For this image (7158x16392 8MB)

I need to calculate the percentage of blacks and browns per triangle, and also the seconds moments of area per triangle. I'm facing some problems. The mesh layer should always be the master. For instance, If I have a triangle with all black, it should return 100% empty and without second moments.

So, I'm facing some problems to find out the proper bit-wise function, which allows me to make the mesh being the "master", and then I don't know how to iterate over a such huge amount of contours and make the calcs. I think the second moments which are native supported by opencv are the seconds moments of inertia, not the second moments of area..

edit retag close merge delete

( 2016-06-17 19:17:25 -0500 )edit

@sturkmen , what is big ? :)

( 2016-06-20 03:45:21 -0500 )edit

8mb is "too big".

( 2016-08-04 01:36:29 -0500 )edit

Sort by ยป oldest newest most voted

The moments function calculates a weighted moment based on the intensity UNLESS you pass the binary image parameter as true. Then it's the same.

I'm not quite sure what you mean by using the triangle mesh as a master. I think you mean you have each triangle as either white or black. In that case, you need to either do bitwise_and to keep the triangles that are white, or do a bitwise_not to switch the white and black, then the and.

It would help if you made a small picture with say, 8 triangle and a square or circle on the other layer to show what you expect.

EDIT: Here's a practice image small enough to look at every pixel if you need to.

more

link text I've cut a litle piece. I want to calculate the volumes and the second moments of intertia of each triangle. I've put some numbers just to have an example. So, the number 1 has 0% of Volume, it's empty, the seconds moments are null. The number 2 has 100% of volume, second moments would have big values. Number 3 would have 60% of volume more or less, and the second moments would be intermediate. Number 4 it's a big hole, I don't want to calc anything.

I think it's clearer what I'd like to calculate.

( 2016-06-20 05:03:49 -0500 )edit

Ok. So you need to do some pre-processing on your triangle mask. Threshold it, so you have lines of 255 separating your black triangles. Then do a bitwise_not to invert that. Now you have a separate areafor each. Run connectedComponents to get a different label for each area.

For your other image, convert it to a binary image.

Now, one by one, use inRange to extract a single triangle from the label image as a mask. Then do a bitwise_and with your floorplan layer. This leaves the only the area that is above zero within that triangle. Now call moments with the binary flag on, and that's the results for this triangle. To calculate percentages, you'll need to also use moments on the triangle mask after you've extracted just one triangle, to compare to the total area.

( 2016-06-20 07:39:07 -0500 )edit

@Tetragramm It's not easy. Should I keep all the mesh contours in white? Or some in white and others in black? Could I use other color to all mesh, and then calculate moments?

( 2016-07-19 05:19:44 -0500 )edit

another alternative approach. If I have the mesh and the "layer" where the mesh is. Is it easier to isolate? Mesh image: https://dl.dropboxusercontent.com/u/7... Layer image: https://dl.dropboxusercontent.com/u/7... code: http://pastebin.com/Q3sN5akv

( 2016-07-20 04:38:05 -0500 )edit

@Tetragramm is it something like this that is need to calc the moments per triangle? https://dl.dropboxusercontent.com/u/7...

( 2016-07-20 08:19:18 -0500 )edit

Not quite. Take your Mesh image there, and use Connected Components to get a label for each triangle.

Then extract just one triangle from the image.

You should have a single white triangle, and the rest black. Make a copy of your layer image and use bitwise_and with the single triangle to erase everything but what is inside that triangle.

Now you have a small amount of layer left. Calculate the moments, and that gives you one triangle.

Repeat for every connected component.

( 2016-07-20 21:42:36 -0500 )edit

@Tetragramm the connectComponents function is not available in python :\ Any alternative, or I should just implement in C++ ? It won't be easy to me, I'm used to use opencv python

( 2016-07-21 03:57:48 -0500 )edit

It should be available. It's used in THIS python tutorial.

( 2016-07-21 07:50:05 -0500 )edit

@Tetragramm you've said " Make a copy of your layer image and use bitwise_and with the single triangle to erase everything but what is inside that triangle." How can I select just one triangle for each time. I think that I'm understanding the process. Having n-masks, one for each triangle. Then for each mesh-triangle I can calc moments, centroids, etc . However. I don't get the "process" to reach it.

( 2016-07-22 05:59:40 -0500 )edit

Well, in the label image that returns from connected components, each triangle has a different label. You can use several methods, the simplest of which is compare.

There's an easy way to call it: Mat singleTriangle = (everyTriangle == labelNumber);

( 2016-07-22 09:58:46 -0500 )edit

Official site

GitHub

Wiki

Documentation