将图像角点坐标转换为世界坐标。

huangapple go评论69阅读模式
英文:

Converting image corner coordinates to world coordinates

问题

I am attempting to create a world file that accompanies each screenshot I produce so that I can easily reference the files in CAD in the correct location, orientation, and scale as my original input data.

The issue is that I need to obtain the coordinates of the upper left corner of the exported image to use as the base point in the worldfile.

If we use the simple code below you will see the top left corner of the rendered polydata is (0, 1). However, I need the actual coordinates of the corner of the image.

I had assumed that the plotter.bounds() would return the polydata bounds and the renderer.bounds() would return the image bounds. However, they both return the polydata bounds. Any ideas?

import pyvista as pv
points = [[0, 0, 0],

          [1, 0, 0],

          [0.5, 1.0, 0]]
mesh = pv.PolyData(points)
pl = pv.Plotter()
pl.add_mesh(mesh)
pl.show_bounds(location='all', all_edges=True, grid=True)
pl.camera.tight(padding=0.1)
pl.parallel_projection = True # redundant but set here to remove perspective questions
pl.screenshot('with_padding')
pl.show()

pl.bounds
(0.0, 1.0, 0.0, 1.0, 0.0, 0.0)

pl.renderer.bounds
(0.0, 1.0, 0.0, 1.0, 0.0, 0.0)

Does anyone know of a method that returns the image corner coordinates?

英文:

I am attempting to create a world file that accompanies each screenshot I produce so that I can easily reference the files in CAD in the correct location, orientation, and scale as my original input data.

The issue is that I need to obtain the coordinates of the upper left corner of the exported image to use as the base point in the worldfile.

If we use the simple code below you will see the the top left corner of the rendered polydata is (0, 1). However I need the actual coordinates of the corner of the image.

I had assumed that the plotter.bounds() would return the polydata bounds and the renderer.bounds() would return the image bounds. However they both return the polydata bounds. Any ideas?

import pyvista as pv
points = [[0, 0, 0],

          [1, 0, 0],

          [0.5, 1.0, 0]]
mesh = pv.PolyData(points)
pl = pv.Plotter()
pl.add_mesh(mesh)
pl.show_bounds(location='all', all_edges=True, grid=True)
pl.camera.tight(padding=0.1)
pl.parallel_projection = True #redunant but set he to remove perspective questions
pl.screenshot('with_padding')
pl.show()

将图像角点坐标转换为世界坐标。

pl.bounds
(0.0, 1.0, 0.0, 1.0, 0.0, 0.0)

pl.renderer.bounds
(0.0, 1.0, 0.0, 1.0, 0.0, 0.0)

Does anyone know of a method that returns the image corner coordinates?

答案1

得分: 0

尽管我在评论中指出,只有在限制为xy视图时才能回答这个问题(因为在这种情况下z坐标是任意的,但你似乎只对xy坐标感兴趣),但似乎 VTK 已经准备好可以通过 vtkCoordinate() 进行这些坐标变换的机制。

你可以创建一个 vtkCoordinate 实例,将其坐标系统设置为归一化视口,使用相应的归一化坐标((0, 0) 是左下角,(1, 1) 是右上角),然后使用绘图器的渲染器查询相应的世界坐标:

import pyvista as pv
from vtkmodules.vtkRenderingCore import vtkCoordinate

# 示例数据
points = [
    [0, 0, 0],
    [1, 0, 0],
    [0.5, 1.0, 0],
]
mesh = pv.PolyData(points)

# 示例绘图
pl = pv.Plotter()
pl.add_mesh(mesh)
pl.show_bounds(location='all', all_edges=True, grid=True)
pl.camera.tight(padding=0.1)
pl.parallel_projection = True

# 获取视口左上角的世界坐标
coordinate = vtkCoordinate()
coordinate.SetCoordinateSystemToNormalizedViewport()
coordinate.SetValue(0, 1)  # (0, 0) 是左下角,(1, 1) 是右上角
coords = coordinate.GetComputedWorldValue(pl.renderer)
print(coords)
# (-0.050000000000000044, 1.05, 0.06472500000000003)

我稍微编辑了你的示例数据,最后一个代码块打印了左上角的世界坐标。请注意,你有一个非零的 z 坐标;你需要确保丢弃它,或者检查它在实际的厚实网格中的行为。如果你使用较旧的 vtk 并且遇到导入错误,你可以使用 from vtk import vtkCoordinate 替代 vtkmodules 导入,但这会慢得多(pyvista 在内部使用 vtkCoordinate,所以上面的导入版本是免费的)。

看着你原来的图,(-0.05, 1.05) 对我来说看起来是正确的。不幸的是,我无法在视觉上证明这是正确的位置,因为即使使用 reset_camera=False 添加一个新的网格也会干扰结果视图,即使我将 pl.camera_position 恢复到第二个网格添加之前的状态也是如此。我怀疑这与与 pl.camera.tight() 相关的某些事情有关。无论如何,你应该能够用你的实际网格确认这些值。

英文:

Although I noted in a comment that the question can only be answered if we restrict ourselves the an xy view (because in that case the z coordinate is arbitrary but you only seem to be looking for x and y coordinates), it seems that VTK readily has machinery that can do these coordinate transformations via vtkCoordinate().

You can create a vtkCoordinate instance, set its coordinate system to be normalized viewport, use the corresponding normalized coordinates ((0, 0) is bottom left corner, (1, 1) is upper right), then query the corresponding world points using the plotter's renderer:

import pyvista as pv
from vtkmodules.vtkRenderingCore import vtkCoordinate

# example data
points = [
    [0, 0, 0],
    [1, 0, 0],
    [0.5, 1.0, 0],
]
mesh = pv.PolyData(points)

# example plot
pl = pv.Plotter()
pl.add_mesh(mesh)
pl.show_bounds(location='all', all_edges=True, grid=True)
pl.camera.tight(padding=0.1)
pl.parallel_projection = True

# get world coordinates of upper left corner of viewport
coordinate = vtkCoordinate()
coordinate.SetCoordinateSystemToNormalizedViewport()
coordinate.SetValue(0, 1)  # (0, 0) is lower left, (1, 1) is upper right
coords = coordinate.GetComputedWorldValue(pl.renderer)
print(coords)
# (-0.050000000000000044, 1.05, 0.06472500000000003)

I slightly edited your example data, and the last code block prints the world coordinates of the upper left corner. Notice you have a nonzero z coordinate; you'll have to make sure to discard this, or check how this behaves with a real, thick mesh. If you have older vtk and you get an import error, you can use from vtk import vtkCoordinate instead of the vtkmodules import, but this will be a lot slower (pyvista uses vtkCoordinate internally, so the above version of the import is free).

Looking at your original figure, (-0.05, 1.05) looks correct to me. Unfortunately I couldn't visually prove that this is the correct position, because adding a new mesh even with reset_camera=False messes with the resulting view, even if I restore pl.camera_position from before the second mesh is added. I suspect this has to do with something related to pl.camera.tight(). Anyway, you should be able to confirm the values with your real mesh.

huangapple
  • 本文由 发表于 2023年5月13日 20:32:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76242749.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定