一、数据分析
以下数据是深度相机拍摄的点云数据,其为为n行6列的文本数据,分别对应x、y、z、r、g、b,列与列之间用‘→’分割。其rgb值不满足open3d程序的点云读写需求,故要将r、g、b的值进行归一化。。
-742.266 -566.249 1237 179 217 240
-747.144 -571.742 1249 179 217 240
-728.721 -559.383 1222 179 215 237
-728.232 -560.756 1225 178 214 236
-720.62 -556.636 1216 177 215 236
-718.359 -556.636 1216 178 216 239
-720.219 -559.84 1223 174 215 237
-713.33 -558.009 1219 173 215 239
-712.813 -559.383 1222 176 217 239
-705.307 -555.263 1213 177 215 238
二、数据处理
对于以上数据,本博文介绍以下三种处理方式:
2.1 完全使用np读写
由于数据有固定统一的格式,可以直接使用numpy库里的函数进行文本数据的读写,该方式最为简单。
可直接使用np.loadtxt函数将txt里的文本数据解析为np数组,需设置数据类型(dtype=np.float32)和分隔符delimiter,本博文设置的分割符为‘→’(数据类型和分隔符可根据自己的文本数据进行调整)
利用np数组可直接进行多维度切片处理的特点b[:,3:]=b[:,3:],对第二个维度进行切片
,对rgb的数值进行归一化处理
最后使用np.savetxt函数将更改后的新数据存入新的txt文件中,需设置文件路径、要存储的对象,delimiter为存储成文本时的分割符,fmt='%0.3f'为存储的数据格式‘%0.3f’表示存储的数据格式为保留3位小数的float
#从txt文件中读取数据
b=np.loadtxt('2023_09_27_14_10_50/PointCloudxyzrgb/00000001.txt',dtype=np.float32,delimiter=' ')
b[:,3:]=b[:,3:]/255 #数组第三位,第四位,第五位分别对应r,g,b,除以255就变为了0-1之间的小数(归一化)
#更改后的新数据存入新的txt文件中
np.savetxt('2023_09_27_14_10_50/PointCloudxyzrgb/000000022.txt',b,delimiter=' ' , fmt='%0.3f')
使用以上代码,操作极为简单与方便,适用于规范性的数据。
2.2 在数据读取阶段不使用np
以下代码使用原始的python操作进行数据解析,将文本格式的数据转为二维数组。
由于二维数组不能直接进行数学运算如加减乘除
和复杂的切片操作如进行多维度切片
,因此需要将二维数组用np.array转为np数组。np.savetxt操作2.1所示。
f = open("2023_09_27_14_10_50/PointCloudxyzrgb/00000001.txt",'r') # 返回一个文件对象
lines = f.readlines() # 调用文件的 readline()方法
lists=[]
for line in lines:
line=line.replace("\n","")
# 字符串str转列表list
list= line.split(' ')
#print('list',list)
lists.append(list)
f.close()
#list 转np数组
arr = np.array(lists)
arr=arr.astype(float)
arr[:,3:]=arr[:,3:]/255
np.savetxt('2023_09_27_14_10_50/PointCloudxyzrgb/2.txt',arr,delimiter=' ' , fmt='%0.3f')
使用以上代码,自行完成数据解析,可以处理一些不符规范的的数据在数据解析过程中,可以自行编码数据过滤或其他处理流程
2.3 全编码实现
全编码实现过程较为复杂,但其优点是可以进行Python和C++等各种编程语言的代码转换。该过程需要我们自己写函数完成数据的解析,数据的修改和数据的保存。
数据的解析:使用read2list函数实现,先将文本读取出来,然后将其转化为二维数组(字符串过滤->字符串分割->字符串数组转float数组);
数据的修改:使用 change_value实现数值的修改,具体使用for循环实现
数据的保存:基于list2str函数与字符串保存操作实现。list2str函数通过遍历数据将二维数组转化为字符串,其中需要注意的是float型的数组要转换为str型的数组才能进行数组转字符串操作。
def read2list(path):
f = open(path,'r') # 返回一个文件对象,r 表示读取
lines = f.readlines() # 调用文件的 readline()方法
f.close()
lists=[]
for line in lines:
line=line.replace("\n","")
# 字符串str转列表list
list1= line.split(' ')
list1=list(map(float,list1))#把list内的元素变成float型
#print('list',list)
lists.append(list1)
return lists
def change_value(list2d):
for list1 in list2d:
list1[3]=list1[3]/255
list1[4]=list1[4]/255
list1[5]=list1[5]/255
#print(list1)
return list2d
def list2str(list2d):
list_all=[]
for list1 in list2d:
#list_new = [str(x) for x in list1]#把float型的数组list1,转换为str型的数组list_new
list_new = ["%.3f"%x for x in list1]#把float型的数组list1,转换为str型的数组list_new
srt=' '.join(list_new)
list_all.append(srt)
result='\n'.join(list_all)
return result
path="2023_09_27_14_10_50/PointCloudxyzrgb/00000001.txt"
list2d=read2list(path)
list2d=change_value(list2d)
srt=list2str(list2d)
#更改后的新数据存入新的txt文件中 w:表示写入数据
f=open("2023_09_27_14_10_50/PointCloudxyzrgb/00000003.txt",'w')
f.write(srt)
f.close()