雨中飞蛾 2023-06-09 17:28 采纳率: 37.5%
浏览 111
已结题

blender python输出纹理坐标(像素级)与三维坐标的对应关系

首先我将一张图片上的部分纹理贴到了一个长方形平面上(实际就是将照片中的路面贴到长方形的平面上)

需求是:获取【图片上的部分纹理】的每个像素所对应的在模型上的顶点坐标。

目前我可以做到的是:将【长方形平面】细分后,可以获取细分后每个定点对应的纹理上的坐标,但是这不是像素级的。

请求给出解决 方向 或 代码 或 提示。

  • 写回答

9条回答 默认 最新

  • 这一次有糖 2023-06-09 17:30
    关注
    获得1.50元问题酬金

    试一试opengL

    评论
  • CF2301_77400554X 2023-06-09 21:09
    关注
    获得0.15元问题酬金

    引用chatgpt部分指引作答:
    要获取纹理坐标(像素级)与三维坐标的对应关系,你可以使用 Blender 的 Python API。下面是一个示例代码,它演示了如何获取纹理图片上每个像素所对应的模型顶点坐标:

    import bpy
    import bmesh
    
    # 选择包含纹理的对象
    obj = bpy.context.object
    
    # 确保对象具有 UV 层
    if not obj.data.uv_layers.active:
        bpy.ops.mesh.uv_texture_add()
    
    # 获取纹理坐标
    uv_layer = obj.data.uv_layers.active.data
    
    # 获取顶点坐标
    vertices = [v.co for v in obj.data.vertices]
    
    # 获取顶点索引
    faces = [f.vertices for f in obj.data.polygons]
    
    # 获取纹理图片的尺寸
    image_width = obj.data.materials[0].texture_slots[0].texture.image.size[0]
    image_height = obj.data.materials[0].texture_slots[0].texture.image.size[1]
    
    # 创建一个空的 BMesh 对象
    bm = bmesh.new()
    
    # 添加顶点
    for vertex in vertices:
        bm.verts.new(vertex)
    
    # 添加面
    for face in faces:
        bm.faces.new([bm.verts[i] for i in face])
    
    # 计算顶点和 UV 坐标之间的映射关系
    bm.faces.ensure_lookup_table()
    for face in bm.faces:
        for loop in face.loops:
            vertex_index = loop.vert.index
            uv = uv_layer[loop.index].uv
            pixel_x = int(uv[0] * image_width)
            pixel_y = int(uv[1] * image_height)
            print("Pixel ({}, {}) corresponds to vertex at {}".format(pixel_x, pixel_y, vertices[vertex_index]))
    
    # 释放 BMesh 对象
    bm.free()
    
    

    这段代码假设你已经选择了包含纹理的对象,并且该对象已经设置了 UV 层。它首先获取纹理坐标(UV)和顶点坐标,然后创建一个 BMesh 对象,将顶点和面添加到其中。接下来,它计算每个顶点对应的 UV 坐标,并将其转换为纹理图片上的像素坐标。最后,它输出每个像素坐标所对应的顶点坐标。

    此代码假设纹理仅应用于对象的第一个材质槽,并且该材质槽中包含一个贴图纹理。如果你的场景中存在多个材质或纹理,请根据需要进行修改。

    评论
  • GIS工具开发 2023-06-16 14:18
    关注
    获得0.75元问题酬金

    可以使用纹理贴图在模型上进行插值来获取每个像素对应的顶点坐标

    评论
  • CSDN-Ada助手 CSDN-AI 官方账号 2023-06-09 20:11
    关注
    获得1.80元问题酬金
    评论
  • 急速光粒 2023-06-10 14:44
    关注
    获得1.20元问题酬金

    应该不是特别难,建议把代码贴出来,描述问题所在,再看有无解决方案。

    评论
  • yy64ll826 2023-06-13 14:28
    关注
    获得0.75元问题酬金

    举个例子

    # 实现三维坐标向二维坐标的转换 
    
    import numpy as np
    
    """相机内、外参矩阵"""
    
    # 外参矩阵 (需要改)
    Out = np.mat([
        [-0.117, -0.992, 0.028, -0.125],
        [-0.0033, -0.0278, -0.9996, 0.2525],
        [0.993, -0.1174, 0.00000315, 0.0716],
        [0, 0, 0, 1]
    ])
    
    # 内参矩阵 (需要改)
    K = np.mat([
        [610.53, 0, 368.114],
        [0, 605.93, 223.969],
        [0, 0, 1]
    ])
    
    """坐标转换"""
    # 打开用于存放世界坐标的txt文件,将其中的以字符串格式保存的世界坐标转换成(Xw, Yw, Zw, 1)的元组格式
    f = open('database', 'r')
    database = []
    for line in f.readlines():
        coordinate = line.strip()  # 去掉左右的空格符
        coordinate = eval(coordinate)  # 将字符串格式的坐标转换为元组格式
        database.append(coordinate)
    # print(database)
    
    world_coordinate_list = []
    for item in database:
        world_coordinate_part = (item[0], item[1], item[2], 1)
        world_coordinate_list.append(world_coordinate_part)
    # print(world_coordinate_list)
    
    
    pixel_coordinate_list = []
    
    for item in world_coordinate_list:
        world_coordinate = np.mat([
            [item[0]],
            [item[1]],
            [item[2]],
            [item[3]]
        ])
        print(f'世界坐标为:\n{world_coordinate}')
        # print(type(world_coordinate))
        
        # 世界坐标系转换为相加坐标系 (Xw,Yw,Zw)--> (Xc,Yc,Zc)
        camera_coordinate = Out * world_coordinate
        print(f'相机坐标为:\n{camera_coordinate}')
        Zc = float(camera_coordinate[2])
        print(f'Zc={Zc}')
    
        # 相机坐标系转图像坐标系 (Xc,Yc,Zc) --> (x, y)  下边的f改为焦距
        focal_length = np.mat([
            [f, 0, 0, 0],
            [0, f, 0, 0],
            [0, 0, 1, 0]
        ])
        image_coordinate = (focal_length * camera_coordinate) / Zc
        print(f'图像坐标为:\n{image_coordinate}')
    
        # 图像坐标系转换为像素坐标系
        pixel_coordinate = K * image_coordinate
        print(f'像素坐标为:\n{pixel_coordinate}')
        pixel_coordinate_list.append(pixel_coordinate)
        print('---------------------分割线--------------------------------')
    
    print(pixel_coordinate_list)
    f = open("result.txt", "w", encoding="utf-8")
    for item in pixel_coordinate_list:
        f.write(str(item)+'\n')
        f.write('------------分割线-----------------'+'\n')
    f.close()
    
    
    
    评论
  • Minuw 2023-06-16 10:52
    关注
    获得0.75元问题酬金

    可以使用OpenCV中的函数cv2.remap()来实现像素级别的纹理映射。该函数将输入图像的每个像素映射到输出图像中指定位置的像素,并可以指定插值方法和重采样因子等参数。

    import cv2
    import numpy as np
    # 读取图片和模型
    img = cv2.imread('image.jpg')
    model = cv2.imread('model.png', 0)
    # 将模型进行细分
    subdiv_levels = 16
    model_subdiv = cv2.ximgproc.createSubdivMeshProcess(model, subdiv_levels)
    # 创建输出图像和纹理映射矩阵
    output_img = np.zeros((img.shape[0], img.shape[1], 4), dtype=np.uint8)
    dst = cv2.remap(img, None, model_subdiv.getMapToPixel(), cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
    # 将纹理映射后的图像与原始图像合并
    output_img[:, :, :3] = img[:, :, :3]
    output_img[:, :, 3] = dst[:, :, 3]
    # 显示结果
    cv2.imshow('Output Image', output_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    评论
  • 是小晴晴呀 2023-06-09 17:57
    关注

    ChatGPT能解决不

    评论
  • 才华横溢caozy 2023-06-12 17:50
    关注

    引用chatgpt:
    要实现这个需求,你可以使用OpenCV库中的remap函数。首先,你需要安装OpenCV库,然后按照以下步骤操作:

    1. 读取图片和模型的纹理。
    2. 将图片上的部分纹理贴到长方形平面上。
    3. 使用remap函数将图片上的部分纹理映射到模型上的顶点坐标。

    以下是一个示例代码:

    import cv2
    import numpy as np
    
    # 读取图片和模型的纹理
    image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    model_texture = cv2.imread('model_texture.jpg', cv2.IMREAD_GRAYSCALE)
    
    # 将图片上的部分纹理贴到长方形平面上
    x, y = 50, 50  # 长方形平面的左上角坐标
    width, height = 100, 100  # 长方形平面的宽度和高度
    image[y:y+height, x:x+width] = model_texture[y:y+height, x:x+width]
    
    # 获取图片上的部分纹理在模型上的顶点坐标
    dst = np.zeros((height, width), dtype=np.float32)
    cv2.remap(image, None, dst, cv2.INTER_LINEAR)
    
    print(dst)
    

    这段代码首先读取了图片和模型的纹理,然后将图片上的部分纹理贴到了长方形平面上。接下来,使用remap函数将图片上的部分纹理映射到模型上的顶点坐标。最后,输出映射后的顶点坐标。

    评论

报告相同问题?

问题事件

  • 系统已结题 6月17日
  • 创建了问题 6月9日

悬赏问题

  • ¥15 定义了函数,但是无法根据函数定义触发器
  • ¥20 5变量卡诺图化简得出与非门电路图
  • ¥20 位置依赖的碱基序列独热编码
  • ¥15 Python爬取交通拥堵指数数据
  • ¥15 使用vba抓取重定向网页问题
  • ¥20 付费需求测试程序(细谈)。
  • ¥15 为什么这段c++代码会报这么多语法错误?
  • ¥20 如何利用C语言实现用最小二乘法选配两个经验公式
  • ¥50 vue-codemirror如何对指定行 指定位置的 字符进行背景颜色或者字体颜色的修改?
  • ¥30 遇到一个的问题,请教各位