本发明公开了一种针对视频目标检测的在线学习方法,属于机器视觉领域。包括模型预训练、目标检测、跟踪修正、标注修正、关键帧提取和模型迭代更新。先利用开源或自标注数据集训练一个基础版本的当前模型;利用当前模型对视频序列进行预检测;利用改进的KCF跟踪算法和基于特征空间的k近邻算法对预检测结果分别进行方框修正和标注修正;利用基于特征空间相似度度量的关键帧提取方法,提取视频关键帧,去除重复图像;利用关键帧数据和修正检测结果对模型进行训练,实现模型的迭代更新。本发明该方法通过跟踪算法和聚类分析对检测和标注结果进行修正,利用修正后的结果重新训练目标检测模型,实现模型性能的不断改进,实现应用场
景的自适应。

1 .一种针对视频目标检测的在线学习方法,其特征在于:该方法包括模型预训练、目标检测、跟踪修正、标注修正、关键帧提取和模型迭代更新,该方法具体包括如下步骤:
步骤1:利用开源或自标注数据集训练一个基础版本的改进YOLOv3目标检测模型,作为当前模型;
步骤2:利用当前模型对视频序列进行预检测,获取初始检测方框和目标类别;
步骤3:利用改进的KCF跟踪算法和基于特征空间的k近邻算法对预检测结果分别进行方框修正和标注修正;
步骤4:利用基于特征空间相似度度量的关键帧提取方法,提取视频关键帧,以压缩数据集大小,去除重复图像;
步骤5:利用关键帧数据和修正检测结果对模型进行训练,实现模型的迭代更新;
步骤6:回到步骤2,重复以上步骤2-步骤5操作;
步骤3所述方框修正的步骤包括:
步骤3 .1:对于第n帧图像的所有预检测目标都初始化一个KCF跟踪器,分别进行正向和负向跟踪,得到邻近图像帧中的跟踪目标;
步骤3 .2:对于临近帧k,计算其与前一帧的帧间差分图像,获取运动目标概率图;
步骤3 .3:对于k帧中的每个跟踪目标,判断其是否静止,如果该目标处于运动状态,则根据运动目标概率图计算该目标的运动目标概率,如果运动目标概率值小于给定阈值,则认为该目标跟踪失败,停止跟踪;
步骤3 .4:对每一帧都进行上述步骤3 .1-步骤3 .3处理,则可以得到所有图像中由跟踪器捕捉到的目标方框;
步骤3 .5:将检测模型得到的目标方框与跟踪器捕捉到的目标方框进行融合,同时进行极大抑制算法NMS得到修正后的目标方框;
所述标注修正的步骤包括:
步骤3 .6:获取ImageNet预训练VGG16网络模型;
步骤3 .7:将检测得到的每个目标方框缩放到统一尺寸,然后传入VGG16网络,得到1000维的特征向量;
步骤3 .8:计算不同目标特征之间的欧式距离作为目标相似度度量方式;
步骤3 .9:对于每个检测目标,通过k近邻算法找出与其最近的k个目标,然后采用投票机制决定该检测目标的目标类别。
2 .根据权利要求1所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤1所述的改进的YOLOv3模型采用全尺度网络OSNet作为特征提取网络,特征金字塔中的上采样方法采用逆卷积神经网络实现,BBox的回归损失函数用GIOU替代MSE,anchors大小的选择仍采用聚类算法,得到9个聚类中心,形成改进的YOLOv3模型。
3 .根据权利要求1所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤3所述跟踪修正方法是:引入了帧间差分估计运动目标概率,首先利用跟踪算法对检测目标进行跟踪,判断目标是否静止,如果目标运动,则利用帧间差分获取方框目标概率,如果小于给定阈值,则认为跟踪失败,停止跟踪,利用跟踪结果进一步修正检测结果,即将跟踪到而未检测到的目标作为漏检目标添加到检测目标列表中。
4 .根据权利要求1所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤3所述标注修正方法是,利用神经网络获取检测目标的特征,通过k近邻算法对目标标注进行投票更新,修正检测结果标注。
5 .根据权利要求1所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤4所述的关键帧提取方法是:利用目标检测网络特征提取层的输出作为图像特征,计算图像之间的距离来衡量图像的相似度,选取相似度的局部极大值作为视频关键帧。
6 .根据权利要求1-5中任何一项所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤1所述的模型训练的工作步骤包括:
步骤1 .1:收集开源数据集,或采集特定场景下的视频数据,人工标注检测目标位置方框和目标类别,建立数据集;
步骤1 .2:对数据集进行旋转、平移、缩放和镜像变换、添加随机白噪音、亮度、色度和饱和度变化,扩充数据集,同时将数据集随机分为训练集、验证集和测试集,其比例为6:2:2;
步骤1 .3:用生成的扩充数据集,利用随机梯度法训练改进的YOLOv3模型,得到基础目标检测模型作为当前模型。
7 .根据权利要求1-5中任何一项所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤2所述预检测的步骤包括:
步骤2 .1:将视频图像帧一帧一帧地送入当前模型,作为输入,进行前向推理得到模型输出;
步骤2 .2:对模型输出进行解析,提取目标方框和目标标注;
步骤2 .3:对得到的检测目标进行极大抑制算法NMS,剔除重复目标,得到最终检测目标,作为预检测结果。
8 .根据权利要求1-5中任何一项所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤4所述的关键帧提取方法步骤包括:
步骤4 .1:将每帧图像通过目标检测网络的特征提取网络的输出作为图像特征提取出来;
步骤4 .2:利用欧式距离计算图像特征之间的相似度;
步骤4 .3:在时间轴上找出相似度的局部极大值作为视频关键帧提取出来。
9 .根据权利要求1-5中任何一项所述的一种针对视频目标检测的在线学习方法,其特征在于:步骤5所述的模型迭代更新步骤包括:
步骤5 .1:用提取的视频关键帧和其对于的修正后的目标方框和标注重构数据集,同时,对数据集进行旋转、平移、缩放和镜像变换、添加随机白噪音、亮度、色度和饱和度变化,扩充数据集;
步骤5 .2:将新数据集划分为训练集、验证集和测试集,其比例为6:2:2;
步骤5 .3:采用新数据集,利用随机梯度法训练改进的YOLOv3模型,得到改进模型,更新当前模型。

