本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。
在智能交通系统领域,实时检测车辆事故的能力变得越来越重要。该项目利用先进的计算机视觉技术,采用最先进的对象检测模型 YOLOv11 来准确识别和分类车辆事故。主要目标是通过向紧急服务提供及时警报并实现更快的响应时间来提高道路安全。
YoloV11 是 ultralytics 的 Yolo 最新版本,与以前的版本相比,有几个优点和最大的功能,有关更多信息,请查看官方 ultralytics yoloV11 文章
https://docs.ultralytics.com/models/yolo11/?source=post_page-----a793d51cc4ba--------------------------------
本文项目涉及几个步骤,这是一个简单的原型级项目,步骤是
1. 数据准备 :数据选择和预处理
2. 模型训练 :使用 Yolov11 使用自定义数据训练模型
3. 模型评估 :在看不见的数据上评估模型的性能
4. 模型推理 :使用实际模型的 onnx 版本对看不见的数据进行推理
数据准备
数据准备和预处理是计算机视觉模型开发的关键步骤。这些步骤可确保模型能够有效地学习并很好地泛化到新数据。以下是它们重要性的关键原因:
1. 数据质量改进
2. 减少过拟合
3. 正确的标签处理
在对象检测或分割等任务中,确保标签(边界框、掩码或关键点)与预处理后的图像匹配对于准确训练至关重要。未对齐的标签会显著降低模型性能。
改进的性能指标
正确预处理的数据会在准确性、精度和召回率方面获得更好的性能。准备充分的数据使模型能够专注于有意义的特征并改进其预测。
总之,数据准备和预处理通过提高数据质量、降低计算复杂性、防止过度拟合和增强模型泛化,直接影响计算机视觉模型的成功。
在这个项目中,我从两个不同的来源获取了数据集
找到我带的 GITHUB 的源代码和数据集
https://github.com/varunpn7405/Vehicle_Accident_detection
数据预处理
作为第一步,我们需要 删除空注释和相应的帧 ,我在整个模型开发过程中提供帮助
- 避免误导模型:对象检测模型经过训练,可以预测图像中对象的存在和位置。如果包含没有注释的图像(即没有任何标记对象的图像),则模型可能会错误地了解到许多图像不包含对象,从而降低其有效检测对象的能力。
- 提高训练效率:在没有注释的图像上进行训练会浪费计算资源,因为模型在处理图像时没有学习任何关于对象位置的有用信息。删除这些图像有助于将训练重点放在相关的信息数据上。
- 减少偏差:包含大量空白图像可能会使模型偏向于预测图像通常不包含对象,从而导致更高的假阴性率(即无法检测到存在的对象)。
- 防止过度拟合:对过多的空图像进行训练可能会导致模型对预测未来图像的“无对象”过于自信,这可能会损害其对存在对象的真实场景的泛化。
- 确保正确的损失计算:目标检测模型通常使用依赖于目标存在的损失(如分类和定位损失)。空图像可能会影响这些损失的计算方式,尤其是当模型期望每个图像至少有一个对象时,这可能会导致训练期间的不稳定。
import os, shutil
# Function to check if a file is empty
def is_empty_file(file_path):
return os.path.exists(file_path) and os.stat(file_path).st_size == 0
image_extensions = ['.jpg', '.jpeg', '.png']
path = os.getcwd()
inputPar = os.path.join(path, r'dataset')
outputPar = os.path.join(path, r'filtered')
if not os.path.exists(outputPar):
os.makedirs(outputPar)
folders = os.listdir(inputPar)
for folder in folders:
if folder in ["test", "train", "valid"]:
inputChild = os.path.join(inputPar, folder, "labels")
outputChild1 = os.path.join(outputPar, folder, "labels")
if not os.path.exists(outputChild1):
os.makedirs(outputChild1)
outputChild2 = os.path.join(outputPar, folder, "images")
if not os.path.exists(outputChild2):
os.makedirs(outputChild2)
files = os.listdir(inputChild)
for file in files:
annotation_path = os.path.join(inputChild, file)
# Check if the annotation file is empty
if not is_empty_file(annotation_path):
shutil.copy(annotation_path, os.path.join(outputChild1, file))
# Try to find and remove the corresponding image file
image_name = os.path.splitext(file)[0]
for ext in image_extensions:
image_path = os.path.join(inputPar, folder, "images", image_name + ext)
if os.path.exists(image_path):
shutil.copy(image_path, os.path.join(outputChild2, image_name + ext))
然后下一个任务是我们的第二个数据集有 3 个类 Accident 、Car 和 Fire,我们只需要 Accident 实例,因此删除 Car 和 Fire 的注释,并删除图像和注释 yolo 文件(如果它仅包含属于 Car 和 Fire 的注释),则删除该文件。
import os, shutil
image_extensions = ['.jpg', '.jpeg', '.png']
path = os.getcwd()
inputPar = os.path.join(path, r'accident detection.v10i.yolov11')
outputPar = os.path.join(path, r'accident detection.v10i.yolov11(Filtered)')
if not os.path.exists(outputPar):
os.makedirs(outputPar)
folders = os.listdir(inputPar)
clsfile = os.path.join(path, 'classes.txt')
with open(clsfile) as tf:
clsnames = [cl.strip() for cl in tf.readlines()]
for folder in folders:
if folder in ["test", "train", "valid"]:
inputChild = os.path.join(inputPar, folder, "labels")
outputChild1 = os.path.join(outputPar, folder, "labels")
if not os.path.exists(outputChild1):
os.makedirs(outputChild1)
outputChild2 = os.path.join(outputPar, folder, "images")
if not os.path.exists(outputChild2):
os.makedirs(outputChild2)
files = os.listdir(inputChild)
for file in files:
fileName, ext = os.path.splitext(file)
finput = os.path.join(inputChild, file)
with open(finput) as tf: