点云转灰度图脚本
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()