从点云中选择一个点

时间:2015-12-22 17:41:10

标签: java android math point-clouds google-project-tango

谷歌的Project Tango提供了一个点云,即一个浮点缓冲区,其位置xyz为一组以米为单位的点。我希望能够通过在屏幕上触摸来选择其中一个点。

实现这一目标的最佳/最简单方法是什么?

更新

到目前为止我包含了代码,正如我所建议的那样,我尝试在屏幕上获取点的投影,但是在显示点之后我发现我得到的值太小(即0.5,0.7等)。我没有使用统一但是使用android studio,因此我没有使用方法cam.WorldToScreenPoint(m_points [it]),但我确实有一个投影矩阵,但我猜这是不正确的(也许因为我们应该从米到像素)。 实现这一目标的正确矩阵是什么?

private void selectClosestCloundPoint(float x, float y) {
    //Get the current rotation matrix
    Matrix4 projMatrix =  mRenderer.getCurrentCamera().getProjectionMatrix();



    //Get all the points in the pointcloud and store them as 3D points
    FloatBuffer pointsBuffer =  mPointCloudManager.updateAndGetLatestPointCloudRenderBuffer().floatBuffer;
    Vector3[] points3D = new Vector3[pointsBuffer.capacity()/3];

    int j =0;
    for (int i = 0; i < pointsBuffer.capacity() - 3; i = i + 3) {

        points3D[j]= new Vector3(
                pointsBuffer.get(i),
                pointsBuffer.get(i+1),
                pointsBuffer.get(i+2));

        j++;
    }


    //Get the projection of the points in the screen.
    Vector3[] points2D = new Vector3[points3D.length];
    for(int i =0; i < points3D.length-1;i++)
    {
        Log.v("Points", "X: " +points3D[i].x + "\tY: "+ points3D[i].y +"\tZ: "+ points3D[i].z );
        points2D[i] = points3D[i].multiply(projMatrix);
        Log.v("Points", "pX: " +points2D[i].x + "\tpY: "+ points2D[i].y +"\tpZ: "+ points2D[i].z );
    }
}

我使用了vector3,因为它是返回类型,但据我所知,它的第三个组成部分并不重要。

1 个答案:

答案 0 :(得分:2)

使用相机内在函数将3D点云的所有点转换到图像平面上。找到图像平面上所有投影点与屏幕上的触摸坐标之间的距离。从屏幕坐标中选择与最小距离对应的3D点或在阈值内。代码段如下所示

   for (int it = 0; it < m_pointsCount; ++it)
    {
        Vector3 screenPos3 = cam.WorldToScreenPoint(m_points[it]);
        Vector2 screenPos = new Vector2(screenPos3.x, screenPos3.y);
        float distSqr = Vector2.SqrMagnitude(screenPos - touchPos);
        if (distSqr > sqMaxDist)
        {
            continue;
        }
        closePoints.Add(it);
    }

我建议的方法可能在计算上很昂贵。