Surface Pro/Laptop 开启Secure Boot也能玩转Ubuntu/Arch双系统(附内核签名保姆级教程)
2026/5/28 18:03:50
存在提取类.ixx)// 在 存在提取类 中添加以下代码private:struct子连通组件{std::vector<点索引>像素列表;// 在父ROI内的局部坐标intumin,umax,vmin,vmax;// 子ROI边界int像素数=0;Vector3D 子中心{0,0,0};Vector3D 子尺寸{0,0,0};};// 从父掩膜提取所有独立子连通组件staticstd::vector<子连通组件>提取子连通组件(conststd::vector<std::uint8_t>&父掩膜,int父ROI_w,int父ROI_h,int最小像素数=100){std::vector<子连通组件>子组件;std::vector<bool>visited(父掩膜.size(),false);constexprstd::array<std::array<int,2>,8>offsets8={{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}};for(intv=0;v<父ROI_h;++v){for(intu=0;u<父ROI_w;++u){size_t idx=static_cast<size_t>(v)*父ROI_w+u;if(父掩膜[idx]==0||visited[idx])continue;// 新连通组件子连通组件 comp;comp.umin=comp.umax=u;comp.vmin=comp.vmax=v;std::queue<点索引>q;q.push({u,v});visited[idx]=true;while(!q.empty()){autop=q.front();q.pop();comp.像素列表.push_back(p);comp.umin=std::min(comp.umin,p.u);comp.umax=std::max(comp.umax,p.u);comp.vmin=std::min(comp.vmin,p.v);comp.vmax=std::max(comp.vmax,p.v);for(constauto&d:offsets8){intnu=p.u+d[0];intnv=p.v+d[1];if(nu>=0&&nu<父ROI_w&&nv>=0&&nv<父ROI_h){size_t nidx=static_cast<size_t>(nv)*父ROI_w+nu;if(父掩膜[nidx]&&!visited[nidx]){visited[nidx]=true;q.push({nu,nv});}}}}comp.像素数=static_cast<int>(comp.像素列表.size());if(comp.像素数>=最小像素数){子组件.push_back(std::move(comp));}}}return子组件;}public:// 递归提取子存在(主接口)staticvoid递归提取子存在(const结构体_存在观测&父观测,std::vector<结构体_存在观测>&子存在列表,const观测提取参数&p,int当前深度=0,int最大深度=3){if(当前深度>=最大深度)return;if(父观测.裁剪掩膜.empty())return;constintfw=父观测.ROI_w;constintfh=父观测.ROI_h;// 提取子连通组件auto子组件=提取子连通组件(父观测.裁剪掩膜,fw,fh,p.最小有效点数/4);for(auto&comp:子组件){// 过滤太小或太接近父边界的子块(可能是噪声或粘连)float子宽=comp.umax-comp.umin+1;float子高=comp.vmax-comp.vmin+1;float子面积比=static_cast<float>(comp.像素数)/(fw*fh);if(子面积比<0.05f||子面积比>0.8f)continue;// 太小或太大都不是好子存在结构体_存在观测 子obs;// 子ROI信息(相对于父ROI)子obs.ROI_x=父观测.ROI_x+comp.umin;子obs.ROI_y=父观测.ROI_y+comp.vmin;子obs.ROI_w=static_cast<int>(子宽);子obs.ROI_h=static_cast<int>(子高);// 提取子裁剪图像和子掩膜子obs.裁剪图像_BGR.resize(static_cast<size_t>(子obs.ROI_w)*子obs.ROI_h);子obs.裁剪掩膜.assign(static_cast<size_t>(子obs.ROI_w)*子obs.ROI_h,0);for(constauto&local_pix:comp.像素列表){intlocal_u=local_pix.u-comp.umin;intlocal_v=local_pix.v-comp.vmin;size_t local_idx=static_cast<size_t>(local_v)*子obs.ROI_w+local_u;size_t parent_idx=static_cast<size_t>(local_pix.v)*fw+local_pix.u;子obs.裁剪图像_BGR[local_idx]=父观测.裁剪图像_BGR[parent_idx];子obs.裁剪掩膜[local_idx]=1;}// 计算子中心和尺寸(可结合深度点云更准,这里用AABB近似)// 简化:用像素中心估算Vector3D 子中心像素{static_cast<float>(comp.umin+comp.umax)*0.5f,static_cast<float>(comp.vmin+comp.vmax)*0.5f,父观测.中心坐标.z// 近似同一深度};// 实际项目中可用重投影得到准确3D中心子obs.中心坐标=子中心像素;// 临时占位,实际需重投影子obs.尺寸={子宽/fw*父观测.尺寸.x,子高/fh*父观测.尺寸.y,父观测.尺寸.z*0.8f};// 厚度估算// 生成轮廓编码生成多尺度轮廓金字塔(子obs.裁剪掩膜,子obs.ROI_w,子obs.ROI_h,子obs,p.生成多尺度轮廓);// 其他特征(平均颜色、边缘等)// ... 可复用主提取逻辑子存在列表.push_back(std::move(子obs));// 递归:对大子块继续提取孙存在if(子面积比>0.2f&&当前深度+1<最大深度){std::vector<结构体_存在观测>孙列表;递归提取子存在(子存在列表.back(),孙列表,p,当前深度+1,最大深度);// 孙存在可进一步处理(如存入更深附属世界)}}}// 在外设循环或融合后for(constauto&main_obs:obsList){// 融合主存在到世界树(已有)// 提取子存在std::vector<结构体_存在观测>子存在列表;存在提取类::递归提取子存在(main_obs,子存在列表,提取参数);// 为每个子存在创建附属世界节点(在三维场景管理中)for(auto&sub_obs:子存在列表){// 创建子存在 + 附属世界 + 存储相对特征}}现在你的数字生命已经能“看清物体的内部结构”了!