【Datawhale AI 夏令营2024--CV】Task1_baseline解读和尝试

一、赛题任务

        根据给定的视频监控数据集,进行城市违规行为的检测。违规行为主要包括垃圾桶满溢机动车违停非机动车违停等。选手需要能够从视频中分析并标记出违规行为提供违规行为发生的时间位置信息。

二、数据集

1、观察数据集

数据集分为三类:测试集,训练集(无标注),训练集(有标注第一批)。

测试集和训练集都为MP4格式,标注为json格式

json文件是视频每一帧检测到的违法行为:

  • frame_id:违规行为出现的帧编号
  • event_id:违规行为ID
  • category:违规行为类别
  • bbox:检测到的违规行为矩形框的坐标,[xmin,ymin,xmax,ymax]形式
    [
    
        {
    
          "frame_id": 20,
    
          "event_id": 1,
    
          "category": "机动车违停",
    
          "bbox": [200, 300, 280, 400]
    
        },
    
        {
    
          "frame_id": 20,
    
          "event_id": 2,
    
          "category": "机动车违停",
    
          "bbox": [600, 500, 720, 560]
    
        },
    
        {
    
          "frame_id": 30,
    
          "event_id": 3,
    
          "category": "垃圾桶满溢",
    
          "bbox": [400, 500, 600, 660]
    
        }
    
      ]

2、分析数据集

video_path = '训练集(有标注第一批)/视频/45.mp4'
cap = cv2.VideoCapture(video_path) # 读取视频
while True:
    ret, frame = cap.read()  # 返回的是是否读取成功 以及当前帧
    if not ret:
        break
    break  # 读取当前帧返回
frame.shape #查看当前帧的大小

frame.shape == (1080, 1920, 3) -->hwc

train_anno = json.load(open('训练集(有标注第一批)/标注/45.json', encoding='utf-8'))
train_anno[0], len(train_anno)

({'frame_id': 0,
  'event_id': 1,
  'category': '机动车违停',
  'bbox': [680, 797, 1448, 1078]},
 9000)   # 找到bbox方便下面提取特征

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)
plt.imshow(frame)
#释放内存
cv2.destroyAllWindows()

# 释放摄像头
cap.release()

利用opecv以及matplotlib来进行图片特征提取的展示

 3、数据集转换

for anno_path, video_path in zip(train_annos[:5], train_videos[:5]):
    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:
            break

        img_height, img_width = frame.shape[:2]
        
        frame_anno = anno_df[anno_df['frame_id'] == frame_idx]
        cv2.imwrite('./yolo-dataset/train/' + anno_path.split('\\')[-1][:-5] + '_' + str(frame_idx) + '.jpg', frame)

        if len(frame_anno) != 0:
            with open('./yolo-dataset/train/' + 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

                    if x_center > 1:
                        print(bbox)
                    up.write(f'{category_idx} {x_center} {y_center} {width} {height}\n')

        frame_idx += 1

将提取标注的数据集内容写入./yolo-dataset/train/'文件夹下

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:
            break

        img_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

和上个代码一样将提取标注的数据集内容写入./yolo-dataset/val/'文件夹下

俩个数据集是提供给yolo模型进行训练

三、模型

import os

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

import warnings

warnings.filterwarnings('ignore')

from ultralytics import YOLO

model = YOLO("yolov8n.pt")
results = model.train(data="yolo-dataset/yolo.yaml", epochs=2, imgsz=1080, batch=16)

baseline用的是yolov8的模型,从"yolo-dataset/yolo.yaml"中读取路径从而读取数据就是上面的俩个数据集,epoch是迭代次数,imgsz是将图片设置为1080的大小,从上文可知改监控每一帧大小为1080,batch是每一个的样本数。该段代码就是利用已经知道的数据集进行训练,得到权重

from ultralytics import YOLO

model = YOLO("runs/detect/train/weights/best.pt")
import glob

for 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 outputs

        if 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)

上面代码就是读取之前训练的权重,进行预测,然后将得到的数据写入json文件中

下面的代码其实我现在也不知道有什么用

        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 outputs

 四、尝试

1、尝试一

在解读这篇代码的时候,发现他只训练的二次,于是我就将他改成30次迭代即:

results = model.train(data="yolo-dataset/yolo.yaml", epochs=2, imgsz=1080, batch=16)-->epochs=2

 效果比较好

2、尝试二

之后我就在想能不能在加大一点,但是效果不尽人意:应该是过拟合了

3、尝试三

之后发现好像是数据集用的太少了,然后我将数据集全部使用但是直接卡死了,用30个数据集也不行,之后我用了14个视频,然后将迭代次数也是调为30,分数还是理想的。

五、下一步

        因为我是个小白,找不到一些更适合的模型,所以我应该还是会在数据集上做工作,先彼此将数据集给转换,然后再将未标注的数据集给标注,在进行训练尝试。之后再看task2,与task3给的提示来尝试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值