Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试从2D图像精确测量3D距离_C#_Math_Graphics_Xna_Computer Vision - Fatal编程技术网

C# 尝试从2D图像精确测量3D距离

C# 尝试从2D图像精确测量3D距离,c#,math,graphics,xna,computer-vision,C#,Math,Graphics,Xna,Computer Vision,我试图提取出二维图像中两个已知点之间的三维距离,单位为mm。我使用方形AR标记来获得相对于场景中标记的摄影机坐标。这些点是这些标记的角 下面显示了一个示例: 代码是用C#编写的,我使用的是XNA。我正在使用forge.net进行共面假设 我为计算距离而采取的步骤: 1.在屏幕上标记拐角。角点以2D矢量形式表示,图像中心为(0,0)。向上在Y方向为正,向右在X方向为正 2.使用org.net共面定位算法获取每个标记的姿势: float focalLength = 640; //Neede

我试图提取出二维图像中两个已知点之间的三维距离,单位为mm。我使用方形AR标记来获得相对于场景中标记的摄影机坐标。这些点是这些标记的角

下面显示了一个示例:

代码是用C#编写的,我使用的是XNA。我正在使用forge.net进行共面假设 我为计算距离而采取的步骤:

1.在屏幕上标记拐角。角点以2D矢量形式表示,图像中心为(0,0)。向上在Y方向为正,向右在X方向为正

2.使用org.net共面定位算法获取每个标记的姿势:

    float focalLength = 640; //Needed for POSIT
    float halfCornerSize = 50; //Represents 1/2 an edge i.e. 50mm
    AVector[] modelPoints = new AVector3[]
    {
         new AVector3( -halfCornerSize, 0,  halfCornerSize ),
         new AVector3(  halfCornerSize, 0,  halfCornerSize ),
         new AVector3(  halfCornerSize, 0, -halfCornerSize ),
         new AVector3( -halfCornerSize, 0, -halfCornerSize ),
    };
    CoplanarPosit coPosit = new CoplanarPosit(modelPoints, focalLength);
    coPosit.EstimatePose(cornersToEstimate, out marker1Rot, out marker1Trans);
3.转换为XNA旋转/平移矩阵(FORGE使用OpenGL矩阵形式):

4.查找角点的三维坐标:

    //Model corner points
    cornerModel = new Vector3[]
    {
        new Vector3(halfCornerSize,0,-halfCornerSize),
        new Vector3(-halfCornerSize,0,-halfCornerSize),

        new Vector3(halfCornerSize,0,halfCornerSize),
        new Vector3(-halfCornerSize,0,halfCornerSize)
    };

    Matrix markerTransform =  Matrix.CreateTranslation(cornerModel[i].X, cornerModel[i].Y, cornerModel[i].Z);
    cornerPositions3d1[i] = (markerTransform * transform).Translation;

    //DEBUG: project corner onto screen - represented by brown dots
    Vector3 t3 = viewPort.Project(markerTransform.Translation, projectionMatrix, viewMatrix, transform);
    cornersProjected1[i].X = t3.X; cornersProjected1[i].Y = t3.Y;
5.查看标记上两个角之间的3D距离,这表示100毫米。查找将此三维距离转换为100mm所需的比例因子。(我实际上得到了平均比例因子):

for(int i=0;i<4;i++)
{
//距离标度;
距离标度1+=(半角尺寸*2)/矢量3.距离(角位置S3d1[i],角位置S3d1[(i+1)%4]);
}
距离标度1/=4;
6.最后,我找到相关角点之间的3D距离,然后乘以比例因子,得到以mm为单位的距离:

    for(int i = 0; i < 4; i++)
    {
       distance[i] = Vector3.Distance(cornerPositions3d1[i], cornerPositions3d2[i]) * scalingFactor;
    }
for(int i=0;i<4;i++)
{
距离[i]=矢量3.距离(转角位置S3d1[i],转角位置S3d2[i])*缩放因子;
}
获得的距离永远不会真正正确。我使用了砧板,因为它可以让我很容易地计算出距离应该是多少。上图计算出拐角1(红色到紫色)的距离为147mm(预计为150mm)。下图显示为188mm(预计为200mm)

同样令人担忧的是,当测量共享同一标记上的边的标记角之间的距离时,获得的三维距离从来都不相同。我注意到的另一件事是,棕色的圆点似乎永远不会与彩色的圆点完全匹配。彩色点是用作共面位置输入的坐标。棕色点是通过POSIT计算的标记中心的计算位置


有人知道这里可能出了什么问题吗?我在拔头发,想弄明白。代码应该很简单,我认为我没有犯任何明显的错误。我的数学不是很好,所以请指出我的基础数学可能也错在哪里…

你的问题中有很多黑匣子。第二步的焦距是多少?为什么要在步骤3中进行ypr?如何校准?我建议您从头开始,不要使用您不了解的库

步骤1:创建相机模型。理解错误,建立投影。如果需要,为镜头畸变应用2d过滤器。这可能很难

第2步:在消除镜头失真后,在2d中查找标记。确保您知道错误,并获得中心。可能在多个帧上

步骤3:将项目取消到3d。在1和2之后,这应该很容易

第四步:


第五步:盈利!(用3d测量距离,知道你的误差)

我认为你需要3d照片(一组距离中的两张照片)因此,你可以从图像差异中获得视差距离

2D->3D脑海中最明显的是立体视觉。这应该与单个网络摄像头一起工作,因此我在已知目标上使用姿势估计的原因。我认为你从所有计算中得到了大量噪音和舍入误差。XNA数学方法旨在提高速度,而不是准确性。看看使用双打,和/或使用自定义数学函数。我考虑了舍入误差,我尝试手动使用双打计算,但它给出了类似的结果。你检查了镜头像差在你的相机?如果在垂直于图像轴的平面上移动相机,而不旋转它,使对象在图像中改变位置,但在其他情况下保持不变,估计值会发生什么变化?
    for (int i = 0; i < 4; i++)
    {
        //Distance scale;
        distanceScale1 += (halfCornerSize * 2) / Vector3.Distance(cornerPositions3d1[i], cornerPositions3d1[(i + 1) % 4]);
    }
    distanceScale1 /= 4;
    for(int i = 0; i < 4; i++)
    {
       distance[i] = Vector3.Distance(cornerPositions3d1[i], cornerPositions3d2[i]) * scalingFactor;
    }