问题描述:python-pcl将彩色点云存储至PCD后,RGB的ASCII值发生巨大变化,导致图片失真。ASCII值如图1所示,原图片和失真图片如图2所示

图1 打开PCD的图,左为rosrun pcl_ros pcl_to_pcd出来的图,右为自己代码的图(RGB的部分不对),代码见下部代码块

图2 可视化点云图,左为正确图,右为失真图
import rospy
import numpy as np
import cv2
import pcl
from pcl import pcl_visualization
import ros_numpy
import open3d as o3d
from sensor_msgs.msg import PointCloud2
from sensor_msgs import point_cloud2
from sensor_msgs.msg import PointField
address = "/home/wmra/catkin_ws/src/my_pcl_tutorial/pictures2"
def morphological_primitives_running(msg):
pcl_points = ros_numpy.numpify(msg) # ros_numpy.numpify()生成的图片是[Heijht,Weight,4],高宽和宽度是像素坐标,"4"是像素坐标上点云的xyz和颜色
print("pcl_points",pcl_points)
pcl_points_color = ros_numpy.point_cloud2.split_rgb_field(pcl_points) # 分离点云点的RGB通道
print("pcl_points_color",pcl_points_color)
height, width = pcl_points.shape[0], pcl_points.shape[1] # 图片像素高度,矩阵行数480 图片像素宽度,矩阵列数640 shape[2]是通道数
print("pcl_points.shape",pcl_points.shape)
print("pcl_points_color['b']",pcl_points_color['b'])
print("pcl_points_color['g']",pcl_points_color['g'])
print("pcl_points_color['r']",pcl_points_color['r'])
#img = cv2.imread("/home/wmra/catkin_ws/src/my_pcl_tutorial/scripts/grasp3_Color.png")
#b,g,r = cv2.split(img)
#img_rgb = cv2.merge([r,g,b])
img_rgb = cv2.merge([np.array(pcl_points_color['b']), np.array(pcl_points_color['g']), np.array(pcl_points_color['r'])])
#cv2.imshow("img_rgb", img_rgb)
#cv2.waitKey(0)
pcl_points_color_red, pcl_points_color_green, pcl_points_color_blue = np.resize(pcl_points_color['r'], height * width), np.resize(pcl_points_color['g'], height * width), np.resize(pcl_points_color['b'], height * width) # 将三色提取出来,[:, :, np.newaxis] np.newaxis放在哪个位置,就会给哪个位置增加维度
pcl_points_color_red, pcl_points_color_green, pcl_points_color_blue = pcl_points_color_red.astype(np.uint32), pcl_points_color_green.astype(np.uint32), pcl_points_color_blue.astype(np.uint32) #
pcl_pcd_points = np.zeros((height * width, 3), dtype=np.float32)
pcl_pcd_rgb = np.zeros((height * width, 1), dtype=np.uint32)
print("pcl_points_color['x']",pcl_points_color['x'])
pcl_pcd_points[:, 0] = np.resize(pcl_points_color['x'], height * width) # 有序点云按照图片从左到右依次排列
pcl_pcd_points[:, 1] = np.resize(pcl_points_color['y'], height * width)
pcl_pcd_points[:, 2] = np.resize(pcl_points_color['z'], height * width)
pcl_pcd_rgb[:, 0] = 255 << 24 | pcl_points_color_red << 16 | pcl_points_color_green << 8 | pcl_points_color_blue # <<是左移运算符,转换为2进制,然后左移1位,此时十进制2变成十进制4
pcl_pcd = np.concatenate((pcl_pcd_points, pcl_pcd_rgb), axis=1)
print("pcl_pcd",pcl_pcd)
cloud_points = pcl.PointCloud_PointXYZRGB()
cloud_points.from_list(pcl_pcd)
print(type(cloud_points))
print(cloud_points[3])
print("Saving points in 1.pcd")
pcl.save(cloud_points, address + '/1.pcd', format = "pcd") # 存储全部点云
def ros_running():
rospy.init_node('morphological_primitives_ros', anonymous=True)
rospy.Subscriber("/camera/depth_registered/points", PointCloud2, morphological_primitives_running, queue_size= 5) #realsense
rospy.spin()
if __name__ == "__main__":
ros_running()
补充描述
在pcl.save之前的 print("pcl_pcd",pcl_pcd) 结果为
pcl_pcd [[-2.90159917e+00 -2.20055056e+00 5.37000036e+00 4.28272238e+09]
[-2.89273000e+00 -2.20055056e+00 5.37000036e+00 4.28298555e+09]
[-2.86130571e+00 -2.18333936e+00 5.32800007e+00 4.28278842e+09]
...
[ nan nan nan 4.28864552e+09]
[ nan nan nan 4.28884213e+09]
[ nan nan nan 4.28877633e+09]]
之后的print(cloud_points[3])结果为:
(-2.852505922317505, -2.1833393573760986, 5.328000068664551, 4282591232.0)