开发者

Projecting an object into a scene based on world coordinates only

I want to place a 3D image into a scene base on world/global coordinates. I have an image of a scene. The image was captures at some global coordinate (x1, y1, z1). I am given an object that needs to be placed into this scene based on its global coordinate (x2, y2, y3). This object needs to be projected into the scene accurately similarly to perspective projection.

An example may help to make this开发者_如何学Go clear. Imagine there is a parking lot with some set of global coordinates. A picture is taken of a portion of the parking lot. The coordinates from the spot where the image was taken is recorded. The goal is to place a virtual vehicle into this image using the global coordinates for that vehicle. Because the global cooridnates for the vehicle may not be in the fov of the global coordinates for the image I am assuming that I will need the image coordinates, angle and possibly fov.

3D graphics is not my area so I have been looking at http://en.wikipedia.org/wiki/Perspective_projection#Perspective_projection. I have also been looking at Matrix3DProjection which seems to possibly be what I am looking for but it only works in Silverlight and I am trying to do this in WPF. In my mind it appears I need to determine the (X,Y,Z) coordinates that are in the fov of the image, determine the world coordinate to pixel conversion and then accurately project the vehicle into the image giving it the correct perspective such that is looks 3D i.e smaller the further away bigger closer

Is there a function within WPF that can help with this or will I need to re-learn matrices and do this by hand?


I'm not sure I understand why this is difficult. If I'm understanding you right, all you need to do is set the transforms on your Model3D objects. I assume you are alreay have Model3D objects for your car model (either Model3DGroup or GeometryModel3D). Here is how you would combine this with your scene image:

  1. Use whatever coordinates are convenient on the Model3D representing your car model, then add a Transform3DGroup consisting of a ScaleTransform3D, a RotateTransform3D, and a TranslateTransform3D to size and position your car model to global coordinates

  2. Create a GeometryModel3D for the scene, using an ImageBrush for the material, a simple rectangular Geometry3D, and a Transform3DGroup consisting of a ScaleTransform3D, a TranslateTransform3D, a RotateTransform3D and a TranslateTransform3D to size and position the scene (see code comments below for details)

  3. Construct a Viewport3DVisual using a PerspectiveCamera and containing a Model3DVisual containing a Model3DGroup that contains an AmbientLight plus the models created in steps 1 and 2

So the XAML would be something like this:

...
<Viewport3DVisual>

  <!-- the camera -->
  <Viewport3DVisual.Camera>
    <PerspectiveCamera ... camera parameters ... />
  </Viewport3DVisual.Camera>

  <ModelVisual3D>
    <ModelVisual3D.Content>
      <Model3DGroup>

        <!-- the light -->
        <AmbientLight ... light parameters ... />

        <!-- the car model -->
        <Model3DGroup>
          <Model3DGroup.Transform>
            <Transform3DGroup>
              <ScaleTransform3D    ... scale car to proper size ... />
              <RotateTransform3D   ... face car in proper direction ... />
              <TranslateTranform3D ... move car to proper global coordinates ... />
            </Transform3DGroup>
          </Model3DGroup.Transform>

          ... GeometryModel3D or Model3DGroup for the car model goes here ...

        </Model3DGroup>

        <!-- the scene image -->
        <GeometryModel3D>

          <GeometryModel3D.Material>
            <ImageBrush ImageSource=... scene image ... />
          </GeometryModel3D.Material>

          <GeometryModel3D.Geometry>
            <MeshGeometry3D Positions="0,0,0 1,0,0 1,1,0 0,1,0" Indices="0,1,2 2,3,0" />
          </GeometryModel3D.Geometry>

          <GeometryModel3D.Transform>
            <Transform3DGroup>
              <ScaleTransform3D     ... scale scene to apparent size ... />
              <TranslateTransform3D ... translate scene along Z axis to apparent distance from camera ... />
              <RotateTransform3D    ... rotate distanced scene to original camera orientation ... />
              <TranslateTransform3D ... move to global coordinates of original camera location ... />
            </Transform3DGroup>
          </GeometryModel3D.Transform>

        </GeometryModel3D>

      </Model3DGroup>
    </ModelVisual3D.Content>
  </ModelVisual3D>
</Viewport3DVisual>

Note that your scene image is set using an apparent size and distance rather than field of view. Select a large apparent distance for the scene image so it will always be behind the car model. Compute the apparent size like this:

var verticalFieldOfView = 60.0;    // Degrees
var horizontalFieldOfView = 60.0;  // Degrees
SceneApparentDistance = 1000.0;    // In global coordinate units

SceneApparentHeight = image.Height * SceneApparentDistance * Math.Tan(verticalFieldOfView * Math.Pi/180));
SceneApparentWidth = image.Width * SceneApparentDistance * Math.Tan(horizontalFieldOfView * Math.Pi/180));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