mp3guy/ICPCUDA

Drift in transformations

Opened this issue · 2 comments

Hey Tom,

I picked your original code and tried with just 2 depth maps, the transform values I got when processing the first depth map with the second is not nearly the inverse of when processing the second depth map with first. Below is the result:

Transformation output when using depth 0-1.txt:
1305031453.404816 0.00677987 0.00253431 -0.00944612 -0.00188307 0.00523863 0.00920236 0.999942

Transformation output when using depth 1-0.txt:
1305031453.374112 -0.00741758 -0.00220185 0.00926915 0.00199852 -0.0049043 -0.00883814 0.999947 (This should be nearly inverse of above)

I also tried adding First and Second depth maps one after other multiple times, and I can see the drift in the output.

You can check these input maps in depth.txt and results in output.poses.txt The drift can be seen in output at line: 1, 3, 5. Ideally, line 2, 4, 6 should be close to identity.

Do you have any advice regarding this ? and which part of ICP should I look to resolve it ?
I am facing this same drift problem when using it with real-time data.

I would guess the asymmetry is due to the rounding occurring during pixel transfer here https://github.com/mp3guy/ICPCUDA/blob/master/src/Cuda/estimate.cu#L163.

You could try implementing a bilinear interpolation there but I'm not sure how well defined that is, especially around discontinuities. Alternatively you could make a bidirectional cost function which if done right will be fully symmetric.

Also the method used for pyramid generation probably isn't the best either.

But anyway, I'm not sure why you're running things forwards and backwards, but depending on your data quality you're going to get drift if you're incrementally estimating motion anyway. Especially if all you're using is raw primesense depth maps.

For now, instead of processing the second depth map with first, I fixed this by taking the inverse of the transformation of the first depth map with second. The reason I did this test was for real-time registration of a static (that actually will never be static) object which was giving a drift otherwise.