Kinect - Difference between Depth and Joint Position.Z - c#

It seems to me that both depth and position.z measure the distance between the body parts and the camera.
From what I see in examples and questions, (e.g.) the body parts of the tracked human being can be coloured differently based on how far they are from the camera.
As for the skeleton, the position z is limited to the joints that are available through the SDK.
So in conclusion, both provides the same function but depth is more precise. Am I having the wrong concept on depth or missing out any important points?
*I apologize if this question can be easily found on stackoverflow or on other websites. I couldn't find any pages that could answer my query so I've decided to post here instead.

Depth is trivially calculated per-pixel. Joint.Z is optionally calculated per-joint. Joint calculating has a substantial performance cost because the SDK has to analyze the image to figure out which of those millions of pixels is, for example, your left knee. Joint has the benefit of also getting inferred by the SDK based on its understanding of human anatomy so if your left knee happens to be occluded by a wandering puppy, the Joint position will still be pretty accurate because assumptions are made based on other visible joints.
If you are already doing skeleton tracking for x,y of joints then you might as well take advantage of the z that comes with it but otherwise depth will be more efficient.

Related

Translate Unity units of measurement?

In Unity one can use Raycasting to calculate various measurements. Examples such as diameter, thickness of a wall, and width. One way to do this is by capturing a users mouse click on an object and using RaycastHits to capture the location of the mouse click on the object and than casting additional rays depending on the measurement desired.
Seen below:
Thickness of the walls clicked is .0098, .0096, and .0072. Width is .0615, .0611, and .060. Diameter is .0475.
Though these measurements are (believed to be) executed and calculated correctly it's unclear how the results translate to real world units of measurement.
This is best demonstrated and shown in the fourth image. Checking the same diameter in other CAD programs, such as NX, the diameter is 0.4210" or inches. Thickness and width were calculated as well at .075244" and .252872" respectively.
So than, how do the results in Unity, (results produced using Vector3.Distance to calculate the distance between two points) translate to real world units of measurement?
Googling the subject yields a common answer: Unity's measurements are "game units" and can be used however desired. While I grasp this, I don't understand how to accomplish the translation of "game units", or whatever Unity's units of measurement truly are, to the measurement results I can see in CAD programs.
Results (CAD x Unity):
Thickness: .075244" x .0098, .0096, and .0072.
Width: .252872" x .0615, .0611, and .060.
Diameter: 0.4210" x .0475
(note1: model scales are identical in Unity and external CAD program.)
(note2: the slight variation in thickness and width results from Unity measurements coming at angles where the CAD program is measuring distance between the two planes, i.e. .009x and .06x.)
(note3: ignore the incorrect labeling of Width in the second visual as 'Thickness' and the inch labeling in all of the Unity visuals, ", as both incorrect).
1 Unity unit is generally held to be 1 meter, however as you've read it's up to your implementation, in this case it looks like you're actually exporting from CAD with 1 inch = 1 unit, since your results seem similar but slightly off.
The reason you're getting innaccuracies is most likely due to Unity's collision system not being extremely accurate, most colliders are in fact slightly larger than the mesh they represent which will throw off your fine tuned measurements significantly, and on top of that Unity will have much lower precision than CAD, since Unity is a game engine and needs to perform in realtime, 3D position data is not very accurate (it gets pretty hazy around 4 digits of precision), and in fact gets significantly worse as you travel away from the origin.
I wouldn't recommend trying to use Unity for any kind of precise design work, especially when representing the real world, but if you're dead set, you might want to scale your objects up by a factor of 10 or 100 in order to keep your digits closer to the decimal point to reduce floating point error, this is a hack obviously.
You may want to also look at your physics settings: https://docs.unity3d.com/Manual/class-PhysicsManager.html
In particular "Default Contact Offset" may be relevant (although I'm not sure if it affects raycasts)
PS: I'd post this as a comment but the rep system won't let me, your description of the measurements between each environment is really confusing, next time maybe try and format it in a table or something?

3D surface reconstruction by preserving point position

I have 3D point clouds and want to reconstruct the surface. I tried various techniques in Meshlab to find the algorithm that best suits my specific kind of cloud.
The poisson surface reconstruction is very promising, but it does not preserve the original point position. After reconstruction and measuring at specific positions in the cloud it turned out that the measurements are off by a factor of over 1.5 compared to measurements on the object in the real world.
The ball pivoting algorithm is better. It preserved the position of the points and the measurements were also within the expected range. However this algorithm is patented in the USA so I can't use it for a commercial project.
After researching other algorithms, I did not find any that preserve the point position like ball pivoting which could be used in a commercial environment. Do you know algorithms that fulfill these two criteria and which I could try with my point cloud to see if they work well before implementing them?
Any help would be appreciated.
For interpolating surface reconstruction (that keeps the datapoints), two algorithms perform reasonably well (crust and co-cone).
Crust algorithm:
The idea is to first compute the Voronoi diagram of the pointset, then select from the Voronoi vertices the ones that are a good approximation of the medial axis (called the poles), then compute the 3D Delaunay triangulation of the input points + the poles, and finally extract the triangles that connect three input points in a tetrahedron where the fourth vertex is a pole.
More references:
http://web.cs.ucdavis.edu/~amenta/pubs/crust.pdf
http://web.mit.edu/manoli/crust/www/crust.html
plus: quite simple to implement, some theoretical guarantees if input data is a good sampling
minus: requires to compute two Delaunay triangulations
Co-cone algorithm:
The idea is to compute the Voronoi diagram of the pointset, and then in each Voronoi cell compute a good approximation of the normal to the surface (as the vector that connect the poles, i.e. the two Voronoi vertices furthest away from the datapoint). Then in each Voronoi cell one considers the complement of a cone (co-cone) centered on the datapoint and having the normal as an axis. If three co-cones have a non-empty intersection with a Voronoi edge, then the three datapoints are connected with a triangle. Note that the co-cone objects do not need to be constructed explicitely (just angles need to be compared in order to test whether there is an intersection).
More references:
http://web.cse.ohio-state.edu/~tamaldey/surfrecon.htm
Plus: requires a single Delaunay triangulation (compared to 2 for the Crust), some theoretical guarantees if the input data is a "good sampling"
Minus: a little bit more complicated than the crust (but worth the effort I think)
Some final words:
These algorithms construct a good (i.e. manifold) surface if the point set realises a good sampling (i.e. density proportional to thickness and curvature, something called "local feature size" = distance to medial axis). In practice, the input data does not satisfy this condition, therefore the output of the method will be a "soup of triangles" that will be mostly OK but that will require some post-processing to fix some local defects.
Edit 03/21/16 You may also try my own algorithm (Co3Ne), implemented in my software library Geogram (http://alice.loria.fr/software/geogram/doc/html/index.html) and my software Graphite (http://alice.loria.fr/software/graphite/doc/html/). Graphite can be downloaded there: http://gforge.inria.fr/frs/?group_id=1465 (both portable source code and Windows64 executable). It is a form of Co-cone with various optimizations and parallel implementation.

How can you stitch multiple heightmaps together to remove seams?

I am trying to write an algorithm (in c#) that will stitch two or more unrelated heightmaps together so there is no visible seam between the maps. Basically I want to mimic the functionality found on this page :
http://www.bundysoft.com/wiki/doku.php?id=tutorials:l3dt:stitching_heightmaps
(You can just look at the pictures to get the gist of what I'm talking about)
I also want to be able to take a single heightmap and alter it so it can be tiled, in order to create an endless world (All of this is for use in Unity3d). However, if I can stitch multiple heightmaps together, I should be able to easily modify the algorithm to act on a single heightmap, so I am not worried about this part.
Any kind of guidance would be appreciated, as I have searched and searched for a solution without success. Just a simple nudge in the right direction would be greatly appreciated! I understand that many image manipulation techniques can be applied to heightmaps, but have been unable to find a image processing algorithm that produces the results I'm looking for. For instance, image stitching appears to only work for images that have overlapping fields of view, which is not the case with unrelated heightmaps.
Would utilizing a FFT low pass filter in some way work, or would that only be useful in generating a single tileable heightmap?
Because the algorithm is to be used in Unit3d, any c# code will have to be confined to .Net 3.5, as I believe that's the latest version Unity uses.
Thanks for any help!
Okay, seems I was on the right track with my previous attempts at solving this problem. My initial attemp at stitching the heightmaps together involved the following steps for each point on the heightmap:
1) Find the average between a point on the heightmap and its opposite point. The opposite point is simply the first point reflected across either the x axis (if stitching horizontal edges) or the z axis (for the vertical edges).
2) Find the new height for the point using the following formula:
newHeight = oldHeight + (average - oldHeight)*((maxDistance-distance)/maxDistance);
Where distance is the distance from the point on the heightmap to the nearest horizontal or vertical edge (depending on which edge you want to stitch). Any point with a distance less than maxDistance (which is an adjustable value that effects how much of the terrain is altered) is adjusted based on this formula.
That was the old formula, and while it produced really nice results for most of the terrain, it was creating noticeable lines in the areas between the region of altered heightmap points and the region of unaltered heightmap points. I realized almost immediately that this was occurring because the slope of the altered regions was too steep in comparison to the unaltered regions, thus creating a noticeable contrast between the two. Unfortunately, I went about solving this issue the wrong way, looking for solutions on how to blur or smooth the contrasting regions together to remove the line.
After very little success with smoothing techniques, I decided to try and reduce the slope of the altered region, in the hope that it would better blend with the slope of the unaltered region. I am happy to report that this has improved my stitching algorithm greatly, removing 99% of the lines reported above.
The main culprit from the old formula was this part:
(maxDistance-distance)/maxDistance
which was producing a value between 0 and 1 linearly based on the distance of the point to the nearest edge. As the distance between the heightmap points and the edge increased, the heightmap points would utilize less and less of the average (as defined above), and shift more and more towards their original values. This linear interpolation was the cause of the too step slope, but luckily I found a built in method in the Mathf class of Unity's API that allows for quadratic (I believe cubic) interpolation. This is the SmoothStep Method.
Using this method (I believe a similar method can be found in the Xna framework found here), the change in how much of the average is used in determining a heightmap value becomes very severe in middle distances, but that severity lessens exponentially the closer the distance gets to maxDistance, creating a less severe slope that better blends with the slope of the unaltered region. The new forumla looks something like this:
//Using Mathf - Unity only?
float weight = Mathf.SmoothStep(1f, 0f, distance/maxDistance);
//Using XNA
float weight = MathHelper.SmoothStep(1f, 0f, distance/maxDistance);
//If you can't use either of the two methods above
float input = distance/maxDistance;
float weight = 1f + (-1f)*(3f*(float)Math.Pow(input, 2f) - 2f*(float)Math.Pow(input, 3f));
//Then calculate the new height using this weight
newHeight = oldHeight + (average - oldHeight)*weight;
There may be even better interpolation methods that produce better stitching. I will certainly update this question if I find such a method, so anyone else looking to do heightmap stitching can find the information they need. Kudos to rincewound for being on the right track with linear interpolation!
What is done in the images you posted looks a lot like simple linear interpolation to me.
So basically: You take two images (Left, Right) and define a stitching region. For linear interpolation you could take the leftmost pixel of the left image (in the stitching region) and the rightmost pixel of the right image (also in the stitching region). Then you fill the space in between with interpolated values.
Take this example - I'm using a single line here to show the idea:
Left = [11,11,11,10,10,10,10]
Right= [01,01,01,01,02,02,02]
Lets say our overlap is 4 pixels wide:
Left = [11,11,11,10,10,10,10]
Right= [01,01,01,01,02,02,02]
^ ^ ^ ^ overlap/stitiching region.
The leftmost value of the left image would be 10
The rightmost value of the right image would be 1.
Now we interpolate linearly between 10 and 1 in 2 steps, our new stitching region looks as follows
stitch = [10, 07, 04, 01]
We end up with the following stitched line:
line = [11,11,11,10,07,04,01,02,02,02]
If you apply this to two complete images you should get a result similar to what you posted before.

Adding metresc distance to Long/Lat e6

Sorry if this has been asked before. I've looked at posts about Haversine and ellipsoids.
I have two points in 1e6 google maps geopoint format that define a directed vector.
I need to create an OABB (object-aligned bounding box) for the directed vector. Easily done by calculating the normals (-y,x), (y,-x). The only issue is that the length of the normalized vectors defines the width of the OABB.
Say for instance, I want these normals to be 20 km long...
So I need to scale the normals by 20km, but I have no idea how to do this in the 1e6 format that the Geopoint class uses.
If someone could post some code on how to add metre values to geopoints, I would love them.
Cheers.
Craig.
Found the answer here -> https://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters
Not before I worked out the damned thing myself though by using the radius of the earth and some simple trig. While I am a competent enough mathematician to do this, I shouldn't have to.
(rant) What are Google playing at? It's obvious that GMap developers are going to need to do vector arithmetic on Geopoint and Location, they should have built-in vector operators. (/rant)

Looking for pathing algorithms for maps without edges

I have 2D world maps that are basically Mercator-Like projections, (If you walk west long enough you end up east of where you started)
Question I have: Can you use A* for computing paths on these types of maps as well?
I can't think of any reason why you couldn't (I'm thinking that you would simply represent the edge map nodes such that the North, South, East, Wed, "border" nodes simply connected to the opposite side).
Thanks in advance, if anyone has seen something like this before or can give me a few hints I would appreciate it.
Pathfinding algorithms don't really care about global topology of the map. The only tricky part is to get a good estimator for A* but using the 3D distance should be ok if your map is indeed a surface in a 3d space and step cost is step length.
Your map can have all sort of strange "connections" (including for example knotted bridges) and this will not be a problem if you implement A* correctly.
I can't imagine why a Mercator-Like projections would cause a problem for A*, as long as your heuristic function approximates distances correctly. I think something along the below function should work fine
float heuristic(point from, point to, size mapsize) {
float x = from.x - to.x;
if (abs(x) > mapsize.x/2)
x = mapsize.x - x;
float y = from.y - to.y;
if (abs(y) > mapsize.y/2)
y = mapsize.y - y;
return sqrt(x*x+y*y);
}
Edited: I realize know I was misled by the non-graph theoretical) use of the word edge (where the question title strongly suggested a graph algorithm question :))
Why do you suppose there are no edges? There are many logical discrete locations that you could model, and limited connections between (i.e. not where a wall is :)). There you go: you have your edges.
What you probably mean is that you don't want to represent your edges in data (which you don't have to, but still there are the logical edges that connect locations/points.)
That said:
you ask whether someone has seen things like this before. I vaguely recall seeing something relevant to this in Knuths Dancing Links article (DLX) which is an implementation technique for A* algorithms.
http://en.wikipedia.org/wiki/Dancing_Links
original publication [PDF]
The article specifically treats states as 'cells' (in a grid) with east/west/north/south links. It's been a long time so I don't quite recall how you would map (no pun intended) your problem on that algorithm.
The dance steps. One good way to implement algorithm X is to represent each 1 in the
matrix A as a data object x with five fields L[x]; R[x]; U [x]; D[x]; C[x]. Rows of the matrix
are doubly linked as circular lists via the L and R fields ("left" and "right"); columns are
doubly linked as circular lists via the U and D fields ("up" and "down"). Each column
list also includes a special data object called its list header.

Categories

Resources