我正在处理一个机器学习任务,尝试使用blender生成合成图像作为神经网络的训练数据集。为此,我必须找到渲染图像中对象的边界框。
到目前为止,我所使用的代码主要基于这个线程中建议的代码,但是它没有考虑顶点是否被另一个对象遮挡或可见。实际上,期望的结果正好与这里所解释的一样。我尝试了那里给出的建议,但它不起作用。我无法确定是因为我给ray_cast函数提供了错误的输入(因为bpy API确实很糟糕),还是因为函数性能差,如我在其他地方读到的那样。我的代码现在是:
import bpy
import numpy as np
def boundingbox(scene, camera, obj, limit = 0.3):
# Get the inverse transformation matrix.
matrix = camera.matrix_world.normalized().inverted()
# Create a new mesh data block, using the inverse transform matrix to undo any transformations.
dg = bpy.context.evaluated_depsgraph_get()
# eval_obj = bpy.context.object.evaluated_get(dg)
eval_obj = obj.evaluated_get(dg)
mesh = eval_obj.to_mesh()
mesh.transform(obj.matrix_world)
mesh.transform(matrix)
# Get the world coordinates for the camera frame bounding box, before any transformations.
frame = [-v for v in camera.data.view_frame(scene=scene)[:3]]
origin = camera.location
lx = []
ly = []
for v in mesh.vertices:
co_local = v.co
z = -co_local.z
direction = (co_local - origin)
result = scene.ray_cast(view_layer=bpy.context.window.view_layer, origin=origin,
direction= direction) # interested only in the first return value
intersection = result[0]
met_obj = result[4]
if intersection:
if met_obj.type == 'CAMERA':
intersection = False
if z <= 0.0 or (intersection == True and (result[1] - co_local).length > limit):
# Vertex is behind the camera or another object; ignore it.
continue
else:
# Perspective division
frame = [(v / (v.z / z)) for v in frame]
min_x, max_x = frame[1].x, frame[2].x
min_y, max_y = frame[0].y, frame[1].y
x = (co_local.x - min_x) / (max_x - min_x)
y = (co_local.y - min_y) / (max_y - min_y)
lx.append(x)
ly.append(y)
eval_obj.to_mesh_clear()
# Image is not in view if all the mesh verts were ignored
if not lx or not ly:
return None
min_x = np.clip(min(lx), 0.0, 1.0)
min_y = np.clip(min(ly), 0.0, 1.0)
max_x = np.clip(max(lx), 0.0, 1.0)
max_y = np.clip(max(ly), 0.0, 1.0)
# Image is not in view if both bounding points exist on the same side
if min_x == max_x or min_y == max_y:
return None
# Figure out the rendered image size
render = scene.render
fac = render.resolution_percentage * 0.01
dim_x = render.resolution_x * fac
dim_y = render.resolution_y * fac
# return box in the form (top left x, top left y),(width, height)
return (
(round(min_x * dim_x), # X
round(dim_y - max_y * dim_y)), # Y
(round((max_x - min_x) * dim_x), # Width
round((max_y - min_y) * dim_y)) # Height
)
我还尝试过将光线从顶点投射到相机位置(而不是反过来),并使用如此处所解释的小正方体解决方法,但仍然无法成功。请问有人能帮助我找出正确的方法或提出其他策略吗?