点云转灰度图+点云转RGB图的python实现

点云转灰度图脚本

import numpy as np
import pcl
import cv2


def test_cloud2gray():
    # 点云转灰度图
    xy_ratio = 100
    z_ratio = 100
    # path = r"D:\Downloads\rule_pointcloud\two_tree.pcd"
    path = r"D:\code\script\3d_detect\data\BGA_3D\yishi_2710\bga_speed-12_expose-120us-frequecy-1000.pcd"
    cloud = pcl.load(path)
    points = cloud.to_array()
    point_x = points[:, 0]
    point_y = points[:, 1]
    point_z = points[:, 2]

    min_x = min(point_x)
    offset_x = 0
    if min_x < 0:
        offset_x = abs(min_x)
    point_x = point_x + offset_x
    point_x = point_x * xy_ratio

    min_y = min(point_y)
    offset_y = 0
    if min_y < 0:
        offset_y = abs(min_y)
    point_y = point_y + offset_y
    point_y = point_y * xy_ratio

    min_z = min(point_z)
    offset_z = 0
    if min_z < 0:
        offset_z = abs(min_z)
    point_z = point_z + offset_z
    point_z = point_z * z_ratio
    # 归一化
    max_z = max(point_z)
    point_z = point_z / max_z * 255  #将取值范围划分到0~255
    print(point_z)

    # 创建画布
    max_x = int(max(point_x)) + 100
    max_y = int(max(point_y)) + 100
    print(f"create template size: x: {max_x}, y:{max_y}")
    background_img = np.zeros((max_y, max_x), np.uint8)
    # cv2.imwrite("background.jpg", background_img)

    # 将点位画上
    n_point_x = np.expand_dims(point_x, axis=1)
    n_point_y = np.expand_dims(point_y, axis=1)
    point_xy = np.array(np.concatenate((n_point_x, n_point_y), axis=1), dtype=np.uint32)
    for index, point in enumerate(point_xy):
        y, x = point[0], point[1]
        background_img[x, y] = int(point_z[index])
    cv2.imwrite("background_bga-1.jpg", background_img)


if __name__ == '__main__':
    test_cloud2gray()

运行结果图:

3D相机生成PNG图:

3D视角(cloudcompare)

正面俯瞰

侧面斜视:

点云转RGB代码:

import numpy as np
import pcl
from pcl import pcl_visualization
import pclpy
import cv2
from tqdm import tqdm
from color_convert import ColorConvert


def cloud_convert_range(cloud, xy_ratio, z_ratio):
    points = cloud.to_array()
    print(f"points number: {len(points)}")
    for i, pts in enumerate(points):
        if pts[0] == 0:
            continue
        # print(f">>>  index: {i} -->  x: {pts[0]}, y: {pts[1]}, z: {pts[2]}")
        # time.sleep(0.1)
    point_x = points[:, 0]
    point_y = points[:, 1]
    point_z = points[:, 2]

    min_x = min(point_x)
    offset_x = 0
    if min_x < 0:
        offset_x = abs(min_x)
    point_x = point_x + offset_x
    point_x = point_x * xy_ratio

    min_y = min(point_y)
    offset_y = 0
    if min_y < 0:
        offset_y = abs(min_y)
    point_y = point_y + offset_y
    point_y = point_y * xy_ratio

    min_z = min(point_z)
    offset_z = 0
    if min_z < 0:
        offset_z = abs(min_z)
    point_z = point_z + offset_z
    point_z = point_z * z_ratio
    # 归一化
    max_z = max(point_z)
    min_z = min(np.argwhere(point_z))
    print(f"max z: {max_z}, min z: {min_z}")
    point_z = point_z / max_z * 255  # 将取值范围划分到0~255
    return point_x, point_y, point_z


