一、分析CV识别任务
- 任务分析
自己研究生期间做过的大多是无监督任务,监督任务做的很少。比如,之前用过yolov5做过滑动验证码的识别,给滑动验证码的缺口打标签是项耗时费力的工作。本次任务相同,是给非机动车、机动车打标签。
frame_id:不同帧
event_id:一帧里面出现的不同车辆id
bbox:车辆位置 - 模型输入输出猜测
1)如果识别车辆很容易,那么输入原始音频x,标出每帧的位置作为输出,记为y。放进Model训练即可,表示为:y=model(x)
2)那如果要对识别的内容进行分类,怎么办?
输出相应标签内容,即event_id。
二、预处理分析
-
读取视频
cap = cv2.VideoCapture(video_path) # 获取cap对象
while True:
# 读取下一帧
ret, frame = cap.read() # frame(高,寛,通道数)
if not ret:
break
break
cap.get(cv2.CAP_PROP_FRAME_COUNT) # 获取视频帧总数 -
框图表示
值得注意的是,由于是矩形,所以只需要两点就可以确定一个框图。bbox = [746, 494, 988, 786]
pt1 = (bbox[0], bbox[1]) # 左上角
pt2 = (bbox[2], bbox[3]) #右下角color = (0, 255, 0) # 蓝、绿、红
thickness = 2 # 线条粗细cv2.rectangle(frame, pt1, pt2, color, thickness) # 框图
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 将BGR转换为RGB
plt.imshow(frame)
三、训练处理
-
模型数据
前面提到,输入原始视频,输出检测框图。那么怎么让模型去学习呢?这里已经给了打标签的每一帧数据,所以只需要获取每一帧音频帧,让其和标签对应起来即可。剩下的交给模型处理。所以最后得到的数据形式应该是图片+txt(标签) 。
Tips:这里要注意的是,保持代码的鲁棒性,限制要加上。下面是示例:for anno_path, video_path in zip(train_annos[-3:], train_videos[-3:]):
print(video_path)
anno_df = pd.read_json(anno_path)
cap = cv2.VideoCapture(video_path)
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
breakimg_height, img_width = frame.shape[:2] frame_anno = anno_df[anno_df['frame_id'] == frame_idx] cv2.imwrite('./yolo-dataset/val/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.jpg', frame) if len(frame_anno) != 0: with open('./yolo-dataset/val/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.txt', 'w') as up: for category, bbox in zip(frame_anno['category'].values, frame_anno['bbox'].values): category_idx = category_labels.index(category) x_min, y_min, x_max, y_max = bbox x_center = (x_min + x_max) / 2 / img_width y_center = (y_min + y_max) / 2 / img_height width = (x_max - x_min) / img_width height = (y_max - y_min) / img_height up.write(f'{category_idx} {x_center} {y_center} {width} {height}\n') frame_idx += 1
-
模型训练
复杂的数据处理完成,便是训练。【个人觉得,深度学习难的是针对问题如何设计模型架构,像数据处理、调参、训练这种,靠的是经验积累。当然,好的Coding确实能提高效率】model = YOLO("yolov8n.pt")
results = model.train(data="yolo-dataset/yolo.yaml", epochs=2, imgsz=1080, batch=16) -
模型测试
针对给出的数据集进行测试,规范一下输出的格式,将检测结果保存。from ultralytics import YOLO
model = YOLO("runs/detect/train/weights/best.pt")
import globfor path in glob.glob('测试集/*.mp4'):
submit_json = []
results = model(path, conf=0.05, imgsz=1080, verbose=False)
for idx, result in enumerate(results):
boxes = result.boxes # Boxes object for bounding box outputs
masks = result.masks # Masks object for segmentation masks outputs
keypoints = result.keypoints # Keypoints object for pose outputs
probs = result.probs # Probs object for classification outputs
obb = result.obb # Oriented boxes object for OBB outputsif len(boxes.cls) == 0: continue xywh = boxes.xyxy.data.cpu().numpy().round() cls = boxes.cls.data.cpu().numpy().round() conf = boxes.conf.data.cpu().numpy() for i, (ci, xy, confi) in enumerate(zip(cls, xywh, conf)): submit_json.append( { 'frame_id': idx, 'event_id': i+1, 'category': category_labels[int(ci)], 'bbox': list([int(x) for x in xy]), "confidence": float(confi) } ) with open('./result/' + path.split('/')[-1][:-4] + '.json', 'w', encoding='utf-8') as up: json.dump(submit_json, up, indent=4, ensure_ascii=False)
四、Linux命令
-
unar命令
之前一直用unzip,第一次接触到unar。相比于unzip,unar 是一个更现代的解压缩工具,它不仅支持 .zip 格式,还能够处理 .rar、.7z 等多种压缩格式。unar 的一个显著特点是能够自动识别和处理文件编码问题,减少解压时出现的乱码情况。 -
处理Json操作
- 加载Json:json.load(open(...)),这个load必须加载的是文件对象,所以用open。[Tips:不要加载路径]
- 可视化Json:pd.read_json(),返回的是DataFrame对象。
-
创建文件夹
平时都直接用mkdir,学习到了一种更好的指令。!mkdir -p ~/.config/Ultralytics/ # 创建它以及任何必要的父目录
-p:这个选项告诉 mkdir 命令,如果目录的上级目录不存在,应该一并创建它们。
~ 符号:代表当前用户的主目录 -
压缩
zip -r result.zip result/ # 创建一个名为 result.zip 的压缩文件,其中包含 result/ 目录下的所有内容和子目录。