根据像素坐标和深度图得到点云

语义分割predict之后得到labels文件夹里面的坐标是归一化的坐标,先将归一化的坐标转成像素坐标(x,y),然后像素坐标结合深度图(z值)就可以得到语义分割轮廓内的点云
1、读取和转换坐标:读取归一化的坐标并转换为像素坐标,将转换后的像素坐标保存到 save_pixel 文件夹中。
2、读取深度图和save_pixel像素坐标:使用转换后的像素坐标和深度图来生成点云。
3、生成和保存点云:根据轮廓内部的像素点生成点云并保存。

import os
import numpy as np
import open3d as o3d
import cv2

# 设置图像的宽度和高度
image_width = 1280  # 根据实际图像的尺寸进行设置
image_height = 720  # 根据实际图像的尺寸进行设置

# 设置文件夹路径
labels_folder = r"data/predict/labels"
pixel_folder = r"data/predict/save_pixel"
depth_folder = r"data/depth"
color_folder = r"data/rgb"  # 添加RGB图像的文件夹
output_folder = r"data/wuti_point"

# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)

# 遍历标签文件夹中的所有txt文件
for label_file in os.listdir(labels_folder):
    if label_file.endswith('.txt'):
        base_name = label_file.replace("_color.txt", "")
        depth_file = f"{base_name}_depth.png"
        pixel_file = f"{base_name}_color.txt"
        color_file = f"{base_name}_color.png"  # RGB图像文件名

        # 读取标签文件并转换为像素坐标
        input_path = os.path.join(labels_folder, label_file)
        output_path = os.path.join(pixel_folder, pixel_file)  # 修正了路径

        if not os.path.isfile(input_path):
            print(f"Label file not found: {input_path}")
            continue

        # 创建 pixel 文件夹,如果不存在的话
        os.makedirs(pixel_folder, exist_ok=True)

        with open(input_path, 'r') as infile, open(output_path, 'w') as outfile:
            lines = infile.readlines()
            for line in lines:
                values = line.split()
                class_id = values[0]
                normalized_coords = list(map(float, values[1:]))

                # 转换为实际像素坐标
                pixel_coords = []
                for i in range(0, len(normalized_coords), 2):
                    x_pixel = normalized_coords[i] * image_width
                    y_pixel = normalized_coords[i + 1] * image_height
                    pixel_coords.append(f"{x_pixel:.2f}")
                    pixel_coords.append(f"{y_pixel:.2f}")

                # 写入新的文件中
                outfile.write(f"{class_id} " + " ".join(pixel_coords) + "\n")

        # 读取深度图像
        depth_path = os.path.join(depth_folder, depth_file)
        if not os.path.isfile(depth_path):
            print(f"Depth file not found: {depth_path}")
            continue

        depth_img = cv2.imread(depth_path, cv2.IMREAD_UNCHANGED)

        # 读取RGB图像
        color_path = os.path.join(color_folder, color_file)
        if not os.path.isfile(color_path):
            print(f"Color file not found: {color_path}")
            continue

        color_img = cv2.imread(color_path)

        # 确定对应的归一化坐标文件名
        pixel_path = os.path.join(pixel_folder, pixel_file)
        if not os.path.isfile(pixel_path):
            print(f"Corresponding pixel file not found for {depth_file}")
            continue

        # 读取像素坐标文件
        with open(pixel_path, 'r') as f:
            lines = f.readlines()

        # 提取轮廓点
        contour = []
        for line in lines:
            data = line.strip().split()
            x_coords = list(map(float, data[1::2]))
            y_coords = list(map(float, data[2::2]))
            for x, y in zip(x_coords, y_coords):
                contour.append([x, y])

        contour = np.array(contour, dtype=np.int32)

        # 创建一个空的点云列表
        points = []
        colors = []

        # 遍历图像中的每个像素
        for y in range(depth_img.shape[0]):
            for x in range(depth_img.shape[1]):
                # 检查该像素是否在轮廓内部或边缘
                if cv2.pointPolygonTest(contour, (x, y), False) >= 0:
                    z = depth_img[y, x]
                    if z > 0:  # 忽略无效深度值
                        points.append([x, y, z])
                        # 获取颜色并进行归一化
                        bgr_color = color_img[y, x]  # OpenCV使用BGR格式
                        rgb_color = bgr_color[::-1]  # 转换为RGB格式
                        colors.append(np.array(rgb_color) / 255.0)  # 归一化颜色

        # 保存带有颜色的点云
        if points:
            point_cloud = o3d.geometry.PointCloud()
            point_cloud.points = o3d.utility.Vector3dVector(np.array(points))
            point_cloud.colors = o3d.utility.Vector3dVector(np.array(colors))
            output_path = os.path.join(output_folder, f"{base_name}_pointcloud.ply")
            o3d.io.write_point_cloud(output_path, point_cloud)
            print(f"Point cloud saved: {output_path}")
        else:
            print(f"No valid points found for {depth_file}")

print("Point cloud generation complete.")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值