在Unity中获得正确的位置

时间:2018-10-02 14:22:56

标签: opencv unity3d

在OpenCV中,检测到某些东西时会显示一个矩形。

Imgproc.rectangle (rgbaMat, new Point (rects [i].x, rects [i].y), new Point (rects [i].x + rects [i].width, rects [i].y + rects [i].height), new Scalar (0, 0, 255, 255), 2);

我想在矩形的一个角上放置一个3D对象或一个立方体实例。

myCube.transform.position = new Vector3(rects[0].x, rects[0].y);

问题在于多维数据集在矩形中的位置不是,但是在变换中它显示了正确的Vector3(float,float,float)。

如何将立方体放置在矩形角的位置?

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题。我想在检测到的对象的中心放置一个 3d 对象。我在 OpenCV 论坛上询问了统一论坛,并得到了开发者的回复。

他们提供了一个包含对我有用的解决方案的软件包。 Overlay a 3D object

在您的情况下,您可以将 DetectFace2DTo3DExample.cs 中的第 68 行更改为您的矩形的位置。

Matrix4x4 point3DMatrix4x4 = Get2DTo3DMatrix4x4 (new Vector2 (rects [0].x, rects [0].y), gameObject);

3d Object Corner Placement

答案 1 :(得分:0)

经过大量研究(所以我不怪你)之后,我发现以下内容是我在this forum中所寻找的:

有一个OpenCv Object detection example

对于您来说,最有趣的方法应该是最底层的方法:

/// <summary>
/// Results the rects to result game objects.
/// </summary>
/// <param name="rects">Rects.</param>
/// <param name="color">Color.</param>
/// <param name="zPos">Z position.</param>
private void ResultRectsToResultGameObjects (IList<object> rects, Color color, float zPos)
{
    Vector3[] resultPoints = new Vector3[rects.Count];

    float textureWidth = GetComponent<Renderer> ().material.mainTexture.width;
    float textureHeight = GetComponent<Renderer> ().material.mainTexture.height;

    Matrix4x4 transCenterM = Matrix4x4.TRS (new Vector3 (-textureWidth / 2, -textureHeight / 2, 0), Quaternion.identity, new Vector3 (1, 1, 1));

    Vector3 translation = new Vector3 (gameObject.transform.localPosition.x, gameObject.transform.localPosition.y, gameObject.transform.localPosition.z);
    Quaternion rotation = Quaternion.Euler (gameObject.transform.localEulerAngles.x, gameObject.transform.localEulerAngles.y, gameObject.transform.localEulerAngles.z);
    Vector3 scale = new Vector3 (gameObject.transform.localScale.x / textureWidth, gameObject.transform.localScale.y / textureHeight, 1);

    Matrix4x4 trans2Dto3DM = Matrix4x4.TRS (translation, rotation, scale);

    for (int i = 0; i < resultPoints.Length; i++) 
    {
        IDictionary rect = (IDictionary)rects [i];

        //get center of rect.
        resultPoints [i] = new Vector3 ((long)rect ["x"] + (long)rect ["width"] / 2, (long)rect ["y"] + (long)rect ["height"] / 2, 0);

        //translate origin to center.
        resultPoints [i] = transCenterM.MultiplyPoint3x4 (resultPoints [i]);

        //transform from 2D to 3D
        resultPoints [i] = trans2Dto3DM.MultiplyPoint3x4 (resultPoints [i]);

        //Add resultGameObject.
        GameObject result = Instantiate (resultPrefab, resultPoints [i], Quaternion.identity) as GameObject;
        result.transform.parent = gameObject.transform;

        result.transform.localPosition = new Vector3 (result.transform.localPosition.x, result.transform.localPosition.y, zPos);
        result.transform.localEulerAngles = new Vector3 (0, 0, 0);
        result.transform.localScale = new Vector3 ((long)rect ["width"] / textureWidth, (long)rect ["height"] / textureHeight, 20);

        result.GetComponent<Renderer> ().material.color = color;

        resultGameObjects.Add (result);
    }
}

当然,我没有进行测试,但看起来确实可以满足您的要求:将对象放置在rects位置。

当然,您将不得不采用它来满足您的需求,但我希望它对您来说是一个很好的起点。