一种针对视频目标检测的在线学习方法.pdf

conda info -e

# conda environments:
#
base                  *  /media/hesy/Elements/miniconda3
python310                /media/hesy/Elements/miniconda3/envs/python310
python38                 /media/hesy/Elements/miniconda3/envs/python38
python39                 /media/hesy/Elements/miniconda3/envs/python39

删除环境

conda remove -n python310 --all

很简单,就是要下载挺久的.

conda create -n yolo11 python=3.11
conda activate yolo11
pip install ultralytics onnx numpy protobuf ncnn

使用示例
https://docs.ultralytics.com/models/yolo11/#usage-examples

# Load a COCO-pretrained YOLO11n model and train it on the COCO8 example dataset for 100 epochs
yolo train model=yolo11n.pt data=coco8.yaml epochs=100 imgsz=640

# Load a COCO-pretrained YOLO11n model and run inference on the 'bus.jpg' image
yolo predict model=yolo11n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/bus.jpg

老版本:

//声明:    
AVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb"); 
//使用
av_bitstream_filter_filter(h264bsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
//释放:
av_bitstream_filter_close(h264bsfc);  

新版本:


//声明  
AVBSFContext *bsf_ctx = nullptr;
const AVBitStreamFilter *pfilter = av_bsf_get_by_name("h264_mp4toannexb");
av_bsf_alloc(pfilter, &bsf_ctx);
//使用:
av_bsf_send_packet(bsf_ctx, &packet);
av_bsf_receive_packet(bsf_ctx, &packet);
//释放:
av_bsf_free(&bsf_ctx);

h264有两种封装,一种是annexb模式,传统模式,有startcode(0x000001或0x0000001)分割NALU,在mpegts流媒体中使用,vlc里打开编码器信息中显示h264;

一种是AVCC模式,一般用mp4、mkv、flv容器封装,以长度信息分割NALU, vlc里打开编码器信息中显示avc1。

很多场景需要进行这两种格式之间的转换,FFmpeg提供了名称为h264_mp4toannexb的Bitstream Filter(bsf)来实现这个功能。

例如将mp4转换成h264可使用如下指令:

mp4->h264:sudo ffmpeg -i test.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 test.h264

bsf的使用方法:

(1)使用查询函数av_bsf_get_by_name 根据名称查找对应的AVBitstreamFilter。

(2)使用av_bsf_alloc为AVBSFContext和他的一些内部变量分配内存。

(3)设置AVBSFContext可能需要使用一些变解码参数和time_base[2].

(4)在设置好参数之后使用av_bsf_init来初始化bsf.

(5)使用av_bsf_send_packet函数输入数据,并使用av_bsf_receive_packet获得处理后的输出数据。

(6)处理结束后,av_bsf_free清理用于上下文和内部缓冲区的内存。

在 Keith Jack’s 的书 “Video Demystified” (ISBN 1-878707-09-4) 给出的公式是这样的。

RGB to YUV

𝑌=0.257𝑅+0.504𝐺+0.098𝐵+16
𝐶𝑟=𝑉=0.439𝑅−0.368𝐺−0.071𝐵+128
𝐶𝑏=𝑈=−0.148𝑅−0.291𝐺+0.439𝐵+128

YUV to RGB

𝐵=1.164(𝑌−16)+2.018(𝑈−128)
𝐺=1.164(𝑌−16)−0.813(𝑉−128)−0.391(𝑈−128)
𝑅=1.164(𝑌−16)+1.596(𝑉−128)

注意在上面的式子中,RGB 的范围是 [0,255],Y 的范围是 [16,235] ,UV 的范围是 [16,239]。 如果计算结果超出这个范围就截断处理。

CCIR 601 定义的转换公式是:

𝑌=0.299𝑅+0.587𝐺+0.114𝐵
𝐶𝑟=𝑉=0.713(𝑅−𝑌)=0.500𝑅−0.419𝐺−0.081𝐵
𝐶𝑏=𝑈=0.564(𝐵−𝑌)=−0.169𝑅−0.331𝐺+0.500𝐵

RGB===Y+1.403VY−0.344U−0.714VY+1.770U
𝑅=𝑌+1.403𝑉
𝐺=𝑌−0.344𝑈−0.714𝑉
𝐵=𝑌+1.770𝑈

这里 RGB 的取值范围是 [0,1]。 Y 的范围是 [0,1], Cr 和 Cb 的范围是 [−0.5,0.5]。

大家仔细看,这两个来源给出的公式系数有些细微的差别,如果将公式中的 YUV 和 RGB 的取值范围统一成相同的,计算出的结果也略有不同,但是差异很小,基本上眼睛看不出区别来。所以大家不用计较这两个公式的区别。

如果把 RGB 和YUV 的范围都放缩到 0,255,那么常用的转换公式是这样的。所以我们可以直接使用下面的公式来转换.

𝑅=𝑌+1.403×(𝑉−128)
𝐺=𝑌–0.343×(𝑈–128)–0.714×(𝑉–128)
𝐵=𝑌+1.770×(𝑈–128)

𝑌=0.299𝑅+0.587𝐺+0.114𝐵
𝐶𝑟=𝑉=0.500𝑅−0.419𝐺−0.081𝐵+128
𝐶𝑏=𝑈=−0.169𝑅−0.331𝐺+0.500𝐵+128

C++转换代码如下:

class RGB
{
public:
    uint8_t R, G, B;
};
class YUV
{
public:
    uint8_t Y, U, V;
};

RGB yuv2rgb(YUV yuv)
{
    int R = round(yuv.Y + 1.403 * (yuv.V - 128));
    int G = round(yuv.Y - 0.343 * (yuv.U - 128) - 0.714 * (yuv.V - 128));
    int B = round(yuv.Y + 1.770 * (yuv.U - 128));

    RGB rgb;
    rgb.R = max(0, min(R, 255));
    rgb.G = max(0, min(G, 255));
    rgb.B = max(0, min(B, 255));
    return rgb;
}

YUV rgb2yuv(RGB rgb)
{
    int Y = round(0.299 * rgb.R + 0.587 * rgb.G + 0.114 * rgb.B);
    int V = round(0.500 * rgb.R - 0.419 * rgb.G - 0.081 * rgb.B + 128);
    int U = round(-0.169 * rgb.R - 0.331 * rgb.G + 0.500 * rgb.B + 128);

    YUV yuv;
    yuv.Y = max(0, min(Y, 255));
    yuv.U = max(0, min(U, 255));
    yuv.V = max(0, min(V, 255));
    return yuv;
}

常见颜色RGB与YUV对应值:

黑色 rgb=[00,00,00],yuv=[00,80,80]
白色 rgb=[ff,ff,ff],yuv=[ff,80,80]
红色 rgb=[ff,00,00],yuv=[4c,55,ff]
青色 rgb=[00,ff,ff],yuv=[b3,ab,01]
蓝色 rgb=[00,00,ff],yuv=[1d,ff,6b]
黄色 rgb=[ff,ff,00],yuv=[e2,01,95]