def test_cloud2rgb():
    import time
    # 点云转灰度图
    xy_ratio = 1
    z_ratio = 100000
    path = r"D:\code\script\3d_detect\data\3d_data\5.pcd"
    save_path = "RGB_background_new_gap_05-01.jpg"
    save_cloud_path = "segmented_cloud_05-01.pcd"
    save_filter_path = "statistical_cloud_05-01.pcd"
    cloud = pcl.load(path)
    print(f"load original over, count point number {cloud.size}")
    seg = cloud.make_segmenter()
    seg.set_optimize_coefficients(True)
    seg.set_model_type(pcl.SACMODEL_PLANE)
    seg.set_method_type(pcl.SAC_RANSAC)
    seg.set_distance_threshold(20)  # 设置RANSAC算法的距离阈值,点到模型小于该值则认为改点属于模型
    inliers, coefficients = seg.segment()  # 执行RANSAC算法进行平面分割
    # 根据分割结果提取分割好的点云
    segmented_cloud = cloud.extract(inliers, negative=False)
    pcl.save(segmented_cloud, save_cloud_path)
    print("save pcd success.")
    # cloud = pclpy.read(path, "PointXYZ")
    print(f"load over, count segmented cloud number {segmented_cloud.size}")
    cloud = segmented_cloud
    # # 创建统计滤波对象
    # statistical_filter = cloud.make_statistical_outlier_filter()
    # statistical_filter.set_mean_k(50)
    # statistical_filter.set_std_dev_mul_thresh(0.1)
    # statistical_filter.set_negative(True)
    # cloud = statistical_filter.filter()
    # pcl.save(cloud, save_filter_path)
    # print(f"point after filter number {cloud.size}")

    # 创建直通滤波
    pass_through = cloud.make_passthrough_filter()
    pass_through.set_filter_field_name("z")
    pass_through.set_filter_limits(1200, 2000)
    cloud = pass_through.filter()
    pcl.save(cloud, save_filter_path)
    print(f"point after filter number {cloud.size}")

    # visual = pcl_visualization.CloudViewing()
    # visual.ShowMonochromeCloud(cloud, b'original point cloud')
    # # visual.ShowMonochromeCloud(segmented_cloud, b'seg cloud')
    # # visual.ShowMonochromeCloud(coefficients_cloud, b'coe cloud')
    # flag = True
    # while flag:
    #     flag = not(visual.WasStopped())
    # exit(0)

    # vox = cloud.make_voxel_grid_filter()
    # # 设置体素大小
    # LEAF_SIZE = 0.05
    # vox.set_leaf_size(LEAF_SIZE, LEAF_SIZE, LEAF_SIZE)
    # downsampled_cloud = vox.f ilter()
    # print(f"original number: {cloud.size} | down sampled number: {downsampled_cloud.size}")
    # cloud = downsampled_cloud

    point_x, point_y, point_z = cloud_convert_range(cloud, xy_ratio, z_ratio)
    # points = cloud.to_array()
    # print(f"points number: {len(points)}")
    # for i, pts in enumerate(points):
    #     if pts[0] == 0:
    #         continue
    #     # print(f">>>  index: {i} -->  x: {pts[0]}, y: {pts[1]}, z: {pts[2]}")
    #     # time.sleep(0.1)
    # point_x = points[:, 0]
    # point_y = points[:, 1]
    # point_z = points[:, 2]
    #
    # min_x = min(point_x)
    # offset_x = 0
    # if min_x < 0:
    #     offset_x = abs(min_x)
    # point_x = point_x + offset_x
    # point_x = point_x * xy_ratio
    #
    # min_y = min(point_y)
    # offset_y = 0
    # if min_y < 0:
    #     offset_y = abs(min_y)
    # point_y = point_y + offset_y
    # point_y = point_y * xy_ratio
    #
    # min_z = min(point_z)
    # offset_z = 0
    # if min_z < 0:
    #     offset_z = abs(min_z)
    # point_z = point_z + offset_z
    # point_z = point_z * z_ratio
    # # 归一化
    # max_z = max(point_z)
    # min_z = min(np.argwhere(point_z))
    # print(f"max z: {max_z}, min z: {min_z}")
    # point_z = point_z / max_z * 255  #将取值范围划分到0~255

    # 创建画布
    max_x = int(max(point_x)) + 10
    max_y = int(max(point_y)) + 10
    print(f"create template size: x: {max_x}, y:{max_y}")
    background_img = np.zeros((max_y, max_x, 3), np.uint8)
    # cv2.imwrite("background.jpg", background_img)

    # 将点位画上
    n_point_x = np.expand_dims(point_x, axis=1)
    n_point_y = np.expand_dims(point_y, axis=1)
    point_xy = np.array(np.concatenate((n_point_x, n_point_y), axis=1), dtype=np.uint32)
    index = 0
    point_xy = point_xy.tolist()
    cc = ColorConvert()
    for point in tqdm(point_xy):
        # print(index)
        # point = point_xy[index]
        y, x = point[0], point[1]
        value = point_z[index]
        r,g,b = cc.gray2rgb(value)
        background_img[x, y] = r, g, b
        index += 1
    cv2.imwrite(save_path, background_img)


def test_height2rgb():
    gray_value = [i for i in range(0, 255, 5)]
    print(gray_value)
    cc = ColorConvert()
    for v in tqdm(gray_value):
        test_img = np.zeros((50, 50, 3), np.uint8)
        r, g, b = cc.gray2rgb(v)
        cv2.circle(test_img, (15, 15), 10, (b, g, r), 8)
        save_path = f"gray2rgb/{v}_gray_{r}_{g}_{b}.jpg"
        cv2.imwrite(save_path, test_img)


if __name__ == '__main__':
    test_cloud2rgb()
    # test_height2rgb()
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值