IQM 在《IDC MarketScape:2026年全球量子计算厂商评估》报告中被评为主要厂商
2026/7/1 4:21:24
堆方量(Bulk Volume): ├── 定义:松散货物堆放的体积 ├── 应用:矿石、粮食、煤炭、砂石 ├── 测量:传统人工测量 vs 视觉测量 └── 精度要求:±3%(商业结算) 视觉测量优势: ├── 非接触式:不影响堆放 ├── 实时性:秒级测量 ├── 高精度:±1-2% └── 自动化:减少人工#!/usr/bin/env python3"""pointcloud_capture.py - 点云采集"""importcv2importnumpyasnpimportopen3daso3dimportpyrealsense2asrsclassPointCloudCapture:"""点云采集器"""def__init__(self):self.pipeline=rs.pipeline()config=rs.config()config.enable_stream(rs.stream.depth,1280,720,rs.format.z16,30)config.enable_stream(rs.stream.color,1280,720,rs.format.bgr8,30)self.pipeline.start(config)align_to=rs.stream.color self.align=rs.align(align_to)# 获取内参profile=self.pipeline.get_active_profile()self.intrinsics=profile.get_stream(rs.stream.color).as_video_stream_profile().get_intrinsics()defcapture_pointcloud(self):"""采集一帧点云"""frames=self.pipeline.wait_for_frames()aligned=self.align.process(frames)depth_frame=aligned.get_depth_frame()color_frame=aligned.get_color_frame()# 创建点云pc=rs.pointcloud()pc.map_to(color_frame)points=pc.calculate(depth_frame)# 转 Open3D 格式vertices=np.asanyarray(points.get_vertices()).view(np.float32).reshape(-1,3)colors=np.asanyarray(color_frame.get_data()).reshape(-1,3)/255.0pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(vertices)pcd.colors=o3d.utility.Vector3dVector(colors)returnpcddefcapture_multi_view(self,num_views=4):"""多视角采集"""pcds=[]foriinrange(num_views):print(f"采集视角{i+1}/{num_views}...")input("调整相机位置后按 Enter...")pcd=self.capture_pointcloud()pcds.append(pcd)# 多视角融合merged=self._merge_pointclouds(pcds)returnmergeddef_merge_pointclouds(self,pcds):"""多视角点云融合"""iflen(pcds)==1:returnpcds[0]# ICP 配准merged=pcds[0]foriinrange(1,len(pcds)):reg=o3d.pipelines.registration.registration_icp(pcds[i],merged,0.02,np.eye(4),o3d.pipelines.registration.TransformationEstimationPointToPoint())pcds[i].transform(reg.transformation)merged+=pcds[i]# 降采样merged=merged.voxel_down_sample(voxel_size=0.01)returnmergedif__name__=="__main__":capture=PointCloudCapture()pcd=capture.capture_pointcloud()# 保存点云o3d.io.write_point_cloud("stockpile.pcd",pcd)print(f"点云点数:{len(pcd.points)}")#!/usr/bin/env python3"""volume_calc.py - 点云体积计算"""importnumpyasnpimportopen3daso3dclassVolumeCalculator:"""体积计算器"""def__init__(self):passdefcalculate_volume_convex_hull(self,pcd):"""凸包体积"""hull,_=pcd.compute_convex_hull()volume=hull.get_volume()returnvolumedefcalculate_volume_alpha_shape(self,pcd,alpha=0.05):"""Alpha Shape 体积(更精确)"""mesh=o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd,alpha)volume=mesh.get_volume()returnvolumedefcalculate_volume_voxel(self,pcd,voxel_size=0.01):"""体素化体积"""# 体素化voxel_grid=o3d.geometry.VoxelGrid.create_from_point_cloud(pcd,voxel_size)voxels=voxel_grid.get_voxels()# 体积 = 体素数 × 体素体积voxel_volume=voxel_size**3total_volume=len(voxels)*voxel_volumereturntotal_volumedefcalculate_volume_height_map(self,pcd,grid_size=0.05):"""高度图体积"""points=np.asarray(pcd.points)# 创建网格x_min,y_min=points[:,0].min(),points[:,1].min()x_max,y_max=points[:,0].max(),points[:,1].max()x_bins=np.arange(x_min,x_max,grid_size)y_bins=np.arange(y_min,y_max,grid_size)# 计算每个网格的最大高度height_map=np.zeros((len(y_bins),len(x_bins)))forpointinpoints:x_idx=int((point[0]-x_min)/grid_size)y_idx=int((point[1]-y_min)/grid_size)if0<=x_idx<len(x_bins)and0<=y_idx<len(y_bins):height_map[y_idx,x_idx]=max(height_map[y_idx,x_idx],point[2])# 计算底面高度(取最小值或已知值)base_height=points[:,2].min()# 体积 = Σ(高度差 × 网格面积)height_diff=height_map-base_height volume=np.sum(height_diff[height_diff>0])*grid_size**2returnvolume,height_mapdefcalculate_stockpile_volume(self,pcd,base_plane=None):"""计算堆料体积"""points=np.asarray(pcd.points)ifbase_planeisNone:# 自动检测底面(RANSAC 平面拟合)plane_model,inliers=pcd.segment_plane(distance_threshold=0.02,ransac_n=3,num_iterations=1000)base_height=np.mean(points[inliers,2])else:base_height=base_plane# 过滤底面以上的点above_base=points[points[:,2]>base_height+0.01]# 计算体积(高度图法)pcd_above=o3d.geometry.PointCloud()pcd_above.points=o3d.utility.Vector3dVector(above_base)volume,height_map=self.calculate_volume_height_map(pcd_above)return{'volume':volume,'base_height':base_height,'max_height':above_base[:,2].max()-base_height,'height_map':height_map,}if__name__=="__main__":# 加载点云pcd=o3d.io.read_point_cloud("stockpile.pcd")calc=VolumeCalculator()# 方法 1:凸包vol_convex=calc.calculate_volume_convex_hull(pcd)print(f"凸包体积:{vol_convex:.2f}m³")# 方法 2:高度图result=calc.calculate_stockpile_volume(pcd)print(f"堆料体积:{result['volume']:.2f}m³")print(f"最大高度:{result['max_height']:.2f}m")#!/usr/bin/env python3"""calibration.py - 体积测量精度校准"""importnumpyasnpclassVolumeCalibrator:"""体积测量校准器"""def__init__(self):self.scale_factor=1.0self.bias=0.0defcalibrate(self,measured_volumes,reference_volumes):"""校准"""measured=np.array(measured_volumes)reference=np.array(reference_volumes)# 线性回归: reference = scale * measured + biasA=np.vstack([measured,np.ones(len(measured))]).T self.scale_factor,self.bias=np.linalg.lstsq(A,reference,rcond=None)[0]# 计算校准后误差calibrated=self.scale_factor*measured+self.bias errors=np.abs(calibrated-reference)/reference*100print(f"校准系数: scale={self.scale_factor:.4f}, bias={self.bias:.4f}")print(f"校准前平均误差:{np.mean(np.abs(measured-reference)/reference*100):.2f}%")print(f"校准后平均误差:{np.mean(errors):.2f}%")defapply_calibration(self,measured_volume):"""应用校准"""returnself.scale_factor*measured_volume+self.bias# 校准示例calibrator=VolumeCalibrator()# 已知体积的标定物calibrator.calibrate(measured_volumes=[1.02,2.05,3.08,4.12,5.15],reference_volumes=[1.00,2.00,3.00,4.00,5.00])#!/usr/bin/env python3"""realtime_stockpile.py - 实时堆方量监测"""importcv2importnumpyasnpimporttimeclassStockpileMonitor:"""堆方量监测器"""def__init__(self,camera,calculator):self.camera=camera self.calculator=calculator self.history=[]defmeasure_once(self):"""单次测量"""pcd=self.camera.capture_pointcloud()result=self.calculator.calculate_stockpile_volume(pcd)self.history.append({'time':time.time(),'volume':result['volume'],'max_height':result['max_height'],})returnresultdefget_trend(self,window=10):"""获取趋势"""iflen(self.history)<2:return0recent=self.history[-window:]volumes=[h['volume']forhinrecent]# 计算变化率iflen(volumes)>=2:rate=(volumes[-1]-volumes[0])/len(volumes)returnratereturn0defrun(self,interval=5):"""持续监测"""print("开始堆方量监测...")whileTrue:result=self.measure_once()trend=self.get_trend()print(f"体积:{result['volume']:.2f}m³ | "f"最大高度:{result['max_height']:.2f}m | "f"变化率:{trend:+.2f}m³/次")time.sleep(interval)if__name__=="__main__":camera=PointCloudCapture()calculator=VolumeCalculator()monitor=StockpileMonitor(camera,calculator)monitor.run()| 方法 | 精度 | 速度 | 适用场景 |
|---|---|---|---|
| 凸包 | 低 | 快 | 凸形物体 |
| Alpha Shape | 中 | 中 | 不规则形状 |
| 高度图 | 高 | 快 | 堆料/仓储 |
| 体素化 | 高 | 慢 | 复杂形状 |