Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bounding Box Filter #94

Closed
threerivers3d-jc opened this issue Jun 7, 2017 · 9 comments
Closed

Bounding Box Filter #94

threerivers3d-jc opened this issue Jun 7, 2017 · 9 comments
Assignees

Comments

@threerivers3d-jc
Copy link
Contributor

I've noticed that the bounding box filter does not work for the z axis. I've got it work on x and y but for some reason it will not apply to the z direction. Any thoughts on why this is happening or what im doing wrong?

@daavoo
Copy link
Owner

daavoo commented Jun 7, 2017

Could you share sample code and data??

@threerivers3d-jc
Copy link
Contributor Author

So I was trying to refine my sphere fits by finding them roughly, creating a bounding box around their min and max then applying another tighter sphere fit to get precise measurements. This is after I've found the sphere center and radius from the initial fit.

x = 0.25
r2 = radius+x 

min_x = center[0] - r2
max_x = center[0] + r2
min_y = center[1] - r2
max_y = center[1] + r2
min_z = center[2] - r2
max_z = center[2] + r2

sphere_cloud_area = pyntcloud.get_filter('BBOX',min_x=min_x, max_x=max_x, min_y=min_y, max_y=max_y, min_z=min_z, max_z=max_z) 
pyntcloud.apply_filter(sphere_cloud_area)

This is the points for the original pointcloud

pyntcloud.points.round(3)
0 24.676001 -1.886000 3.539000 1
1 24.919001 -0.946000 1.775000 1
2 24.919001 -1.088000 1.692000 1
3 25.000000 0.000000 0.000000 1
4 24.676001 -2.168000 3.374000 1
5 24.274000 -3.634000 4.753000 1
6 24.274000 -3.235000 5.033000 1
7 24.919001 -1.222000 1.598000 1
8 24.676001 -2.687000 2.977000 1
9 24.676001 -2.436000 3.186000 1
10 24.919001 -1.348000 1.493000 1
11 24.274000 -4.009000 4.441000 1
12 24.274000 -4.358000 4.099000 1
13 23.712999 -5.767000 5.424000 1
14 23.712999 -5.305000 5.876000 1
15 23.000000 -6.567000 7.273000 1
16 24.919001 -1.465000 1.378000 1
17 24.676001 -2.921000 2.748000 1
18 23.000000 -7.661000 6.110000 1
19 23.000000 -7.138000 6.714000 1
20 22.136000 -9.083000 7.244000 1
21 24.919001 -1.573000 1.254000 1
22 24.919001 -1.670000 1.122000 1
23 24.676001 -3.135000 2.500000 1
24 24.274000 -4.678000 3.730000 1
25 23.712999 -6.571000 4.415000 1
26 23.712999 -6.190000 4.936000 1
27 24.676001 -3.329000 2.236000 1
28 24.274000 -5.222000 2.921000 1
29 24.274000 -4.966000 3.337000 1
... ... ... ...
2898 -18.712999 6.578000 15.217000 1
2899 -15.811000 10.470000 16.291000 1
2900 -14.202000 12.497000 16.344000 1
2901 -12.500000 13.151000 17.198999 1
2902 -6.955000 18.774000 14.972000 1
2903 -6.955000 19.931999 13.392000 1
2904 -5.001000 20.332001 13.660000 1
2905 -3.013000 21.660000 12.115000 1
2906 -1.007000 22.722000 10.377000 1
2907 1.007000 23.493000 8.490000 1
2908 5.001000 24.083000 4.472000 1
2909 6.955000 23.888000 2.445000 1
2910 6.955000 24.007999 0.490000 1
2911 10.717000 22.544001 -1.381000 1
2912 12.500000 21.430000 -3.081000 1
2913 12.500000 21.108000 -4.818000 1
2914 14.202000 19.618999 -6.198000 1
2915 15.811000 18.466000 -5.834000 1
2916 15.811000 17.929001 -7.319000 1
2917 19.986000 12.797000 -7.860000 1
2918 21.129999 10.098000 -8.750000 1
2919 22.136000 8.780000 -7.608000 1
2920 22.136000 8.131000 -8.299000 1
2921 23.000000 6.858000 -6.999000 1
2922 23.000000 6.265000 -7.535000 1
2923 24.274000 3.437000 -4.897000 1
2924 24.274000 3.027000 -5.161000 1
2925 24.676001 2.029000 -3.459000 1
2926 24.676001 1.740000 -3.613000 1
2927 24.919001 0.873000 -1.812000 1

then applying this:

sphere_cloud_area = pyntcloud.get_filter('BBOX',min_x=5, max_x=max_x, min_y=5, max_y=max_y, min_z=5, max_z=max_z) 
pyntcloud.apply_filter(sphere_cloud_area)

pyntcloud.points.round(3)

