2、3D 手部 - 对象交互序列优化:TOCH 方法解析

3D 手部 - 对象交互序列优化:TOCH 方法解析

1. 引言

在虚拟现实和增强现实的众多应用中,追踪与物体交互的手部动作至关重要,例如建模能够执行操作任务的数字人类。然而,目前针对手部与物体的联合追踪研究相对较少。由于手部可能的配置具有高自由度、频繁的遮挡以及观测数据的噪声或不完整性(如 RGB 图像中缺乏深度通道),使得该问题具有很强的不适定性。

现有的手部追踪器,特别是那些依赖极少摄像头的追踪器,常常产生视觉上不真实的结果,如手部与物体相交或缺少接触。虽然纠正这些错误需要考虑交互的时间方面,但大多数先前的工作主要集中在静态抓握和接触上。

为了解决这些问题,本文提出了 TOCH 方法,这是一种基于数据驱动的方法,用于优化错误的 3D 手部 - 对象交互序列。与先前的交互建模工作不同,TOCH 不仅考虑静态交互,还可以应用于序列,而不会引入突然变化的伪影。

2. 相关工作
2.1 手部和对象重建
  • 手部重建和追踪 :从 RGB 或深度观测中重建 3D 手表面是一个研究较为充分的问题。现有工作通常可分为判别式方法和生成式方法。判别式方法直接从观测中估计手部形状和姿势参数,而生成式方法则迭代优化参数化手部模型,使其投影与观测匹配。然而,这些工作大多忽略了物体的存在,因此在交互密集的场景中可靠性较低。
  • 联合手部和对象重建 :联合重建交互中的手部和对象受到了广泛关注。由于手部 - 对象交互数据集的增加,深度神经网络常被用于估计手部和对象姿势的初始假设,然后进行联合优化以满足某些交互约束。但这些简单方法通常会
