『Python』2D RGB图像转3D点云图像的一种方案

2D RGB图像转3D点云数据

中午老板给了一张电路板图要转3D点云,老板要的不是具体的3D数据,而是想要这样的效果。

思路

如果按照正常套路的话应该是走3D重建,上模型来搞,不过因为我之前搞过一些opencv,所以就用了另外一种笨拙但有效的方法。

RGB image ==> Gray image ==> Cannny边缘检测 ==>3D的z坐标置零 ==> 保留原来的像素点颜色 ==> 生成点云

代码

def transform(path):
    import cv2
    import open3d as o3d

    # 读取RGB电路板图像
    image = cv2.imread(path)

    # 进行图像预处理,如边缘检测
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    cv2.imshow("img",image)
    cv2.waitKey(0)
    # cv2.imshow("edges",edges)
    # cv2.waitKey(0)

    # 生成点云和颜色
    points = []
    colors = []
    a,b = edges.shape
    for x in range(a):
        for y in range(b):
            # 将轮廓点映射到3D空间中,可以简单地假设深度为0
            if edges[x][y]!=0:
                points.append([x, y, 0])
                # 获取像素点的颜色作为点云的颜色
                color = image[x, y] / 255  # 注意颜色顺序为BGR
                colors.append([color[0], color[1], color[2]])  # 颜色顺序转换为RGB

    # 创建Open3D点云对象,并设置点和颜色
    point_cloud = o3d.geometry.PointCloud()
    point_cloud.points = o3d.utility.Vector3dVector(points)
    point_cloud.colors = o3d.utility.Vector3dVector(colors)

    # 可以对点云进行滤波、去除离群点等处理
    # 例如,使用半径滤波器进行滤波
    # point_cloud = point_cloud.random_down_sample(sampling_ratio=0.6)  # 简单的下采样

    # 保存点云
    o3d.io.write_point_cloud("output_point_cloud_with_color.ply", point_cloud)

    # 可以使用Open3D可视化点云
    o3d.visualization.draw_geometries([point_cloud])

效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

以下是Python代码,用于将深度图像换为3D点云: ```python import cv2 import numpy as np def depth_to_pointcloud(depth_img, intrinsic_matrix): # 获取内参矩阵的逆矩阵 inv_intrinsics = np.linalg.inv(intrinsic_matrix) # 获取深度图像的尺寸 height, width = depth_img.shape[:2] # 生成网格状的像素坐标矩阵 pixel_coords = np.array([[x, y] for y in range(height) for x in range(width)]) # 将像素坐标矩阵换为相机坐标系下的坐标矩阵 camera_coords = np.matmul(inv_intrinsics, np.hstack((pixel_coords, np.ones((height*width, 1)))).T).T # 将深度图像换为相机坐标系下的坐标矩阵 depth_values = depth_img.reshape(-1) camera_coords = np.multiply(camera_coords, np.tile(depth_values, (3, 1)).T) # 将相机坐标系下的坐标矩阵换为世界坐标系下的坐标矩阵 world_coords = camera_coords return world_coords # 读取深度图像 depth_img = cv2.imread('depth.png', cv2.IMREAD_UNCHANGED).astype(float) / 1000.0 # 读取相机内参矩阵 intrinsic_matrix = np.loadtxt('intrinsic_matrix.txt') # 将深度图像换为3D点云 pointcloud = depth_to_pointcloud(depth_img, intrinsic_matrix) # 保存3D点云 np.savetxt('pointcloud.txt', pointcloud) ``` 代码中,`depth_to_pointcloud()` 函数接受深度图像和相机内参矩阵作为输入,并返回3D点云。函数内部首先获取内参矩阵的逆矩阵,然后生成网格状的像素坐标矩阵。接着,将像素坐标矩阵换为相机坐标系下的坐标矩阵,并将深度图像换为相机坐标系下的坐标矩阵。最后,将相机坐标系下的坐标矩阵换为世界坐标系下的坐标矩阵,并返回该矩阵作为3D点云。 在使用该函数时,需要将深度图像和相机内参矩阵作为输入,并指定3D点云的保存路径。其中,深度图像应该是灰度图像,每个像素值表示该像素点到相机的距离;相机内参矩阵应该是3x3的矩阵,表示相机的内部参数,如焦距、光心等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值