目录
1、前言
先讲一下我做这个项目的想法吧,这是我一年前自己从零开发的项目,整个项目是我和朋友两个人做的,我主要做的是嵌入式、下位机的一些东西,包括机器人的结构设计、光源布置、底层硬件选型、嵌入式的一些工作。整个系统的上位机全部是由我朋友写的,上位机主要是用python写的,主要是用opencv进行识别,其中也用到了一些仿射变换算法等。但是最终由于个人以及赛区原因,很遗憾最终没有进入国赛。为了弥补之前的遗憾,也为了恶补一下软件方面知识,刚好遇到了地瓜机器人的项目,所以我把整个项目重启了。
2、项目背景
魔方,作为一种广受欢迎的智力玩具,自1974年由匈牙利建筑师厄尔诺·鲁比克发明以来,已经成为全球数以百万计人们挑战智力和手速的对象。它不仅是一种娱乐工具,更是一种训练空间思维、逻辑思维和问题解决能力的有效手段。随着科技的发展,自动化和机器人技术的进步为魔方的自动化还原提供了可能,魔方还原机器人因此应运而生。在自动化领域,机器人技术已经取得了显著的进步,从工业生产线上的自动化机械臂到家庭中的清洁机器人,机器人的应用范围日益广泛。然而,将这些技术应用于解决如魔方这样的复杂问题,需要机器人具备高度的感知、决策和执行能力。魔方还原机器人的开发,不仅是对现有机器人技术的挑战,也是对机器人智能水平的一种测试。目前魔方机器人的主流还原算法就是kociemba算法,也叫二阶段算法,这个相对于其他的还原算法有更为明显的优势。
3、项目历程
3.1 技术难点
很多开发者的深度学习项目都是在开发机上运行,本项目最大的难点就在于部署在RDK x5,最主要的其实就是模型转换。一般开发者都是用pytorch训练的pt模型,而这种魔模型不能直接部署到板端。需要先将pt模型转换成onnx模型,再用地平线算法工具链将onnx转换为bin文件。这是整个项目最大的难点所在,最后就是在板端的部署和测试了。在部署过程中会发现很多问题。
3.2完整项目部署流程
3.2.1 模型训练
本项目是基于yolov8进行开发,在模型训练中最主要就是要找到大数据集,并且需要不同场景、光源情况下的图片,以提高模型准确率。通过kaggle datasets这个网站找到数据集,但是也只能找到很有限的图片,完全无法进行模型训练。所以需要对数据集进行增强。
在kaggle datasets上找到一些图片后,用LabelImg软件进行标注。
在进行标注完成后,就要解决数据量不够的问题了,常用的数据集增强方法就是平移、旋转、随机裁剪、噪声扰动、对比度变化、缩放、尺度变换等。这里我将我的数据增强代码展示出来。
import imgaug.augmenters as iaa
import cv2
import os
from torch.utils.data import Dataset, DataLoader
import torch
# 定义图像增强操作
seq = iaa.Sequential([
iaa.Crop(percent=(0, 0.1)), # 随机裁剪图像
iaa.Fliplr(0.5), # 50%几率进行水平翻转
iaa.Flipud(0.2), # 20%几率进行垂直翻转
iaa.GaussianBlur(sigma=(0, 3.0)), # 高斯模糊
iaa.Affine(rotate=(-30, 30)), # 随机旋转图像
iaa.Multiply((0.8, 1.2)), # 改变亮度
iaa.ContrastNormalization((0.8, 1.2)), # 改变对比度
])
# 自定义数据集
class CustomDataset(Dataset):
def __init__(self, image_folder, label_folder, augmenter=None):
self.image_folder = image_folder
self.label_folder = label_folder
self.augmenter = augmenter
self.image_paths = self._get_image_paths(image_folder) # 获取所有图像路径
self.labels = self._get_labels(label_folder) # 获取所有标签路径
def _get_image_paths(self, folder):
"""获取文件夹中的所有图像文件路径"""
image_paths = []
for filename in os.listdir(folder):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')): # 支持常见图像格式
image_paths.append(os.path.join(folder, filename))
return image_paths
def _get_labels(self, folder):
"""根据图像文件名获取对应的标签"""
labels = []
for filename in os.listdir(folder):
if filename.lower().endswith('.txt'): # 假设标签文件为txt格式
label_path = os.path.join(folder, filename)
with open(label_path, 'r') as f:
label = int(f.read().strip()) # 读取标签
labels.append(label)
return labels
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
# 读取图像并转换为RGB
image = cv2.imread(self.image_paths[idx])
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 获取对应标签
label = self.labels[idx]
# 如果指定了数据增强操作,应用它
if self.augmenter:
image = self.augmenter(image=image) # 增强图像
# 转换为Tensor类型(如果需要)
image = torch.tensor(image.transpose(2, 0, 1)) # 转换为[C, H, W]格式
return image, label
# 示例数据
image_folder = "path/to/dataset_folder/images" # 图像所在文件夹
label_folder = "path/to/dataset_folder/labels" # 标签所在文件夹
# 创建数据集实例
dataset = CustomDataset(image_folder, label_folder, augmenter=seq)
# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
# 测试数据加载器
for images, labels in dataloader:
print(images.shape) # 输出Tensor的形状
break
数据增强后就可以进行模型训练了,训练完成后会得到一个pt文件,也就pytorch模型。
3.2.2模型转换
训练出来的pt模型只能在电脑上跑,不能直接部署在RDK X5上,所以要进行模型转换,也是对我来说整个项目最为棘手的点。
由于在模型转换时对于o