找回密码
 会员注册
查看: 32|回复: 0

深度图+RGB图像转点云python

[复制链接]

4

主题

0

回帖

13

积分

新手上路

积分
13
发表于 2024-9-12 18:07:11 | 显示全部楼层 |阅读模式
1、深度图(.png)转点云(有内参)importnumpyasnpimportopen3daso3dfromPILimportImagedefdepth_to_point_cloud(depth_map,fx,fy,cx,cy):#h,w=depth_map.shapeh,w=1184,1600points=[]forvinrange(h):foruinrange(w):Z=depth_map[v,u]X=(u-cx)*Z/fxY=(v-cy)*Z/fypoints.append([X,Y,Z])returnnp.array(points)depth_path=r'./depth.png'depth_map=Image.open(depth_path).convert("L")#替换成自己的路径depth_map=np.array(depth_map)fx=2892.33fy=2883.18cx=823.205cy=619.071points=depth_to_point_cloud(depth_map,fx,fy,cx,cy)#print(points)pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(points)o3d.io.write_point_cloud('./output.ply',pcd)#o3d.io.write_point_cloud("./output.pcd",pcd)1234567891011121314151617181920212223242526272829303132332、深度图(.pfm)转点云(有内参)importreimportnumpyasnpimportopen3daso3ddefread_pfm(file_path):withopen(file_path,'rb')asf:color=Nonewidth=Noneheight=Nonescale=Noneendian=Noneheader=f.readline().decode('utf-8').rstrip()ifheader=='PF':color=Trueelifheader=='Pf':color=Falseelse:raiseException('NotaPFMfile.')dim_match=re.match(r'^(\d+)\s(\d+)\s,f.readline().decode('utf-8'))ifdim_match:width,height=map(int,dim_match.groups())else:raiseException('MalformedPFMheader.')scale=float(f.readline().decode('utf-8').rstrip())ifscale'depth_data=np.fromfile(f,endian+'f')shape=(height,width,3)ifcolorelse(height,width)depth_data=np.reshape(depth_data,shape)depth_data=np.flipud(depth_data)returndepth_datadefdepth_to_point_cloud(depth_map,fx,fy,cx,cy):h,w=depth_map.shapepoints=[]forvinrange(h):foruinrange(w):Z=depth_map[v,u]X=(u-cx)*Z/fxY=(v-cy)*Z/fypoints.append([X,Y,Z])returnnp.array(points)#读取深度图depth_path=r"./depth.pfm"depth_map=read_pfm(depth_path)fx=2892.33fy=2883.18cx=823.205cy=619.071#转换为点云points=depth_to_point_cloud(depth_map,fx,fy,cx,cy)pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(points)o3d.io.write_point_cloud("./output.ply",pcd)#o3d.io.write_point_cloud("./output.pcd",pcd)1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465663、深度图(.png)+RGB图像转点云(无内参)#转换需要depth图像和rgb图像尺寸一致,若不一致需要先resize成一样的大小fromPILimportImageimg=Image.open('./depth.png')resized_img=img.resize((1600,1184))resized_img.save('./depth.png')importopen3daso3dimportmatplotlib.pyplotasplt#plt用于显示图片importnumpyasnprgb_path=r'./rgb.png'depth_path=r'./depth.png'color_raw=o3d.io.read_image(rgb_path)depth_raw=o3d.io.read_point_cloud(depth_path)rgbd_image=o3d.geometry.RGBDImage.create_from_color_and_depth(color_raw,depth_raw,depth_scale=1000.0,depth_trunc=3,convert_rgb_to_intensity=False)plt.subplot(1,2,1)plt.title('read_depth')plt.imshow(rgbd_image.color)plt.subplot(1,2,2)plt.title('depthimage')plt.imshow(rgbd_image.depth)plt.show()#若要查看自己的深度图值是多少,使用下面的np函数显示print(np.asarray(rgbd_image.depth))pcd=o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image,o3d.camera.PinholeCameraIntrinsic(o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))pcd.transform([[1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,1]])#o3d.visualization.draw_geometries([pcd])o3d.io.write_point_cloud('./output.ply',pcd)123456789101112131415161718192021222324252627282930314、深度图(.pfm)+RGB图像转点云(有内参)importnumpyasnpimportopen3daso3dimportcv2defread_pfm(fpath,expected_identifier="Pf"):#PFMformatdefinition:http://netpbm.sourceforge.net/doc/pfm.htmldef_get_next_line(f):next_line=f.readline().decode('utf-8').rstrip()#ignorecommentswhilenext_line.startswith('#'):next_line=f.readline().rstrip()returnnext_linewithopen(fpath,'rb')asf:#headeridentifier=_get_next_line(f)ifidentifier!=expected_identifier:raiseException('Unknownidentifier.Expected:"%s",got:"%s".'%(expected_identifier,identifier))try:line_dimensions=_get_next_line(f)dimensions=line_dimensions.split('')width=int(dimensions[0].strip())height=int(dimensions[1].strip())except:raiseException('Couldnotparsedimensions:"%s".''Expected"widthheight",e.g."512512".'%line_dimensions)try:line_scale=_get_next_line(f)scale=float(line_scale)assertscale!=0ifscale"except:raiseException('Couldnotparsemaxvalue/endianessinformation:"%s".''Shouldbeanon-zeronumber.'%line_scale)try:data=np.fromfile(f,"%sf"%endianness)data=np.reshape(data,(height,width))data=np.flipud(data)withnp.errstate(invalid="ignore"):data*=abs(scale)except:raiseException('Invalidbinaryvalues.Couldnotcreate%dx%darrayfrominput.'%(height,width))returndatadefreconstruct_point_cloud(rgb_image,depth_image,fx,fy,cx,cy):#获取图像尺寸height,width=depth_image.shape#创建点云坐标y_coords,x_coords=np.indices((height,width))x_coords=x_coords.reshape(-1)y_coords=y_coords.reshape(-1)z_coords=depth_image.reshape(-1)points_x=[]points_y=[]points_z=[]colors=[]forx,yinzip(x_coords,y_coords):[b,g,r]=rgb_image[y][x]#rgb是三通道的BGR格式图,所以读取顺序要顺序留意。ifr==0andg==0andb==0:continuedepth=depth_image[y][x]ifdepth==0:#如果深度值为0,表示无效值,跳过当前点continueX=(x-cx)*depth/fxY=(y-cy)*depth/fypoints_x.append(X)#points_y.append(1023-Y)#平移ypoints_y.append(Y)points_z.append(depth)color=[r/255.0,g/255.0,b/255.0]colors.append(color)#创建点云points=np.column_stack((points_x,points_y,points_z))#colors=rgb_image.reshape(-1,3)/255.0#print(colors)point_cloud=o3d.geometry.PointCloud()point_cloud.points=o3d.utility.Vector3dVector(points)point_cloud.colors=o3d.utility.Vector3dVector(colors)returnpoint_cloudfx=2892.33fy=2883.18cx=823.205cy=619.071rgb_image_path=r'./rgb.png'depth_image_path=r'./depth.pfm'save_path=r"./output.ply"rgb_image=cv2.imread(rgb_image_path)#depth_image=cv2.imread(depth_image_path,cv2.IMREAD_GRAYSCALE)depth_image=read_pfm(depth_image_path)point_cloud=reconstruct_point_cloud(rgb_image,depth_image,fx,fy,cx,cy)point_size=np.array(point_cloud.points).shape[0]print(point_size)o3d.io.write_point_cloud(save_path,point_cloud)#o3d.visualization.draw_geometries([point_cloud])1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081095、深度图pfm格式转为png格式fromPILimportImageimportnumpyasnpimportimageio.v3asiioimportnumpyasnpimportmatplotlib.pyplotaspltimportopen3daso3ddefwrite_pfm(data,fpath,scale=1,file_identifier=b'Pf',dtype="float32"):#PFMformatdefinition:http://netpbm.sourceforge.net/doc/pfm.htmldata=np.flipud(data)height,width=np.shape(data)[:2]values=np.ndarray.flatten(np.asarray(data,dtype=dtype))endianess=data.dtype.byteorderprint(endianess)ifendianess=='"except:raiseException('Couldnotparsemaxvalue/endianessinformation:"%s".''Shouldbeanon-zeronumber.'%line_scale)try:data=np.fromfile(f,"%sf"%endianness)data=np.reshape(data,(height,width))data=np.flipud(data)withnp.errstate(invalid="ignore"):data*=abs(scale)except:raiseException('Invalidbinaryvalues.Couldnotcreate%dx%darrayfrominput.'%(height,width))returndatapfm_path=r'/home/czh/CVP-MVSNet_backup/outputs/dtu_dataset-nsrc2/scan1/rgbd2ply/00000000.pfm'save_path='/home/czh/CVP-MVSNet_backup/outputs/dtu_dataset-nsrc2/scan1/rgbd2ply/pfm2png000.png'data=read_pfm(pfm_path)data_max=np.max(data)data_min=np.min(data)print("Max:",data_max)print("Min:",data_min)depth_instensity=np.array(256*(data-463)/512,dtype=np.uint8)#这里是改变深度表示的范围,为了可视化。463为数据中的最小值,相当于把数据范围最小值变为0;除512是因为最大值-最小值的值约等于500512的表示可以覆盖掉这500个数据iio.imwrite(save_path,depth_instensity)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-27 00:51 , Processed in 0.593696 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表