public override void HandleToolStopped(object stateSwchLock) { try { //NMC.Scheduling.Scheduler.GetInstance().StopSchedule(); // <><> stop scheduler for continuous calls, ALN 20150928 MissRun if (this.mRescheduleEventFired) { this.mRescheduleEventFired = false; // <> reset //<><><>yangy 20160617<><><>Coordinator.GetIns().RecalculateProcessTime(); string err = ""; Coordinator.GetIns().RecalculateProcessTime(ref err); if (!string.IsNullOrEmpty(err)) { Coordinator.GetIns().GetLogger().ErrorFormat("TaskManagerRunning::HandleToolStopped(): {0}", err); } TaskManager.GetIns().UpdateAllTasks(); // <><> yangy: update task for removed modules List<ArrayList> routelist = new List<ArrayList>(); List<Material> wfs = new List<Material>(); using (StreamReader sr = new StreamReader("txt.txt")) { List<string> strlist = new List<string>(); string str = null; List<string> tasklist = new List<string>(); Dictionary<string, double> modTimes = ModuleManager.GetIns().GetModuleAvailableTimes(); while ((str = sr.ReadLine()) != null) { if (str.Contains("DefineRoutes")) { str = str.Substring(str.IndexOf(':') + 1); string[] steplist = str.Split('|'); ArrayList routedefine = new ArrayList(); for (int i = 1; i <= 25; ++i) { Route route = new Route("route"); for (int stepidx = 0; stepidx < steplist.Length; ++stepidx) { RouteStep step = new RouteStep(); if (stepidx == 0 || stepidx == steplist.Length - 1) { Visit visit = new Visit(steplist[stepidx], i, "", "", ""); step.AddVisit(visit); } else { // string[] visitlist = steplist[stepidx].Split(','); for (int vstidx = 0; vstidx < visitlist.Length; ++vstidx) { string[] rcpstr = visitlist[vstidx].Split('#'); string chamber = rcpstr[0]; string rcp = rcpstr.Length == 1 ? "" : rcpstr[1]; Visit visit = new Visit(chamber, 0, "", "", rcp); step.AddVisit(visit); } } route.AddStep(step); } routedefine.Add(route); } routelist.Add(routedefine); } if (str.Contains("@@ MovableMaterial:")) { int pos = str.IndexOf("ID("); int matid = int.Parse(str.Substring(pos + 3, str.IndexOf(')', pos) - pos - 3)); strlist.Add(str.Substring(pos + 3, str.IndexOf(')', pos) - pos - 3)); // matid pos = str.IndexOf("Name("); string[] matName = str.Substring(pos + 5, str.IndexOf(')', pos) - pos - 5).Split('.'); if (!tasklist.Contains(matName[0])) { tasklist.Add(matName[0]); } int taskid = tasklist.Count; int matsrcslot = int.Parse(matName[1]); strlist.Add(tasklist.Count.ToString()); // taskid strlist.Add(matName[1]); // matsrcslot pos = str.IndexOf("CurStep("); int stepid = int.Parse(str.Substring(pos + 8, str.IndexOf(')', pos) - pos - 8)); strlist.Add(str.Substring(pos + 8, str.IndexOf(')', pos) - pos - 8)); // curstep pos = str.IndexOf("CurPos("); string curPos = str.Substring(pos + 7, str.IndexOf(')', pos) - pos - 7); strlist.Add(str.Substring(pos + 7, str.IndexOf(')', pos) - pos - 7)); // curpos Material matNew = new Material(matid, taskid, (Route)routelist[taskid - 1][matsrcslot - 1], stepid, curPos.Substring(0, curPos.LastIndexOf('_')), int.Parse(curPos.Substring(curPos.LastIndexOf('_') + 1)), true, "nocare", matName[0] + "." + matName[1], "nocare", 0); matNew.IsFromPureJob = true; wfs.Add(matNew); if (!curPos.Contains("ATR") && !curPos.Contains("VTR")) { matNew.Route.GetStep(stepid).GetVisit(curPos.Substring(0, curPos.IndexOf('_'))).ProcessRecipe = string.Empty; } } if (str.Contains("UnleftMats")) { int taskid = int.Parse(str.Substring(str.IndexOf(':') + 1, 1)); string[] startend = str.Substring(str.IndexOf(',') + 1).Split('~'); int start = int.Parse(startend[0]); int end = int.Parse(startend[1]); for (; start <= end; ++start) { Route route = (Route)routelist[taskid - 1][start - 1]; string station = route.GetStep(0).GetVisit(0).StationName; Material matlp = new Material(10000 + start, taskid, route, 0, station, start, true, "nocare", station + "." + start.ToString(), "nocare", 0); matlp.IsFromPureJob = true; wfs.Add(matlp); } } if (str.Contains("UpdateStationAvailableTime:")) { double availabletime = double.Parse(str.Substring(str.IndexOf("= ") + 2)); if (availabletime != 0) { string chamber = str.Substring(str.IndexOf("UpdateStationAvailableTime: ") + 28, str.IndexOf(" =") - str.IndexOf("UpdateStationAvailableTime: ") - 28); modTimes[chamber] = availabletime; } } } NMC.Scheduling.Scheduler.GetInstance().AddMaterials(wfs); // deep copy all materials <> Coordinator.GetIns().SetMDxRecvMatIntvlMin(); // <> yangy 20170320: for MDx //Dictionary<string, double> modTimes = ModuleManager.GetIns().GetModuleAvailableTimes(); NMC.Scheduling.Scheduler.GetInstance().UpdateStationAvailableTime(modTimes); } #endif NMC.Scheduling.Scheduler.GetInstance().AddMaterials(MoveManager.GetIns().GetSortedMats()); // deep copy all materials <> Coordinator.GetIns().SetMDxRecvMatIntvlMin(); // <> yangy 20170320: for MDx NMC.Scheduling.Scheduler.GetInstance().UpdateStationAvailableTime(ModuleManager.GetIns().GetModuleAvailableTimes()); #endif NMC.Scheduling.Scheduler.GetInstance().StartSchedule(); // will trigger new move event <> } } catch (Exception ex) // <> yangy 20181016: avoid deadlock from Polaris 300mm zentao_bug_6354 { Coordinator.GetIns().GetLogger().FatalFormat("TaskManagerRunning::HandleToolStopped(): {0}", ex.Message); } finally // <> yangy 20181016: avoid deadlock from Polaris 300mm zentao_bug_6354 { Monitor.Exit(stateSwchLock); // <><> avoid racing-condition with 'PauseTool()' method } } }这个C#程序可以实现对log文件的读取,比如log内容是这样的:DefineRoutes:LP2|LA|Ch1#/Ch1/3601;1|Ch3#/Ch3/175;1|Ch4#/Ch4/23.3;1|Ch5#/Ch5/65.3;1|LB|LP2 DefineRoutes:LP1|LA|Ch1#/Ch1/601;1|Ch3#/Ch3/110;1|Ch5#/Ch5/65.3;1|LB|LP1 2021-07-31 13:07:59.236 WARN [17420] Scheduler - @@ MovableMaterial: ID(378), Name(LP2.3), CurPos(Ch5_1), CurStep(5) 2021-07-31 13:07:59.236 WARN [17420] Scheduler - @@ MovableMaterial: ID(379), Name(LP2.4), CurPos(Ch4_1), CurStep(4) 2021-07-31 13:07:59.236 WARN [17420] Scheduler - @@ MovableMaterial: ID(380), Name(LP2.5), CurPos(Ch3_1), CurStep(3) 2021-07-31 13:07:59.236 WARN [17420] Scheduler - @@ MovableMaterial: ID(381), Name(LP2.6), CurPos(Ch1_7_1), CurStep(2) 2021-07-31 13:07:59.236 WARN [17420] Scheduler - @@ MovableMaterial: ID(382), Name(LP2.7), CurPos(Ch1_18_1), CurStep(2)。 现在需要对程序添加新功能,可以实现读取log自动生成路径的代码。比如log日志文件中的路径表示为:2025-08-28 13:36:47.429 WARN [11692] Coordinator - Slot{0}: Route(a) Group:Default2025-08-28 13:36:47.429 WARN [11692] Coordinator - Step(0)2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).StationName: LB2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).SlotID: 22025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).ProcessRecipe: 2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(1).StationName: LA2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(1).SlotID: 22025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(1).ProcessRecipe: 2025-08-28 13:36:47.429 WARN [11692] Coordinator - Step(1)2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).StationName: ChD2025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).SlotID: 02025-08-28 13:36:47.429 WARN [11692] Coordinator - Visit(0).ProcessRecipe: /ChD/test;12025-08-28 13:36:47.430 WARN [11692] Coordinator - Visit(1).StationName: ChC2025-08-28 13:36:47.430 WARN [11692] Coordinator - Visit(1).SlotID: 02025-08-28 13:36:47.430 WARN [11692] Coordinator - Visit(1).ProcessRecipe: /ChC/test;12025-08-28 13:36:47.431 WARN [11692] Coordinator - Step(2)2025-08-28 13:36:47.431 WARN [11692] Coordinator - Visit(0).StationName: ChE2025-08-28 13:36:47.431 WARN [11692] Coordinator - Visit(0).SlotID: 02025-08-28 13:36:47.431 WARN [11692] Coordinator - Visit(0).ProcessRecipe: /ChE/test_100s;12025-08-28 13:36:47.432 WARN [11692] Coordinator - Visit(1).StationName: ChF2025-08-28 13:36:47.432 WARN [11692] Coordinator - Visit(1).SlotID: 02025-08-28 13:36:47.432 WARN [11692] Coordinator - Visit(1).ProcessRecipe: /ChF/test_100s;1 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Step(3) 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).StationName: ChA 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).SlotID: 0 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).ProcessRecipe: 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Step(4) 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).StationName: Ch1 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).SlotID: 0 2025-08-28 13:36:47.434 WARN [11692] Coordinator - Visit(0).ProcessRecipe: /Ch1/test100s;1 2025-08-28 13:36:47.438 WARN [11692] Coordinator - Step(5) 2025-08-28 13:36:47.438 WARN [11692] Coordinator - Visit(0).StationName: Ch6 2025-08-28 13:36:47.438 WARN [11692] Coordinator - Visit(0).SlotID: 0 2025-08-28 13:36:47.438 WARN [11692] Coordinator - Visit(0).ProcessRecipe: /Ch6/test100s;1 2025-08-28 13:36:47.439 WARN [11692] Coordinator - Visit(1).StationName: Ch4 2025-08-28 13:36:47.439 WARN [11692] Coordinator - Visit(1).SlotID: 0 2025-08-28 13:36:47.439 WARN [11692] Coordinator - Visit(1).ProcessRecipe: /Ch4/test100s;1 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Step(6) 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Visit(0).StationName: ChB 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Visit(0).SlotID: 0 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Visit(0).ProcessRecipe: /ChB/cool;1 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Step(7) 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Visit(0).StationName: LB 2025-08-28 13:36:47.440 WARN [11692] Coordinator - Visit(0).SlotID: 1 2025-08-28 13:36:47.441 WARN [11692] Coordinator - Visit(0).ProcessRecipe: 2025-08-28 13:36:47.441 WARN [11692] Coordinator - Visit(1).StationName: LA 2025-08-28 13:36:47.441 WARN [11692] Coordinator - Visit(1).SlotID: 1 2025-08-28 13:36:47.441 WARN [11692] Coordinator - Visit(1).ProcessRecipe: 在写入程序需要为:ArrayList routes = new ArrayList(); for (int i = 1; i <= 1; ++i) { Visit fromCassA = new Visit("LP1", i, "", "", "", ""); RouteStep step1 = new RouteStep(); step1.AddVisit(fromCassA); Visit inLLB = new Visit("LB", 2, "", "", "", ""); Visit inLLA = new Visit("LA", 2, "", "", "", ""); RouteStep step2 = new RouteStep(); step2.AddVisit(inLLB); step2.AddVisit(inLLA); Visit todegas1 = new Visit("ChD", 0, "", "", "/ChD/test;1", ""); Visit todegas2 = new Visit("ChC", 0, "", "", "/ChC/test;1", ""); RouteStep step3 = new RouteStep(); step3.AddVisit(todegas1); step3.AddVisit(todegas2); Visit toche = new Visit("ChE", 0, "", "", "/ChE/test_100s;1", ""); Visit tochf = new Visit("ChF", 0, "", "", "/ChF/test_100s;1", ""); RouteStep step4 = new RouteStep(); step4.AddVisit(toche); step4.AddVisit(tochf); Visit tobypass1 = new Visit("ChA", 0, "", "", "", ""); RouteStep step5 = new RouteStep(); step5.AddVisit(tobypass1);Visit toch1 = new Visit("Ch1", 0, "", "", "/Ch1/test100s;1", ""); RouteStep step6 = new RouteStep(); step6.AddVisit(toch1); Visit toch6 = new Visit("Ch6", 0, "", "", "/Ch6/test100s;1", ""); Visit toch4 = new Visit("Ch4", 0, "", "", "/Ch4/test100s;1", ""); RouteStep step7 = new RouteStep(); step7.AddVisit(toch6); step7.AddVisit(toch4); Visit tocu1 = new Visit("ChB", 0, "", "", "/ChB/cool;1", ""); RouteStep step8 = new RouteStep(); step8.AddVisit(tocu1); Visit tobypass11 = new Visit("LB", 1, "", "", "", ""); Visit tobypass21 = new Visit("LA", 1, "", "", "", ""); RouteStep step9 = new RouteStep(); step9.AddVisit(tobypass11); step9.AddVisit(tobypass21); Visit toCassA = new Visit("LP1", i, "", "", "", ""); RouteStep step10 = new RouteStep(); step10.AddVisit(toCassA); Route route = new Route("route"); route.AddStep(step1); route.AddStep(step2); route.AddStep(step3); route.AddStep(step4); route.AddStep(step5); route.AddStep(step6); route.AddStep(step7); route.AddStep(step8); route.AddStep(step9); route.AddStep(step10); routes.Add(route); }。请你对上面的HandleToolStopped函数进行完善,添加读取路径的功能,能够通过日志中给出的路径,自动生成路径代码,而不是手动编写路径代码。
09-20
这个是完整源码 python实现 Flask,Vue 【python毕业设计】基于Python的Flask+Vue物业管理系统 源码+论文+sql脚本 完整版 数据库是mysql 本文首先实现了基于Python的Flask+Vue物业管理系统技术的发展随后依照传统的软件开发流程,最先为系统挑选适用的言语和软件开发平台,依据需求分析开展控制模块制做和数据库查询构造设计,随后依据系统整体功能模块的设计,制作系统的功能模块图、E-R图。随后,设计框架,依据设计的框架撰写编码,完成系统的每个功能模块。最终,对基本系统开展了检测,包含软件性能测试、单元测试和性能指标。测试结果表明,该系统能够实现所需的功能,运行状况尚可并无明显缺点。本文首先实现了基于Python的Flask+Vue物业管理系统技术的发展随后依照传统的软件开发流程,最先为系统挑选适用的言语和软件开发平台,依据需求分析开展控制模块制做和数据库查询构造设计,随后依据系统整体功能模块的设计,制作系统的功能模块图、E-R图。随后,设计框架,依据设计的框架撰写编码,完成系统的每个功能模块。最终,对基本系统开展了检测,包含软件性能测试、单元测试和性能指标。测试结果表明,该系统能够实现所需的功能,运行状况尚可并无明显缺点。本文首先实现了基于Python的Flask+Vue物业管理系统技术的发展随后依照传统的软件开发流程,最先为系统挑选适用的言语和软件开发平台,依据需求分析开展控制模块制做和数据库查询构造设计,随后依据系统整体功能模块的设计,制作系统的功能模块图、E-R图。随后,设计框架,依据设计的框架撰写编码,完成系统的每个功能模块。最终,对基本系统开展了检测,包含软件性能测试、单元测试和性能指标。测试结果表明,该系统能够实现所需的功能,运行状况尚可并无明显缺点。本文首先实现了基于Python的Flask+Vue物业管理系统技术的发
源码地址: https://pan.quark.cn/s/a4b39357ea24 # SerialAssistant串口助手 下载地址: 本仓库release文件夹 在线下载:http://mculover666.cn/SerialAssistant.zip 功能说明 本项目是使用C# + WinForm框架编写的串口助手。 目前版本为2.0.0版本,拥有以下功能: 未打开串口时,自动扫描可用端口 接收数据支持文本或者HEX方式显示 支持接收数据加入时间戳 支持将当前接收数据保存为文件 支持发送文本数据或HEX数据 支持自动定时发送数据 支持从文件中(.txt, .json)加载数据到发送文本框 支持发送数据记录(不重复记录) ……欢迎加入更多功能 环境说明 VS2019 .NET Framework 4.5 教程 C#上位机开发(一)—— 了解上位机 C#上位机开发(二)—— Hello,World C#上位机开发(三)—— 构建SerialAssistant雏形 C#上位机开发(四)—— SerialAssistant功能完善 C#上位机开发(五)——SerialAssistant界面升级(WinForm界面布局进阶) C#上位机开发(六)——SerialAssistant功能优化(串口自动扫描功能、接收数据保存功能、加载发送文件、发送历史记录、打开浏览器功能、定时发送功能) C#上位机开发(七)—— 修改窗口图标和exe文件图标 C#上位机开发(八)—— 美化界面(给按钮添加背景) 更新日志 2018/6/3 完成串口属性设置,打开与关闭异常处理; 字符串发送功能; 字符串接收功能; 2018/6/4 完善串口扩展功能界面部分 2018/6/6 完善...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值