0 18.712999 9.524000 -13.569000 1
1 17.318001 11.527000 -13.864000 1
2 14.202000 15.549000 -13.474000 1
3 12.500000 17.464001 -12.797000 1
4 8.865000 19.917999 -12.234000 1
5 8.865000 20.849001 -10.570000 1
6 5.001000 22.677999 -9.258000 1
7 5.001000 23.357000 -7.379000 1
8 21.129999 6.759000 -11.526000 1
9 21.129999 7.676000 -10.936000 1
10 19.986000 8.628000 -12.293000 1
11 19.986000 9.601000 -11.548000 1
12 17.318001 13.626000 -11.807000 1
13 17.318001 12.618000 -12.878000 1
14 15.811000 15.620000 -11.446000 1
15 12.500000 18.448999 -11.331000 1
16 8.865000 21.641001 -8.835000 1
17 6.955000 23.410999 -5.343000 1
18 5.001000 23.881001 -5.451000 1
19 6.955000 21.417999 -10.858000 1
20 6.955000 20.462000 -12.568000 1
21 5.001000 21.848000 -11.076000 1
22 5.001000 20.872000 -12.820000 1
23 8.865000 18.855000 -13.817000 1
24 10.717000 18.218000 -13.350000 1
25 8.865000 17.666000 -15.308000 1
26 6.955000 19.368999 -14.194000 1
27 6.955000 18.148001 -15.725000 1
28 5.001000 19.757999 -14.478000 1
29 14.202000 14.399000 -14.696000 1
.. ... ... ... ...
410 21.129999 5.797000 -12.038000 1
411 19.986000 7.598000 -12.955000 1
412 18.712999 10.598000 -12.748000 1
413 15.811000 14.635000 -12.682000 1
414 14.202000 16.596001 -12.161000 1
415 10.717000 19.246000 -11.821000 1
416 10.717000 20.145000 -10.213000 1
417 6.955000 22.232000 -9.076000 1
418 6.955000 22.898001 -7.234000 1
419 22.136000 5.041000 -10.468000 1
420 15.811000 6.952000 -18.073999 1
421 14.202000 7.386000 -19.202999 1
422 12.500000 7.773000 -20.207001 1
423 10.717000 9.800000 -20.350000 1
424 8.865000 10.142000 -21.059999 1
425 5.001000 24.083000 4.472000 1
426 6.955000 23.888000 2.445000 1
427 6.955000 24.007999 0.490000 1
428 10.717000 22.544001 -1.381000 1
429 12.500000 21.430000 -3.081000 1
430 12.500000 21.108000 -4.818000 1
431 14.202000 19.618999 -6.198000 1
432 15.811000 18.466000 -5.834000 1
433 15.811000 17.929001 -7.319000 1
434 19.986000 12.797000 -7.860000 1
435 21.129999 10.098000 -8.750000 1
436 22.136000 8.780000 -7.608000 1
437 22.136000 8.131000 -8.299000 1
438 23.000000 6.858000 -6.999000 1
439 23.000000 6.265000 -7.535000 1

the x and y show >5 but the z does not seem to be applied. I've looked through the bbox filter and see no obvious reason to ignore the z.

@daavoo
Copy link
Owner

daavoo commented Jun 7, 2017 via email

@daavoo daavoo self-assigned this Jun 8, 2017
@daavoo
Copy link
Owner

daavoo commented Jun 8, 2017

Ok. So, In order to reproduce the result I need the full point cloud, the printed output that you are sharing on the commnent does not contain all the points.

If the point cloud is not quite big, you can copypaste all the coordinates in a https://gist.github.com/ and share the link.

I also need to know what is the value of radius.

And finally, if I understand correctly, you are doing this to obtain a refined fit of the sphere.

There should be no need for this refinement once I find some time to solve #29 . This will make ransac to use least squares to fit the model to the best group of inliers found, as last step before returning the result.

@threerivers3d-jc
Copy link
Contributor Author

Ah, sorry about that. The ply file is here. The ideal radius is 9.5, I'm using your library to check the calibration of our 3d scanners and this is an in process check.

I've found so far that the ransac is pretty fast with some loose arguments and then giving it a smaller section of the file with tighter arguments gets the dimensions of it down sub 0.1mm range.

I'll look into the least squares fit, i think i might have some code for it.

@threerivers3d-jc
Copy link
Contributor Author

threerivers3d-jc commented Jun 8, 2017

So I am using this code to get the center and radius after I run the sphere_fit, this might help , I had to track down where I found it.

spX = sphere_cloud.points.x
spY = sphere_cloud.points.y
spZ = sphere_cloud.points.z
            
A = np.zeros((len(spX),4))
A[:,0] = spX*2
A[:,1] = spY*2
A[:,2] = spZ*2
A[:,3] = 1
            
#   Assemble the f matrix
f = np.zeros((len(spX),1))
f[:,0] = (spX*spX) + (spY*spY) + (spZ*spZ)
center, residules, rank, singval = np.linalg.lstsq(A,f)
            
#   solve for the radius
t = (center[0]*center[0])+(center[1]*center[1])+(center[2]*center[2])+center[3]
radius = math.sqrt(t)

@daavoo
Copy link
Owner

daavoo commented Jun 8, 2017

I'm a little busy this week. I'll try to look into this as soon as possible.

In the internal loop, when sphere_fit is fitting the model to the Point Cloud, it generates a instance Sphere from pyntcloud.geometry.sphere. That Sphere has a radius attribute.

Right now the return_model kwarg in ransac.single_fit does not work because of the lack of a least squares fit for the geometry models.

Once this least squares fit is implemented, ransac.single_fit should be able to return a Sphere instance wich will have a radius attribute, no extra computations needed.

@daavoo
Copy link
Owner

daavoo commented Jun 8, 2017

The link looks quite useful. Many thanks! 😄

@daavoo daavoo mentioned this issue Jun 8, 2017
@daavoo
Copy link
Owner

daavoo commented Jun 8, 2017

@threerivers3d-jc

I'm fixing the 'z' coordinate bug of the bbox filter in #95 .

Let's continue the conversation about the least square fitting in #29

@daavoo daavoo closed this as completed in #95 Jun 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants