# 混合现实辅助装配科研课堂 **Repository Path**: jokerjdy/detection-of-assembly-state-class ## Basic Information - **Project Name**: 混合现实辅助装配科研课堂 - **Description**: 北航混合现实辅助装配科研课堂相关文件 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2024-09-20 - **Last Updated**: 2025-02-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: Unity ## README [TOC] # 第一课_20240902 ## 智能检测服务端 ### 学习内容 #### python语言学习 - 参考文档 - [python编程——从入门到实践](https://pan.baidu.com/s/1ne9curHoSlILtLFMsOy2Tw?pwd=edxr) - [python基础教程](https://www.runoob.com/python/python-tutorial.html) - 参考视频 - [python教程](https://www.bilibili.com/video/BV1qW4y1a7fU/) > [!NOTE] > > python语言的学习可以在项目中继续,目前阶段只需要读懂基本语法,能够使用基本数据结构和程序结构即可。 #### 深度学习环境部署 - Anaconda python虚拟环境管理器 - cuda、cudnn 英伟达N卡深度学习支持 - pytorch python深度学习框架 - git 版本控制器,主要用于拉取已有程序代码 > [!IMPORTANT] > > 以上内容可在CSDN、知乎等网站搜素,查看时注意文章发布时间,越接近当前时间越好,git安装可后续再进行,主要完成前三项。 ### 本周任务 - 完成深度学习环境部署 - 安装深度学习框架搭建 - 安装YOLO模型的python库`ultralytics` - (*选做*)编写代码调用YOLO预训练模型进行简单识别 ### 拓展参考 YOLO系列论文 - [YOLOv1](https://arxiv.org/abs/1506.02640) - [YOLOv2/YOLO9000](https://arxiv.org/abs/1612.08242) - [YOLOv3](https://arxiv.org/abs/1804.02767) - [YOLOv4](https://arxiv.org/abs/2004.10934) - [YOLOv6](https://arxiv.org/pdf/2209.02976.pdf) - [YOLOv7](https://arxiv.org/pdf/2207.02696.pdf) - [YOLOv9](https://arxiv.org/abs/2402.13616) > [!TIP] > > 可参考文章[YOLO论文精读系列](https://blog.csdn.net/weixin_43334693/article/details/129011644?spm=1001.2014.3001.5502)。 ## MR设备端 ### 学习内容 #### HOLOLENS智能眼镜 ![HOLOLENS爆炸图](https://learn.microsoft.com/zh-cn/hololens/images/hololens2-exploded-view-diagram.png) - Hololens2是由微软设计开发的一款全息计算机,运行的是**Windows**系统。 - 具体信息可在微软官网查看:[Microsoft HoloLens](https://learn.microsoft.com/zh-cn/hololens/) - 主要了解[使用Hololens](https://learn.microsoft.com/zh-cn/hololens/hololens2-setup)和[部署Hololens](https://learn.microsoft.com/zh-cn/hololens/hololens-requirements)两部分 #### MRTK3混合现实开发 ##### 部署MRTK3工具包 ![MRTK3](https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/unity/images/featuretoolstart.png) - 参考MRTK官方教程教程 - [MRTK简介](https://learn.microsoft.com/zh-cn/windows/mixed-reality/mrtk-unity/mrtk2/?view=mrtkunity-2022-05) - [MRTK使用](https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/unity/welcome-to-mr-feature-tool) ##### 学习微软官方开发教程 - 重点关注1~3节 - 教程地址:[HOLOLENS开发教程](https://learn.microsoft.com/zh-cn/training/paths/beginner-hololens-2-tutorials/) ### 本周任务 - 完成unity、visual studio、MRTK3环境的部署 - 完成[HOLOLENS开发教程](https://learn.microsoft.com/zh-cn/training/paths/beginner-hololens-2-tutorials/)第一节内容 > [!TIP] > > unity采用c#进行脚本开发,在使用unity进行开发前建议先了解c#基本语法,能够使用基本数据类型及程序结构。 ### 拓展参考 - [c#学习文档](https://www.runoob.com/csharp/csharp-tutorial.html) - [c#官方文档](https://learn.microsoft.com/zh-cn/dotnet/csharp/) - [Unity官方文档](https://docs.unity.cn/cn/2022.3/Manual/UnityManual.html) - [Unity官方开发教程](https://learn.u3d.cn/for-beginners) # 第二课_20240911 ## 智能检测服务 ### 学习内容 #### YOLO模型应用 ```python from ultralytics import YOLO # Load the model model = YOLO("yolov8n.yaml") model = YOLO("yolov8n.pt") # Evaluate the model's performance on the validation set results = model.val() # Use the model results = model("https://ultralytics.com/images/bus.jpg") # Export the model to ONNX format success = model.export(format="onnx") ``` YOLO模型简单调用代码 - 一个YOLO模型总检测类别数为80 - YOLO输出为检测物体类别及其位置坐标以及置信度,结构为ultralytics.engine.results.Results对象,具体查看[YOLO Docs](https://docs.ultralytics.com/reference/engine/results/) #### YOLO模型微调 ```python # Train the model results = model.train(data="coco8.yaml", epochs=3) ``` 微调代码 - data:训练yaml文件路径 - epochs:迭代次数 ```yaml train: D:\path\to\data\train # 训练集路径 val: D:\path\to\data\valid # 评估集路径 test: D:\path\to\data\test # 测试集路径 nc: 2 # YOLO识别数量 names: ['cls1', 'cls2'] # YOLO识别各类名称 ``` yaml文件示例 - 更多yaml文件配置可以自行搜索 - 图像标注请使用[labelme](https://github.com/labelmeai/labelme)离线标注,**禁止**使用在线标注软件 > [!TIP] > > 数据集文件结构 > > > ``````powershell > > Project > > ├─test > > │ ├─images > > │ └─labels > > ├─train > > │ ├─images > > │ └─labels > > └─valid > > ├─images > > └─labels > > `````` > > > > - images存放图片文件 > > - labels存放标注txt文件 #### python学习 - [Python3教程文档](https://www.runoob.com/python3/python3-tutorial.html) - [python3.10文档](https://docs.python.org/zh-cn/3.10/) > [!NOTE] > > python学习参考3.10版本,不要使用3.10以上版本特性,避免程序不兼容。 ### 本周任务 - 完善ultralytics官方代码,实现输入一张图片,输出带有识别类型、边界框、置信度的结果图片,注意[ultralytics.engine.results.Results](https://docs.ultralytics.com/reference/engine/results/)对象的使用。 - 使用python完成一个猜数字小游戏 - 要求: - 程序每次运行后需要猜测的目标数字是随机的 - 猜测数字范围可配置 - 猜测次数N有限,且必须小于$log_{2}(N)$ - 每次交互都必须反馈输入数字是大于或小于目标数 - 所有可配置项需要使用JSON格式文件进行存储,在程序运行时读取配置文件确定参数 - 可配置项: - 猜测数字范围最小值$min$ - 猜测数字范围最大值$max$ - 猜测次数$N$ ## MR设备 ### 学习内容 #### MR设备开发 - 学习教程1~3节 - 教程地址:[HOLOLENS开发教程](https://learn.microsoft.com/zh-cn/training/paths/beginner-hololens-2-tutorials/) #### C#学习 - [c#学习文档](https://www.runoob.com/csharp/csharp-tutorial.html) - [Unity文档](https://docs.unity.cn/cn/2022.3/Manual/UnityManual.html) ### 本周任务 - 完成教程1~3节 - 在Unity中实现一个c#脚本 - 要求: - 脚本名称统一命名为Player - 挂载后物体能使用键盘的WASD控制前后左右移动 - 挂载后物体能随鼠标移动实现上下左右旋转 ## Delmia ### 本周任务 - 完成Delmia安装 - 自由创建3维零件后尝试完成简单动画制作 # 第三课_20240918 ## 智能检测服务端 ### 学习内容 #### 图像标注 ![labelme](https://i-blog.csdnimg.cn/blog_migrate/a2688203501506f495f19d892bb3184b.jpeg#pic_center) - 使用labelme进行图像标注 - 项目[github主页](https://github.com/labelmeai/labelme) - 使用教程可参考[labelme超详细教程](https://blog.csdn.net/u014264373/article/details/115918118) #### python学习 参考*2.1.1.3* ### 本周任务 - 编写python程序,实现labelme标注图像转为YOLO训练格式图像 - (*选做*)找30~40张自己感兴趣的检测照片,用labelme标注,并转为YOLO格式训练文件对YOLO模型进行微调,查看微调效果 ## MR设备端 ### 学习内容 #### C#学习 参考*2.2.1.2* #### hololens UI开发 ![MRTK3 UX](https://learn.microsoft.com/zh-cn/windows/mixed-reality/mrtk-unity/mrtk3-overview/images/uxbuildingblocks/button/mrtk_button_canvastearsheet.png) - hololens UI开发主要使用MRTK3配套UX中的prefab进行 - 文档可参考[UX 组件 - MRTK3 | Microsoft Learn](https://learn.microsoft.com/zh-cn/windows/mixed-reality/mrtk-unity/mrtk3-uxcomponents/packages/uxcomponents/overview) ### 本周任务 - 完成上周Unity脚本编写 - 使用MRTK3的预制体搭建一个简单的对话框,包含如下内容: - 标题栏 - 右上角关闭按钮 - 内容主体 - 确认按钮 - 取消按钮 # 第四课_20240925 ## 智能检测服务端 ### 学习内容 ![数据增强](https://pypi-camo.freetls.fastly.net/46621a780ae56d322269bb2a4912edb5af84a4e9/68747470733a2f2f686162726173746f726167652e6f72672f776562742f62642f6e652f72762f62646e6572763563746b75646d73617a6e687734637273646669772e6a706567) #### 安装并引入数据增强第三方库albumentations ```powershell pip install albumentations # 安装albumentation pip isntall opencv-python # 安装opencv库 ``` ```python import albumentations import cv2 ``` #### 使用albumentations 主要关注一下几个类的使用: - Compose:用于构造图像转换器 - OneOf:以一定概率从几种增强方法中选择一种进行 - BboxParams:标注边界框参数 - FancyPCA:主成分分析增强 - GaussNoise、ISONoise、PixelDropout:添加噪声 - GaussianBlur:高斯模糊 - Cutout、BBoxSafeRandomCrop:图像剪除 - ShiftScaleRotate:仿射变换 - RandomBrightnessContrast:随机亮度变换 其他使用方法参考[官方文档](https://albumentations.ai/docs/api_reference/full_reference/) ### 本周任务 - 完善课堂例程,实现以下功能: - 实现新的工作流水线 - 对bbox文件以YOLO格式进行保存 - 支持通过输入文件夹的形式遍历文件夹内所用图像进行增强,并将结果保存至指定文件夹下 - 基于以上程序,使用labelme标注自选20~50张图片,并使用图像增强方式将数量增大10倍,并对模型进行微调,查看结果 ## MR设备端 ### 学习内容 #### 实现工序信息显示UI - 创建主要Canvas,并添加Content Size Fitter控制宽度,用于为所有显示信息进行布局 - 创建工序Canvas和工步Canvas,分别显示两种信息 - 使用预制件完成UI界面的设计 - 编写c#脚本,加载信息文件至UI中 - 绑定信息文件与UI显示控件 - 使用NewtonSoft库加载信息Json文件 - 修改UI信息 ### 本周任务 - 理解DataClass文件下的工艺信息模型 - 完善例程,实现以下功能: - 将Json文件保存至Resources文件夹,使用Unity内置Resource类进行加载 - 完整显示工序信息内容 # 第五课_20241009 ## 智能检测服务端 ### 学习内容 #### 常用模型调研 | **模块名称** | **实现框架** | **微调方式** | | --------------- | -------------- | :-------------------------------------------: | | **EasyOCR** | Pytorch | 基于 Pytorch 深度学习框架实现 | | **Pytesseract** | tesseract 引擎 | 基于 tesseract 微调实现 | | **PaddleOCR** | 百度飞浆 | 基于 paddlepaddle 深度学习框架实现 | | **TrOCR** | transformers | 基于 transformers 库 API 或支持的框架原生微调 | | **CnOCR** | Pytorch | 基于 Pytorch 或微调脚本实现 | #### CnOCR使用 - [OCR官网](https://cnocr.readthedocs.io/zh-cn/stable/) - 安装CnOCR - ``````powershell pip install cnocr `````` - 简单应用 - ``````python from cnocr import CnOcr img_fp = 'path/to/your/image' ocr = CnOcr() # 所有参数都使用默认值 out = ocr.ocr(img_fp) print(out) `````` - [🧳 可用模型列表 - CnOCR](https://cnocr.readthedocs.io/zh-cn/stable/models/) - [📖 使用说明 - CnOCR](https://cnocr.readthedocs.io/zh-cn/stable/usage/) ### 本周任务 完善课程程序内容,实现如下功能: - 根据config文件内的type(image/text/none)完成相应的检测(YOLO/OCR/不检测) - 将检测结果转换为`OCRFilterResult/YOLOFilterResult`对象进行输出 ## MR设备端 ### 学习内容 #### 了解Unity中组件的查找方法 ``````c# // 1.声明公开变量通过unity编辑器绑定 public class YourScript : MonoBehaviour { public GameObject field; } // 2.使用代码查找 transform.Find("name").GetComponent<>(); // 用于查找父组件的直接子组件 GameObject.Find("GameObject/ChildGameObject").GetComponent<>(); // 在全局查找 `````` #### 了解实例化预制体的方法 ``````c# // 声明public属性进行绑定 public class YourScript : MonoBehaviour { public Prefab prefab; } // 使用Instantiate方法实例化预制体并绑定父对象 GameObject part = Instantiate(prefab, parent: prefab_parent.transform); part.transform.Find("name").GetComponent<>(); // 修改预制体内容 `````` ### 本周任务 利用以上方法,实现工步内容选择面板,要求显示: - 工步名称 - 工步号 - 工步标题 - 工步内容 # 第六课_20241016 ## 智能检测服务端 ### 学习内容 参考群里发送文件3.3节,了解射线吸附算法的总体流程 ### 本周任务 - 使用python实现射线吸附算法 - 将吸附算法与错误计数器相结合,实现YOLO检测结果的过滤器 ## MR设备端 ### 学习内容 #### HOLOLENS手部菜单 ![手部菜单](https://learn.microsoft.com/zh-cn/windows/mixed-reality/mrtk-unity/mrtk2/features/images/solver/mrtk_ux_handmenu.png?view=mrtkunity-2022-05) 手部菜单是HOLOLENS内置的预制体,其具有以下优势: - 不用时隐藏,不影响操作人员视线 - 可以追踪手部移动,方便操作 详细内容可参阅[手动菜单 - MRTK 2 | Microsoft Learn](https://learn.microsoft.com/zh-cn/windows/mixed-reality/mrtk-unity/mrtk2/features/ux-building-blocks/hand-menu?view=mrtkunity-2022-05) #### 工序工步内容切换 - 使用一个CanvasManager管理工序、工步内容的加载 - 为手部菜单的按钮添加回调函数,调用CanvasManager的重加载函数重加载内容 ### 本周任务 - 实现使用手部菜单切换工序和工步 - *(选做)*思考用栈如何实现多个页面的切换,并尝试实现 # 第七课_20241022 > [!IMPORTANT] > > 下周需要实现两个程序间的网络通信,请大家一定要保证本周任务的质量 ## 智能检测服务端 ### 学习内容 #### TCP/IP ![TCP/IP数据包](https://pic1.zhimg.com/80/v2-b336a50e1d671a5ef82f532c492474fe_1440w.webp?source=1def8aca) - IP地址用于确定计算机 - 端口号用于确定应用程序 ![TCP三次握手](https://pic3.zhimg.com/80/v2-e1b5eff3f8c8ec1cb6f924f91cbfa016_1440w.webp) ![TCP四次挥手](https://pic3.zhimg.com/80/v2-27026268f928cac20e22172bd9abba06_1440w.webp) #### socket编程 ![socket通信流程](https://pic1.zhimg.com/80/v2-3fa310d29577b8f025e6cfc3715def48_1440w.webp) ``````python import socket import struct # 服务端 if __name__ == '__main__': server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) packer = struct.Struct("I") server.bind(("127.0.0.1", 9090)) server.listen(5) conn, addr = server.accept() while True: send_data = input("input something >>>").encode("utf-8") send_data_len = len(send_data) conn.send(packer.pack(send_data_len)) conn.send(send_data) recv_data_len = packer.unpack(conn.recv(4))[0] recv_data = conn.recv(recv_data_len).decode("utf-8") print("recv_data: ", recv_data) `````` ```python import socket import struct # 客户端 if __name__ == '__main__': client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) packer = struct.Struct("I") client.connect(("127.0.0.1", 9090)) while True: recv_data_len = packer.unpack(client.recv(4))[0] recv_data = client.recv(recv_data_len).decode("utf-8") print("recv_data: ", recv_data) send_data = input("input something >>>").encode("utf-8") send_data_len = len(send_data) client.send(packer.pack(send_data_len)) client.send(send_data) ``` ### 本周任务 实现一个微型的服务端与接收端,要求: - 实现对相应信息的提示 - 服务端与客户端数据载荷为json格式字符串 - 服务端根据客户端的数据动态切换过滤器的配置文件 ## MR设备端 ### 学习内容 #### TCP/IP #### socket编程 ![socket通信流程](https://pic1.zhimg.com/80/v2-3fa310d29577b8f025e6cfc3715def48_1440w.webp) ``````c# void WaitConnect() { string ip = "127.0.0.1"; Debug.Log($"[INFO] server ip:{ip}"); IPAddress ipAdress = IPAddress.Parse(ip); //网络端点:为待请求连接的IP地址和端口号 IPEndPoint ipEndpoint = new IPEndPoint(ipAdress, 9090); server.Bind(ipEndpoint); server.Listen(1); while (true) { Socket connect = server.Accept(); Debug.Log($"[INFO] server receive from :{connect.RemoteEndPoint.ToString()}"); try { while (true) { byte[] length = new byte[4]; int num = 0; int len = 0; byte[] buffer = new byte[1048576]; DateTime start_time; DateTime end_time; start_time = DateTime.Now; while (connect.Available < 4) { end_time = DateTime.Now; if ((end_time - start_time).Seconds > 1) { throw new Exception("timed out"); } } // 获取消息长度 num = connect.Receive(length); len = BitConverter.ToInt32(length, 0); while (connect.Available < len) { } num = connect.Receive(buffer, len, SocketFlags.None); //接收服务端消息 receive_info = Encoding.UTF8.GetString(buffer, 0, num); Debug.Log($"[INFO] receive {receive_info}"); } } catch (Exception e) { Debug.Log(e); connect.Close(); continue; } } } `````` ``````c# public void Send() { // 建立连接 string ip = "127.0.0.1"; Debug.Log(ip); client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ipAdress = IPAddress.Parse(ip); //网络端点:为待请求连接的IP地址和端口号 IPEndPoint ipEndpoint = new IPEndPoint(ipAdress, 9090); client.Connect(ipEndpoint); // 编码发送信息 byte[] info = Encoding.UTF8.GetBytes(send_info.text); // 发送消息长度 int send_len = info.Length; byte[] send_length = BitConverter.GetBytes(send_len); client.Send(send_length); client.Send(info); client.Close(); } `````` ### 本周任务 实现一个微型的服务端与接收端,要求: - 客户端仅负责发送信息,服务端仅负责接收信息 - 客户端通过HOLOLENS输入框实现接收用户输入,服务端通过一个自定义界面对信息进行显示 - 服务端与客户端数据载荷为json格式字符串 # 第八课_ ## 学习内容 ### 进程/线程 ![进程/线程](https://i-blog.csdnimg.cn/blog_migrate/c76f43fa45010e0418dfef2f9ebcd177.png) - cpu——工厂 - 进程——车间 - 线程——工人 > [!NOTE] > > - 单核CPU同一时间允许一个进程 > - 多核CPU一时间可以允许多个进程 > - 线程共享内存,进程不共享内存,不同进程间需要将通信 > - 为保证内存安全,进程与线程需要有锁机制 > - python受GIL限制,是伪多线程 ### 多线程示例 ```python import threading import time # 线程函数 def fun1(flag:str, x:int)->None: for i in range(x): print(flag + ":" + str(i)) time.sleep(1) if __name__ == "__main__": # 打印5次 th1 = threading.Thread(target=fun1, args=("th1",5,)) # 打印10次 th2 = threading.Thread(target=fun1, args=("th2",10,)) # 线程守护 th1.daemon = True th2.daemon = True # 开启线程 th1.start() th2.start() # 等待线程结束 th1.join() th2.join() ``` ## 本周任务 ### python 根据多线程编程方法优化上节课的服务器,要求: - 能够同时对至少5个客户端提供服务 - 提供两种服务: - 根据客户端的消息动态切换配置文件 - 向客户端不断发送消息一定`json`格式的消息 ### C# 实现两个客户端: - 请求上述**第一种**服务,在进行工序工步切换时要求客户端切换配置文件 - 请求上述**第二种**服务,不断获取服务端的消息并显示(Log或用UI显示均可)