You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Intel RealSense D455+PCL生成的OBJ网格添加纹理?

给OrganizedFastMesh生成的网格添加纹理(Intel RealSense D455 + PCL)

你的核心问题是当前仅使用了PointXYZ类型的点云,没有携带**纹理坐标(UV)**和彩色数据,导致生成的OBJ文件缺少纹理信息。以下是可行的实现方案:

关键步骤

  1. 改用带RGB的点云类型:使用PointXYZRGB或PointXYZRGBA,从RealSense同步获取对齐后的深度和彩色帧,将每个3D点与对应的彩色像素绑定。
  2. 添加纹理坐标:根据点云的行列索引计算UV坐标(OBJ的UV原点在左下角,需注意Y轴反转)。
  3. 关联纹理图片:保存彩色帧为纹理图片,在OBJ中引用该图片并绑定UV坐标。

修改后的完整代码

#include <pcl/io/obj_io.h>
#include <pcl/surface/organized_fast_mesh.h>
#include <pcl/point_types.h>
#include <librealsense2/rs.hpp>
#include <opencv2/opencv.hpp>

int main() {
    // 初始化RealSense管道,配置彩色和深度流
    rs2::pipeline pipe;
    rs2::config cfg;
    cfg.enable_stream(RS2_STREAM_COLOR, 848, 480, RS2_FORMAT_RGB8, 30);
    cfg.enable_stream(RS2_STREAM_DEPTH, 848, 480, RS2_FORMAT_Z16, 30);
    pipe.start(cfg);

    // 对齐深度帧到彩色帧,确保点云与彩色像素一一对应
    rs2::align align(RS2_STREAM_COLOR);
    auto aligned_frames = align.process(pipe.wait_for_frames());
    auto color_frame = aligned_frames.get_color_frame();
    auto depth_frame = aligned_frames.get_depth_frame();

    int width = color_frame.get_width();
    int height = color_frame.get_height();
    int total_points = width * height;

    // 创建带RGB信息的有序点云
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    cloud->width = width;
    cloud->height = height;
    cloud->resize(total_points);

    // 获取彩色相机内参,用于像素转3D坐标
    rs2::video_stream_profile color_profile = color_frame.get_profile().as<rs2::video_stream_profile>();
    rs2::intrinsics intrin = color_profile.get_intrinsics();

    // 填充点云的XYZ和RGB数据
    const uint8_t* color_data = reinterpret_cast<const uint8_t*>(color_frame.get_data());
    int color_stride = color_frame.get_stride_in_bytes();

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int idx = y * width + x;
            float depth = depth_frame.get_distance(x, y);
            if (depth <= 0.0f) continue; // 跳过无效深度点

            // 将像素坐标转换为3D空间坐标
            rs2::point3d world_pt = rs2::deproject_pixel_to_point(intrin, {static_cast<float>(x), static_cast<float>(y)}, depth);
            cloud->at(idx).x = world_pt.x;
            cloud->at(idx).y = world_pt.y;
            cloud->at(idx).z = world_pt.z;

            // 提取对应像素的RGB值
            int color_idx = y * color_stride + x * 3;
            cloud->at(idx).r = color_data[color_idx];
            cloud->at(idx).g = color_data[color_idx + 1];
            cloud->at(idx).b = color_data[color_idx + 2];
        }
    }

    // 使用OrganizedFastMesh重建网格
    pcl::OrganizedFastMesh<pcl::PointXYZRGB>::Ptr mesh_generator(new pcl::OrganizedFastMesh<pcl::PointXYZRGB>);
    pcl::PolygonMesh output_mesh;

    mesh_generator->setTriangulationType(pcl::OrganizedFastMesh<pcl::PointXYZRGB>::TRIANGLE_RIGHT_CUT);
    mesh_generator->setInputCloud(cloud);
    mesh_generator->reconstruct(output_mesh);

    // 1. 保存彩色帧为纹理图片
    cv::Mat color_mat(cv::Size(width, height), CV_8UC3, (void*)color_frame.get_data(), cv::Mat::AUTO_STEP);
    cv::cvtColor(color_mat, color_mat, cv::COLOR_RGB2BGR); // OpenCV默认BGR格式,转换后保存
    cv::imwrite("texture.jpg", color_mat);

    // 2. 为每个顶点添加纹理坐标(UV)
    output_mesh.tex_coords.resize(total_points);
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int idx = y * width + x;
            // OBJ的UV坐标规则:u范围0-1(x/宽度),v范围0-1(1 - y/高度,因为OBJ原点在左下角)
            output_mesh.tex_coords[idx].u = static_cast<float>(x) / width;
            output_mesh.tex_coords[idx].v = 1.0f - static_cast<float>(y) / height;
        }
    }

    // 3. 保存带纹理的OBJ文件,自动生成MTL文件关联纹理
    pcl::io::saveOBJFile("Mesh.obj", output_mesh, "texture.jpg");

    pipe.stop();
    return 0;
}

注意事项

  • 确保已安装librealsense2和opencv库,编译时链接对应依赖
  • 帧对齐是关键:如果深度和彩色帧未对齐,3D点会对应错误的彩色像素,导致纹理错位
  • 若PCL版本较旧,saveOBJFile可能无法自动生成MTL文件,此时需要手动创建MTL文件并在OBJ头部添加引用(如mtllib Mesh.mtl)

内容的提问来源于stack exchange,提问作者Amayes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:15:42