精华内容
下载资源
问答
  • Pytorch目标检测实现

    千次阅读 2021-12-02 20:48:44
    torchvision库中已存在目标检测的相应模型,只需要调用相应的函数即可。 1. 单文件: ## 导入相关模块 import numpy as np import torchvision import torch import torchvision.transforms as transforms from PIL ...

    torchvision库中已存在目标检测的相应模型,只需要调用相应的函数即可。

    1. 单文件:

    ## 导入相关模块
    import numpy as np
    import torchvision
    import torch
    import torchvision.transforms as transforms
    from PIL import Image, ImageDraw, ImageFont
    import matplotlib.pyplot as plt
    
    model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
    model.eval()
    
    
    ## 准备需要检测的图像
    image = Image.open("/mnt/COCO2017/val2017/000000000285.jpg")
    transform_d = transforms.Compose([transforms.ToTensor()])
    image_t = transform_d(image)    ## 对图像进行变换
    pred = model([image_t])         ## 将模型作用到图像上
    print(pred)
    
    ## 定义使用COCO数据集对应的每类的名称
    """
        fire hydrant 消防栓,stop sign 停车标志, parking meter 停车收费器, bench 长椅。
        zebra 斑马, giraffe 长颈鹿, handbag 手提包, suitcase 手提箱, frisbee (游戏用)飞盘(flying disc)。
        skis 滑雪板(ski的复数),snowboard 滑雪板(ski是单板滑雪,snowboarding 是双板滑雪。)
        kite 风筝, baseball bat 棒球棍, baseball glove 棒球手套, skateboard 滑板, surfboard 冲浪板, tennis racket 网球拍。
        broccoli 西蓝花,donut甜甜圈,炸面圈(doughnut,空心的油炸面包), cake 蛋糕、饼, couch 长沙发(靠chi)。
        potted plant 盆栽植物。 dining table 餐桌。 laptop 笔记本电脑,remote 遥控器(=remote control), 
        cell phone 移动电话(=mobile phone)(cellular 细胞的、蜂窝状的), oven 烤炉、烤箱。 toaster 烤面包器(toast 烤面包片)
        sink 洗碗池, refrigerator 冰箱。(=fridge), scissor剪刀(see, zer), teddy bear 泰迪熊。 hair drier 吹风机。 
        toothbrush 牙刷。
    """
    COCO_INSTANCE_CATEGORY_NAMES = [
        '__BACKGROUND__', 'person', 'bicycle', 'car', 'motorcycle',
        'airplane', 'bus', 'train', 'trunk', 'boat', 'traffic light',
        'fire hydrant', 'N/A', 'stop sign', 'parking meter', 'bench',
        'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant',
        'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A',
        'N/A', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard',
        'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard',
        'surfboard', 'tennis racket', 'bottle', 'N/A', 'wine glass',
        'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
        'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A',
        'dining table', 'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop',
        'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven',
        'toaster', 'toaster', 'sink', 'refrigerator', 'N/A', 'book', 'clock',
        'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
    ]
    
    ## 检测出目标的类别和得分
    pred_class = [COCO_INSTANCE_CATEGORY_NAMES[ii] for ii in list(pred[0]['labels'].numpy())]
    pred_score = list(pred[0]['scores'].detach().numpy())
    
    ## 检测出目标的边界框
    pred_boxes = [[ii[0], ii[1], ii[2], ii[3]] for ii in list(pred[0]['boxes'].detach().numpy())]
    
    ## 只保留识别的概率大约 0.5 的结果。
    pred_index = [pred_score.index(x) for x in pred_score if x > 0.5]
    
    ## 设置图像显示的字体
    fontsize = np.int16(image.size[1] / 20)
    font1 = ImageFont.truetype("/usr/share/fonts/gnu-free/FreeMono.ttf", fontsize)
    
    ## 可视化对象
    draw = ImageDraw.Draw(image)
    for index in pred_index:
        box = pred_boxes[index]
        draw.rectangle(box, outline="blue")
        texts = pred_class[index]+":"+str(np.round(pred_score[index], 2))
        draw.text((box[0], box[1]), texts, fill="blue", font=font1)
    
    ## 显示图像
    plt.imshow(image)
    plt.show()
    

    2. 对该文件夹下随机10个文件进行目标检测。

    """
        对给定文件夹下随机数量的文件进行目标检测。
    """
    import numpy as np
    import torchvision
    import torch
    import torchvision.transforms as transforms
    from PIL import Image, ImageDraw, ImageFont
    import matplotlib.pyplot as plt
    import os
    
    # 定义使用COCO数据集对应的每类的名称
    """
        fire hydrant 消防栓,stop sign 停车标志, parking meter 停车收费器, bench 长椅。
        zebra 斑马, giraffe 长颈鹿, handbag 手提包, suitcase 手提箱, frisbee (游戏用)飞盘(flying disc)。
        skis 滑雪板(ski的复数),snowboard 滑雪板(ski是单板滑雪,snowboarding 是双板滑雪。)
        kite 风筝, baseball bat 棒球棍, baseball glove 棒球手套, skateboard 滑板, surfboard 冲浪板, tennis racket 网球拍。
        broccoli 西蓝花,donut甜甜圈,炸面圈(doughnut,空心的油炸面包), cake 蛋糕、饼, couch 长沙发(靠chi)。
        potted plant 盆栽植物。 dining table 餐桌。 laptop 笔记本电脑,remote 遥控器(=remote control), 
        cell phone 移动电话(=mobile phone)(cellular 细胞的、蜂窝状的), oven 烤炉、烤箱。 toaster 烤面包器(toast 烤面包片)
        sink 洗碗池, refrigerator 冰箱。(=fridge), scissor剪刀(see, zer), teddy bear 泰迪熊。 hair drier 吹风机。 
        toothbrush 牙刷。
    """
    COCO_INSTANCE_CATEGORY_NAMES = [
        '__BACKGROUND__', 'person', 'bicycle', 'car', 'motorcycle',
        'airplane', 'bus', 'train', 'trunk', 'boat', 'traffic light',
        'fire hydrant', 'N/A', 'stop sign', 'parking meter', 'bench',
        'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant',
        'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A',
        'N/A', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard',
        'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard',
        'surfboard', 'tennis racket', 'bottle', 'N/A', 'wine glass',
        'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
        'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A',
        'dining table', 'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop',
        'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven',
        'toaster', 'toaster', 'sink', 'refrigerator', 'N/A', 'book', 'clock',
        'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
    ]
    
    # 加载预训练的模型
    model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
    model.eval()
    
    # 准备需要检测的图像文件夹
    image_folder_path = "/mnt/COCO2017/val2017/"
    number = 10     # 随机选择10张图片可视化。
    transform_d = transforms.Compose([transforms.ToTensor()])
    
    # 随机选择10张图片
    dirs = os.listdir(image_folder_path)
    idx = np.random.randint(0, len(dirs), number)
    
    for i in idx:
        image_path = os.path.join(image_folder_path, dirs[i])
        image = Image.open(image_path)
    
        image_t = transform_d(image)    # 对图像进行变换
        pred = model([image_t])         # 将模型作用到图像上
        print(pred)
    
        # 检测出目标的类别和得分
        pred_class = [COCO_INSTANCE_CATEGORY_NAMES[ii] for ii in list(pred[0]['labels'].numpy())]
        pred_score = list(pred[0]['scores'].detach().numpy())
    
        # 检测出目标的边界框
        pred_boxes = [[ii[0], ii[1], ii[2], ii[3]] for ii in list(pred[0]['boxes'].detach().numpy())]
    
        # 只保留识别的概率大约 0.5 的结果。
        pred_index = [pred_score.index(x) for x in pred_score if x > 0.5]
    
        # 设置图像显示的字体
        fontsize = np.int16(image.size[1] / 20)
        font1 = ImageFont.truetype("/usr/share/fonts/gnu-free/FreeMono.ttf", fontsize)
    
        # 可视化对象
        draw = ImageDraw.Draw(image)
        for index in pred_index:
            box = pred_boxes[index]
            draw.rectangle(box, outline="blue")
            texts = pred_class[index]+":"+str(np.round(pred_score[index], 2))
            draw.text((box[0], box[1]), texts, fill="blue", font=font1)
    
        # 显示图像
        plt.imshow(image)
        plt.show()
    
    

    3. 我们在COCO2017数据集上进行了一些测试,结果如下:

    在这里插入图片描述
    上图识别出了“人”,概率为100%,识别出了“棒球手套”,概率没瞅见哈哈。
    在这里插入图片描述
    上图识别出了“摩托”,概率100%,“长椅”,概率为74%。
    在这里插入图片描述
    这玩意认为有66%的概率存在“马桶”,87%的概率存在“杯子”,这个识别就有点问题啊。
    在这里插入图片描述
    上面识别出了“披萨(pizza)”,“勺子(spoon)”,“叉子(fork)”。
    在这里插入图片描述
    妈耶,我的Trypophobia都出来了。不过其识别出了 bowl,cup,dinning table,person、spoon,可以调优下哈哈。

    下面的图我就不描述了。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    识别出了西蓝花(broccoli),三明治、叉子。
    在这里插入图片描述
    消防栓,fire hydrant

    4. 参考书籍:

    《PyTorch深度学习入门与实践》孙玉林、余本国著。

    展开全文
  • MATLAB实现简单目标跟踪 预处理:中值滤波; 目标检测:二值化 后处理:形态学滤波或者连通性处理 目标跟踪:计算形心 clear all; close all; %预处理-中值滤波 t = imread('1.png');%原始图像 t1 = rgb2gray(t);%...

    MATLAB实现简单目标跟踪

    预处理:中值滤波;
    目标检测:二值化
    后处理:形态学滤波或者连通性处理
    目标跟踪:计算形心

    clear all;
    close all;
    %预处理-中值滤波
    t = imread('1.png');%原始图像
    t1 = rgb2gray(t);%灰度图像
    t2=imnoise(t1,'salt & pepper',0.3);%加入椒盐噪声后
    t3 = medfilt2(t1,[3 3]);%中值滤波图像
    %目标检测-二值化
    a = graythresh(t3);%自动确定二值化阈值
    t4 = im2bw(t3,a);%对图像进行二值化
    %后处理-形态滤波和连通性处理
    % imdilate()膨胀
    SE=[0 1 0
        1 1 1
        0 1 0];
    t5=imdilate(t4,SE);%使用结构元素SE对图像t4进行一次膨胀 
    %imerode()腐蚀
    %strel函数的功能是运用各种形状和大小构造结构元素
    SE1=strel('disk',3);%这里是创建一个半径为3的平坦型圆盘结构元素
    t6=imerode(t4,SE1); 
    % imopen()开运算
    t7=imopen(t4,SE);%直接开运算 
    %imclose()闭运算
    t8=imclose(t4,SE);%直接闭运算
    
    figure('name','目标检测');
    subplot(4,3,1),imshow(t),title('原始图像')
    subplot(4,3,2),imshow(t2),title('加入椒盐噪声后')
    subplot(4,3,3),imshow(t3),title('中值滤波后的图像')
    subplot(4,3,4),imshow(t4),title('二值化后的图像')
    subplot(
    展开全文
  • 在这里我们主要实现了一个多目标跟踪器,管理多个卡尔曼滤波器对象,主要包括以下内容: 初始化:最大检测数,目标未被检测的最大帧数 目标跟踪结果的更新,即跟踪成功失败的目标的更新 初始化 def _...

    在这里我们主要实现了一个多目标跟踪器,管理多个卡尔曼滤波器对象,主要包括以下内容:

    • 初始化:最大检测数,目标未被检测的最大帧数
    • 目标跟踪结果的更新,即跟踪成功和失败的目标的更新

    • 初始化

       def __init__(self, max_age=1, min_hits=3):
              """
              初始化:设置SORT算法的关键参数       
              """
              # 最大检测数:目标未被检测到的帧数,超过之后会被删 
              self.max_age = max_age
              # 目标命中的最小次数,小于该次数不返回
              self.min_hits = min_hits  
              # 卡尔曼跟踪器
              self.trackers = []  
              # 帧计数
              self.frame_count = 0

    1、目标跟踪结果的更新:

    该方法实现了SORT算法,输入是当前帧中所有物体的检测框的集合,包括目标的score,输出是当前帧标的跟踪框集合,包括目标的跟踪的id要求是即使检测框为空,也必须对每一帧调用此方法,返回一个类似的输出数组,最后一列是目标对像的id。需要注意的是,返回的目标对象数量可能与检测框的数量不同.

        def update(self, dets):
            self.frame_count += 1
            # 在当前帧逐个预测轨迹位置,记录状态异常的跟踪器索引
            # 根据当前所有的卡尔曼跟踪器个数(即上一帧中跟踪的目标个数)创建二维数组:行号为卡尔曼滤波器的标识索引,列向量为跟踪框的位置和ID
            trks = np.zeros((len(self.trackers), 5))  # 存储跟踪器的预测
            to_del = []   # 存储要删除的目标框
            ret = []    # 存储要返回的追踪目标框
            # 循环遍历卡尔曼跟踪器列表
            for t, trk in enumerate(trks):
                # 使用卡尔曼跟踪器t产生对应目标的跟踪框
                pos = self.trackers[t].predict()[0]
                # 遍历完成后,trk中存储了上一帧中跟踪的目标的预测跟踪框
                trk[:] = [pos[0], pos[1], pos[2], pos[3], 0]
                # 如果跟踪框中包含空值则将该跟踪框添加到要删除的列表中
                if np.any(np.isnan(pos)):
                    to_del.append(t)
            # numpy.ma.masked_invalid 屏蔽出现无效值的数组(NaN 或 inf)
            # numpy.ma.compress_rows 压缩包含掩码值的2-D 数组的整行,将包含掩码值的整行去除
            # trks中存储了上一帧中跟踪的目标并且在当前帧中的预测跟踪框
            trks = np.ma.compress_rows(np.ma.masked_invalid(trks))
            # 逆向删除异常的跟踪器,防止破坏索引
            for t in reversed(to_del):
                self.trackers.pop(t)
            # 将目标检测框与卡尔曼滤波器预测的跟踪框关联获取跟踪成功的目标,新增的目标,离开画面的目标
            matched, unmatched_dets, unmatched_trks = associate_detections_to_trackers(dets, trks)
    
            # 将跟踪成功的目标框更新到对应的卡尔曼滤波器
            for t, trk in enumerate(self.trackers):
                if t not in unmatched_trks:
                    d = matched[np.where(matched[:, 1] == t)[0], 0]
                    # 使用观测的边界框更新状态向量
                    trk.update(dets[d, :][0])
    
            # 为新增的目标创建新的卡尔曼滤波器对象进行跟踪
            for i in unmatched_dets:
                trk = KalmanBoxTracker(dets[i, :])
                self.trackers.append(trk)
    
            # 自后向前遍历,仅返回在当前帧出现且命中周期大于self.min_hits(除非跟踪刚开始)的跟踪结果;如果未命中时间大于self.max_age则删除跟踪器。
            # hit_streak忽略目标初始的若干帧
            i = len(self.trackers)
            for trk in reversed(self.trackers):
                # 返回当前边界框的估计值
                d = trk.get_state()[0]
                # 跟踪成功目标的box与id放入ret列表中
                if (trk.time_since_update < 1) and (trk.hit_streak >= self.min_hits or self.frame_count <= self.min_hits):
                    ret.append(np.concatenate((d, [trk.id + 1])).reshape(1, -1))  # +1 as MOT benchmark requires positive
                i -= 1
                # 跟踪失败或离开画面的目标从卡尔曼跟踪器中删除
                if trk.time_since_update > self.max_age:
                    self.trackers.pop(i)
            # 返回当前画面中所有目标的box与id,以二维矩阵形式返回
            if len(ret) > 0:
                return np.concatenate(ret)
            return np.empty((0, 5))

    我们将上述两个方法封装在一个类中。


    总结

    了解sort进行多目标跟踪的实现


    功能实现

    # 1.SORT目标跟踪:
    #       1.第一帧刚开始时:对第一帧所有的检测框生成对应的新跟踪框。
    #       2.第二帧开始到以后所有帧:
    #           上一帧成功跟踪并且保留下来的的跟踪框 在当前帧中 进行新一轮的预测新的跟踪框,
    #           并且针对所预测的新跟踪框和当前帧中的检测框进行iou计算和使用匈牙利算法对该两者进行关联匹配,
    #           通过上述操作后成功返回跟踪目标成功的跟踪框(即和当前帧中的目标检测框相匹配的跟踪框),
    #           并且另外发现了新出现目标的检测框、跟踪目标失败的跟踪框(即目标离开了画面/两者匹配度IOU值小于iou阈值),
    #           那么首先使用当前帧中的检测框对“成功关联匹配的跟踪框中的”状态向量进行更新,
    #           然后对新增目标的检测框生成对应新的跟踪框,最后把跟踪目标失败的跟踪框从跟踪器链列表中移除出去。
    # 2.传入的检测框dets:[检测框的左上角的x/y坐标, 检测框的右下角的x/y坐标, 检测框的预测类别的概率值]
    # 3.返回值tracks:
    #   当前帧中跟踪目标成功的跟踪框/预测框的集合,包含目标的跟踪的id(也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个)
    #   第一种返回值方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度, trk.id] ...]
    #   第二种返回值方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, trk.id] ...]
    #   d:[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]
    #   trk.id:卡尔曼滤波器的个数/目标框的个数,也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个。
    #Sort多目标跟踪 管理多个卡尔曼滤波器
    class Sort(object):
        """
            Sort 是一个多目标跟踪器的管理类,管理多个 跟踪器链中的多个 KalmanBoxTracker 卡尔曼滤波对象
            """
        #设置Sort算法的参数
        def __init__(self,max_age = 1,min_hits = 3):
            """
                    初始化:设置SORT算法的关键参数
                    :param max_age: 最大检测数:目标未被检测到的帧数,超过之后会被删除
                    :param min_hits: 目标命中的最小次数,小于该次数update函数不返回该目标的KalmanBoxTracker卡尔曼滤波对象
                    """
            """
                    max_age:跟踪框的最大连续跟丢帧数。如果当前跟踪框连续N帧大于最大连续跟丢帧数的话,则从跟踪器链中删除该卡尔曼滤波对象的预测框(跟踪框)。
                    min_hits:跟踪框连续成功跟踪到目标的最小次数(目标连续命中的最小次数),也即跟踪框至少需要连续min_hits次成功跟踪到目标。
                    trackers:卡尔曼滤波跟踪器链,存储多个 KalmanBoxTracker 卡尔曼滤波对象
                    frame_count:当前视频经过了多少帧的计数
            """
            # 最大检测数:目标未被检测到的帧数,超过之后会被删
            set.max_age = max_age
            # 目标连续命中的最小次数,小于该次数update函数不返回该目标的KalmanBoxTracker卡尔曼滤波对象
            self.min_hits=min_hits
            # 卡尔曼滤波跟踪器链,存储多个 KalmanBoxTracker 卡尔曼滤波对象
            self.trackers = []
            #帧计数
            self.frane_count = 0
    
        """
            update(dets):
                输入dets:
                    当前帧中yolo所检测出的所有目标的检测框的集合,包含每个目标的score
                    以[[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]形式输入的numpy.array
                    x1、y1 代表检测框的左上角坐标;x2、y2代表检测框的右上角坐标;score代表检测框对应预测类别的概率值。
                输出ret:
                    当前帧中跟踪目标成功的跟踪框/预测框的集合,包含目标的跟踪的id(也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个)
                    第一种返回值方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度, trk.id] ...]
                    第二种返回值方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, trk.id] ...]
                    d:[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]
                    trk.id:卡尔曼滤波器的个数/目标框的个数,也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个。
                注意:
                    即使检测框为空,也必须对每一帧调用此方法,返回一个类似的输出数组,最后一列是目标对像的id。
                    返回的目标对象数量可能与检测框的数量不同。
        """
        #更新数值
        def update(self,dets):
            """
                    该方法实现了SORT算法,输入是当前帧中所有物体的检测框的集合,包括目标的score,
                    输出是当前帧目标的跟踪框集合,包括目标的跟踪的id
                    要求是即使检测框为空,也必须对每一帧调用此方法,返回一个类似的输出数组,最后一列是目标对像的id
                    注意:返回的目标对象数量可能与检测框的数量不同
                    :param dets:以[[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...]形式输入的numpy.array
                    :return:
                    """
            """ 每经过一帧,frame_count+=1"""
            self.frane_count +=1
    
            """
                    1.trackers:
                        上一帧中的跟踪器链(列表),保存的是上一帧中成功跟踪目标的跟踪框,也即上一帧中成功跟踪目标的KalmanBoxTracker卡尔曼滤波对象。
    
                    2.trks = np.zeros((len(trackers), 5))
                        上一帧中的跟踪器链(列表)中的所有跟踪框(卡尔曼滤波对象)在当前帧中成功进行predict预测新跟踪框后返回的值。
                        所有新跟踪框的左上角的x坐标和y坐标、右下角的x坐标和y坐标、置信度 的一共5个值。
    
                        1.因为一开始第一帧时,trackers跟踪器链(列表)仍然为空,所以此时的trks初始化如下:
                            np.zeros((0, 5))     
                                输出值:array([], shape=(0, 5), dtype=float64)
                                输出值类型:<class 'numpy.ndarray'>
                        2.np.zeros((len(trackers), 5)) 创建目的:
                            1.用于存储上一帧中的跟踪器链中所有跟踪框(KalmanBoxTracker卡尔曼滤波对象)在当前帧中进行predict预测新跟踪框后返回的值,
                              之所以创建的numpy数组的列数为5,是因为一个跟踪框在当前帧中进行predict预测新跟踪框后返回的值为1行5列的矩阵,
                              返回值分别为新跟踪框的左上角的x坐标和y坐标、右下角的x坐标和y坐标、置信度 的一共5个值。
                            2.如果是在视频的第一帧中,那么因为跟踪器链不存在任何跟踪框(KalmanBoxTracker卡尔曼滤波对象),
                              因此np.zeros((len(trackers), 5))创建的是空列表:array([], shape=(0, 5), dtype=float64)。
                        3.trackers:跟踪器链(列表)
                            1.跟踪器链中存储了上一帧中成功跟踪目标并且在当前帧中的预测框(跟踪框),
                              同时也存储了“为了当前帧中的检测框中的新增目标所创建的”新预测框(新跟踪框),
                              但是同时不存储当前帧中预测跟踪失败的预测框(跟踪框),同时也不存储
                            2.跟踪器链实际就是多个的卡尔曼滤波KalmanBoxTracker自定义类的实例对象组成的列表。
                              每个目标框都有对应的一个卡尔曼滤波器(KalmanBoxTracker实例对象),
                              KalmanBoxTracker类中的实例属性专门负责记录其对应的一个目标框中各种统计参数,
                              并且使用类属性负责记录卡尔曼滤波器的创建个数,增加一个目标框就增加一个卡尔曼滤波器(KalmanBoxTracker实例对象)。
                              把每个卡尔曼滤波器(KalmanBoxTracker实例对象)都存储到跟踪器链(列表)中。
            """
            # 存储跟踪器在当前帧逐个预测轨迹位置,记录状态异常的跟踪器索引
            # 根据当前所有的卡尔曼跟踪器个数(即上一帧中跟踪的目标个数)创建二维数组:行号为卡尔曼滤波器的标识索引,列向量为跟踪框的位置和ID
            trks = np.zeros(len(self.trackers),5)#跟踪器对当前帧的图像预测结果
            """ to_del:存储“跟踪器链中某个要删除的”KalmanBoxTracker卡尔曼滤波对象的索引 """
            to_del = []#存储要删除的目标框
    
            ret = []#返回的跟踪目标
            #遍历卡尔曼滤波器中的跟踪框
            """
                    for t, trk in enumerate(ndarray类型的trks)
                        t:为从0到列表长度-1的索引值
                        trk:ndarray类型的trks中每个(1, 5)形状的一维数组
           """
    
            """ 遍历trks 用于存储上一帧中的跟踪器链中所有跟踪框(KalmanBoxTracker卡尔曼滤波对象)在当前帧中进行predict预测新跟踪框后返回的值 """
            for t,trk in enumerate(trks):
                """ 上一帧中的跟踪器链中所有跟踪框(KalmanBoxTracker卡尔曼滤波对象)在当前帧中进行predict预测新跟踪框 """
                #使用卡尔曼跟踪器t产生对应目标的跟踪框,即对目标进行预测
                pos = self.trackers[t].predict()[0]
                """ 新跟踪框的左上角的x坐标和y坐标、右下角的x坐标和y坐标、置信度 的一共5个值。
                               trk中存储了上一帧中目标的跟踪框在当前帧中新的跟踪框的信息值。
                """
                # 遍历完成后,trk中存储了上一帧中跟踪的目标的预测结果的跟踪框
                trk[:] = [pos[0],pos[1],pos[2],pos[3],0]
                """ 如果预测的新的跟踪框的信息(1行5列一共5个值)中包含空值的话,则将该跟踪框在跟踪器链(列表)中的索引值t放到to_del列表中。
                   使用np.any(np.isnan(pos))即能判断这1行5列一共5个值是否包含空值。
                   后面下一步将会根据to_del列表中保存的跟踪框的索引值到跟踪器链(列表)中将该跟踪框从其中移除出去。
                """
                #若预测结果pos中包含空值,添加到del中
                if np.any(np.isnan(pos)):
                    to_del.append(t)
            """ 
                np.ma.masked_invalid(跟踪器链trks矩阵):
                    将会对跟踪器链trks矩阵中出现了NaN或inf的某行进行生成掩码,用于屏蔽出现无效值该整行的跟踪器框。
                np.ma.compress_rows(包含掩码值的跟踪器链trks矩阵):
                    将包含掩码值的整行从中进行移除出去。
                最终跟踪器链trks矩阵:只包含“上一帧中的跟踪器链中所有跟踪框在当前帧中成功进行predict预测”的新跟踪框。
            """
            #trks中去除无效值的行,保存根据上一帧结果预测当前帧的内容
            # numpy.ma.masked_invalid 屏蔽出现无效值的数组(NaN 或 inf)
            # numpy.ma.compress_rows 压缩包含掩码值的2-D 数组的整行,将包含掩码值的整行去除
            # trks中存储了上一帧中跟踪的目标并且在当前帧中的预测跟踪框
            trks = np.ma.compress_rows(np.ma.masked_invalid(trks))
            """
            1.for t in reversed(列表):
                1.t:列表中的元素值
                2.要想从List列表中删除任意索引位置的元素的话,必须不能从列表头开始遍历删除元素,必须从列表尾向列表头的方向进行遍历删除元素,
                  因为如果从列表头开始遍历删除元素的话,便会导致后面的元素会移动补充到被删除元素的索引位置上,
                  那么再向后进行遍历时便会出现漏遍历的元素,也即防止破坏索引,因此删除列表中元素时需要从列表尾向列表头的方向进行遍历。
            2.for t in reversed(to_del)
                1.t:列表中的元素值
                2.此处to_del列表中的元素值保存的是trackers跟踪器链(列表)中要删除元素的索引值,
                  因此从to_del列表的列表尾向列表头的方向进行遍历出“trackers跟踪器链(列表)中要删除元素的”索引值。
                  然后使用trackers.pop(t)根据trackers跟踪器链(列表)中元素的索引值t自动从列表中移除该元素。
            3.List pop()方法
                    1.pop()方法语法:list.pop([index=-1])
                    2.pop()函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
                    3.pop(可选参数)中参数:可选参数,要移除列表元素的索引值,不能超过列表总长度,默认为 index=-1,删除最后一个列表值。
                    4.pop()返回值:该方法返回从列表中被移除的元素对象。
                    5.pop(要移除的列表中元素的索引值):根据列表中元素的索引值自动从列表中移除
            """
            #删除nan的结果,逆向删除异常的跟踪器,防止破坏索引
            for t in reversed(to_del):
                """
                            根据to_del列表中保存的跟踪框的索引值到跟踪器链(列表)中将该跟踪框从其中移除出去。
                            trackers:上一帧中的跟踪器链(列表),保存的是上一帧中成功跟踪目标的跟踪框,也即成功跟踪目标的KalmanBoxTracker卡尔曼滤波对象。
                            trackers.pop(要移除的某个跟踪框的索引值):即能根据该索引值从跟踪器链(列表)中把该跟踪框移除出去
                            """
                # pop(要移除的列表中元素的索引值):根据列表中元素的索引值自动从列表中移除
                self.trackers.pop(t)
            """
                matches:
                    [[检测框的索引值, 跟踪框的索引值] [检测框的索引值, 跟踪框的索引值] 。。。]
                    跟踪成功并且两两匹配组合的IOU值大于iou阈值的检测框和跟踪框组成的矩阵
                unmatched_detections:
                    [检测框的索引值,。。。]
                    1.新增目标的检测框在detections检测框列表中的索引位置
                    2.两两匹配组合的IOU值小于iou阈值的检测框在detections检测框列表中的索引位置
                unmatched_trackers:
                    [跟踪框的索引值,。。。]
                    1.跟踪失败的跟踪框/预测框在trackers跟踪框列表中的索引位置
                    2.两两匹配组合的IOU值小于iou阈值的跟踪框/预测框在trackers跟踪框列表中的索引位置
    
                1.matched:跟踪成功目标的矩阵。即前后帧都存在的目标,并且匹配成功同时大于iou阈值。
                2.unmatched_detections(列表):
                    1.检测框中出现新目标,但此时预测框(跟踪框)中仍不不存在该目标,
                      那么就需要在创建新目标对应的预测框/跟踪框(KalmanBoxTracker类的实例对象),
                      然后把新目标对应的KalmanBoxTracker类的实例对象放到跟踪器链(列表)中。
                    2.同时如果因为“跟踪框和检测框之间的”两两组合的匹配度IOU值小于iou阈值,
                      则也要把目标检测框放到unmatched_detections中。
                3.unmatched_trackers(列表):
                    1.当跟踪目标失败或目标离开了画面时,也即目标从检测框中消失了,就应把目标对应的跟踪框(预测框)从跟踪器链中删除。
                      unmatched_trackers列表中保存的正是跟踪失败即离开画面的目标,但该目标对应的预测框/跟踪框(KalmanBoxTracker类的实例对象)
                      此时仍然存在于跟踪器链(列表)中,因此就需要把该目标对应的预测框/跟踪框(KalmanBoxTracker类的实例对象)从跟踪器链(列表)中删除出去。
                    2.同时如果因为“跟踪框和检测框之间的”两两组合的匹配度IOU值小于iou阈值,
                      则也要把跟踪目标框放到unmatched_trackers中。
             """
            #使用匈牙利算法:将目标检测框和卡尔曼滤波器预测的跟踪框进行匹配,分别获取跟踪成功的目标,新增的目标,离开画面的目标
            matched,unmatched_dets,unmatche_trkes = associate_detection_to_tracker(dets,trks)
            """
               for t, trk in enumerate(trackers列表)
                   t:为从0到列表长度-1的索引值
                   trk:trackers列表中每个KalmanBoxTracker卡尔曼滤波对象
            """
            #将跟踪成功的目标更新到对应的卡尔曼滤波器
            for t,trk in enumerate(self.trackers):
                """ 
                    1.trackers:上一帧中的跟踪器链(列表),保存的是上一帧中成功跟踪目标的跟踪框,也即成功跟踪目标的KalmanBoxTracker卡尔曼滤波对象。
                    2.for t, trk in enumerate(trackers):
                        遍历上一帧中的跟踪器链(列表)中从0到列表长度-1的索引值t 和 每个KalmanBoxTracker卡尔曼滤波对象trk。
                    3.if t not in unmatched_trks:
                        如果上一帧中的跟踪框(KalmanBoxTracker卡尔曼滤波对)的索引值不在当前帧中的unmatched_trackers(列表)中的话,
                        即代表上一帧中的跟踪框在当前帧中成功跟踪到目标,
                        并且代表了“上一帧中的跟踪框在当前帧中的”预测框和当前帧中的检测框的匹配度IOU值大于iou阈值。
                    4.matched[:, 1]:获取的是跟踪框的索引值,即[[检测框的索引值, 跟踪框的索引值] 。。。]中的跟踪框的索引值。
                    5.np.where(matched[:, 1] == t)[0]:
                        where返回的为符合条件的“[检测框的索引值, 跟踪框的索引值]”数组在matched矩阵中的索引值,即行值。
                        因此最后使用[0]就是从array([索引值/行值])中把索引值/行值取出来。
                    6.matched[索引值/行值, 0]:
                        根据索引值/行值获取出matched矩阵中的[检测框的索引值, 跟踪框的索引值],然后获取出第一列的“检测框的索引值”。
                    7.dets[d, :]:
                            根据检测框的索引值/行值从当前帧中的dets检测框列表获取出该检测框的所有列值,最终返回的是一个二维矩阵如下所示:
                            第一种方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度]]
                            第二种方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]]
                    8.dets[d, :][0]:获取出[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]
                    9.trk.update(检测框的5个值的列表):使用检测框进行更新状态更新向量x(状态变量x),也即使用检测框更新跟踪框。
                """
                if t not in unmatche_trkes:
                    d = matched[np.where(matched[:, 1] == t)[0], 0]
                    # 使用观测的边界框更新状态向量
                    trk.update(dets[d, :][0])
            """
            unmatched_detections(列表)
                保存了出现新目标的检测框的索引值,还保存了“因为跟踪框和检测框之间的两两组合的匹配度IOU值小于iou阈值的”目标检测框的索引值。
            dets[i, :]:
                根据索引值从当前帧中的检测框列表dets中获取对应的检测框,即该行的所有列值。
                该检测框的值为:
                    第一种方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度]]
                    第二种方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]]
            KalmanBoxTracker(dets[i, :]):
                传入检测框进行创建该新目标对应的跟踪框KalmanBoxTracker卡尔曼滤波对象trk。
                每个目标框都有对应的一个卡尔曼滤波器(KalmanBoxTracker实例对象),增加一个目标框就增加一个卡尔曼滤波器(KalmanBoxTracker实例对象)。
            trackers.append(trk):把新增的卡尔曼滤波器(KalmanBoxTracker实例对象trk)存储到跟踪器链(列表)trackers中
            """
            #为新增目标创建新的卡尔曼滤波器的跟踪器
            for i in unmatched_dets:
                trk = KalmanBoxTracker(dets[i,0])
                self.trackers.append(trk)
            # 自后向前遍历,仅返回在当前帧出现且命中周期大于self.min_hits(除非跟踪刚开始)的跟踪结果;如果未命中时间大于self.max_age则删除跟踪器。
            # hit_streak忽略目标初始的若干帧
            """ i为trackers跟踪器链(列表)长度,从列表尾向列表头的方向 每遍历trackers跟踪器链(列表)一次 即进行 i-=1 """
            i = len(self.trackers)
    
            """ reversed逆向遍历trackers跟踪器链(列表),目的为删除列表中的元素的同时不会造成漏遍历元素的问题 """
            # 逆向遍历
            for trk in reversed(self.trackers):
                """ 
                    (跟踪框)KalmanBoxTracker卡尔曼滤波对象trk.get_state():
                        获取跟踪框所预测的在当前帧中的预测结果(已经从[x,y,s,r]转换为[x1,y1,x2,y2]) 
                        [x1,y1,x2,y2]即为[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]。
                   get_state()[0] 中使用[0] 是因为返回的为二维矩阵如下:   
                        第一种方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度]]
                        第二种方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]]
                """
                #返回当前边界框的估计值
                d = trk.get_state()[0]
                """
                1.trk.time_since_update < 1:
                    1.time_since_update:
                        记录了该目标对应的卡尔曼滤波器中的预测框(跟踪框)进行连续预测的次数,每执行predict一次即进行time_since_update+=1。
                        在连续预测(连续执行predict)的过程中,一旦执行update的话,time_since_update就会被重置为0。
                    2. time_since_update < 1:
                        该目标对应的卡尔曼滤波器一旦update更新的话该变量值便重置为0,因此要求该目标对应的卡尔曼滤波器必须执行update更新步骤。
                        update更新代表了使用检测框来更新状态更新向量x(状态变量x)的操作,
                        实际即代表了使用“通过yoloV3得到的并且和预测框(跟踪框)相匹配的”检测框来更新该目标对应的卡尔曼滤波器中的预测框(跟踪框)。
    
                2.trk.hit_streak >= min_hits:
                        1.hit_streak
                            1.连续更新的次数,每执行update一次即进行hit_streak+=1。
                            2.在连续更新(连续执行update)的过程中,一旦开始连续执行predict两次或以上的情况下,
                              当连续第一次执行predict时,因为time_since_update仍然为0,并不会把hit_streak重置为0,
                              然后才会进行time_since_update+=1;
                              当连续第二次执行predict时,因为time_since_update已经为1,那么便会把hit_streak重置为0,
                              然后继续进行time_since_update+=1。     
                        2.min_hits
                            跟踪框连续成功跟踪到目标的最小次数,也即跟踪框至少需要连续min_hits次成功跟踪到目标。
                        3.hit_streak >= min_hits
                            跟踪框连续更新的次数hit_streak必须大于等于min_hits。
                            而小于该min_hits次数的话update函数不返回该目标的KalmanBoxTracker卡尔曼滤波对象。
    
                3.frame_count <= min_hits:
                        因为视频的一开始frame_count为0,而需要每经过一帧frame_count才会+=1。
                        因此在视频的一开始前N帧中,即使frame_count 小于等于min_hits 也可以。
                """
                # 跟踪成功目标的box与id放入ret列表中
                if (trk.time_since_update < 1) and (trk.hit_streak >= self.min_hits or self.frame_count <= self.min_hits):
                    """ 
                        1.ret:
                            当前帧中跟踪目标成功的跟踪框/预测框的集合,包含目标的跟踪的id(也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个)
                            第一种返回值方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度, trk.id] ...]
                            第二种返回值方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, trk.id] ...]
                            d:[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]
                            trk.id:卡尔曼滤波器的个数/目标框的个数,也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个。
                        2.np.concatenate((d, [trk.id + 1])).reshape(1, -1)
                            [[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, 该跟踪框是创建出来的第几个]]
                    """
                    ret.append(np.concatenate((d, [trk.id + 1])).reshape(1, -1))  # +1 as MOT benchmark requires positive
                """ i为trackers跟踪器链(列表)长度,从列表尾向列表头的方向 每遍历trackers跟踪器链(列表)一次 即进行 i-=1 """
                i -= 1
                """
                trk.time_since_update > max_age
                    1.time_since_update:
                        记录了该目标对应的卡尔曼滤波器中的预测框(跟踪框)进行连续预测的次数,每执行predict一次即进行time_since_update+=1。
                        在连续预测(连续执行predict)的过程中,一旦执行update的话,time_since_update就会被重置为0。
                    2.max_age:
                        最大跟丢帧数。如果当前连续N帧大于最大跟丢帧数的话,则从跟踪器链中删除该卡尔曼滤波对象的预测框(跟踪框)。
                    3.time_since_update > max_age:
                        每预测一帧time_since_update就会+=1,只有预测的跟踪框跟踪到目标(即预测的跟踪框和检测框相似度匹配)才会执行update更新,
                        那么time_since_update才会被重置为0。
                        那么当连续time_since_update帧都没有跟踪到目标的话,即当连续time_since_update帧大于最大跟丢帧数时,
                        那么就需要根据该跟踪失败的跟踪器框的索引把该跟踪器框从跟踪器链(列表)trackers中进行移除出去。
                """
                # 跟踪失败或离开画面的目标从卡尔曼跟踪器中删除
                if trk.time_since_update > self.max_age:
                    """
                                   trackers:上一帧中的跟踪器链(列表),保存的是上一帧中成功跟踪目标的跟踪框,也即成功跟踪目标的KalmanBoxTracker卡尔曼滤波对象。
                                   trackers.pop(要移除的某个跟踪框的索引值):即能根据该索引值从跟踪器链(列表)中把该跟踪框移除出去
                                   """
                    # pop(要移除的列表中元素的索引值):根据列表中元素的索引值自动从列表中移除
                    self.trackers.pop(i)
            # 返回当前画面中所有目标的box与id,以二维矩阵形式返回
            if len(ret) > 0:
                """ 
                    ret:
                        当前帧中跟踪目标成功的跟踪框/预测框的集合,包含目标的跟踪的id(也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个)
                        第一种返回值方案:[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度, trk.id] ...]
                        第二种返回值方案(当前使用的为该种):[[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, trk.id] ...]
                        d:[左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标]
                        trk.id:卡尔曼滤波器的个数/目标框的个数,也即该跟踪框(卡尔曼滤波实例对象)是创建出来的第几个。
                    [
                      [左上角的x坐标, 左上角的x坐标y坐标, 右下角的x坐标, 右下角的y坐标, yolo识别目标是某种物体的可信度, 该跟踪框是创建出来的第几个] 
                      [...]
                      [...]
                    ]
                """
                return np.concatenate(ret)
            return np.empty((0, 5))
    
    
    展开全文
  • 用YOLOV5初步实现目标检测

    千次阅读 2021-12-12 18:07:29
    用YOLOV5初步实现目标检测

     文章目录

    ​前言

    随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就将分享用YOLOV5进行目标检测并进行机器学习的方法

    一、目标检测是什么?

    目标检测(Object Detection也叫目标提取,是一种基于目标几何和统计特征的图像分割。就是在视频或者图像中,通过计算机自动检测出其中的物体,将其框出,并注释。它是计算机视觉领域的核心问题之一。随着计算机技术的发展和计算机视觉原理的广泛应用,利用计算机图像处理技术对目标进行实时跟踪研究越来越热门,对目标进行动态实时跟踪定位在智能化交通系统、智能监控系统军事目标检测及医学导航手术中手术器械定位等方面具有广泛的应用价值。

    二、使用步骤


    1.代码下载

    https://github.com/ultralytics/yolov5


    2.pycharm进行代码运行

    1、打开pycharm新建工程,并打开下载源码的目录,找到detect.py并打开。(你也可以阅读README来获取更多代码的相关信息)

    2、进行代码的初次运行,右键后点击运行 detect.py’,不出意外的话将会出现许多红色的报错,比如“No model named 'yaml’ ”这是因为在你的电脑上缺少运行此程序需要的model,只需要在命令行(cmd)上下载下来就可以。(当然要下载model,还需要配置环境以及将pip源转换到国内镜像)

    3、拿缺少'yaml'为例子,打开命令行,输入pip install pyyaml,回车,就可以看到正在下载该model,如果成功下载会出现一下情景:

    4、在下载完所有model后,打开运行run)菜单,进入编辑配置Edit Configurations)在

    参数Paramters)中输入 --source 0 ,则表示用0号摄像头(笔记本电脑自带位于屏幕上方)进行测试。如输入--source data/images,则表示用data/images下的所有图片进行测试,如果输入--source 1.mp4,则表示用1.mp4视频文件进行测试。

    在这之后在运行detect.py,稍等片刻就会看到摄像头指示灯亮起,目标检测开始了:

    当然这次目标检测初步识别也有识别失败的,如把凳子识别成交通信号灯,此外旁边的小数代表概率。接下来就需要进行大量的数据训练来提高识别精度了。

    运行目标检测


    命令行下的项目model下载


    总结

    以上就是用YOLOV5初步进行目标检测的步骤,此外还可以进一步进行数据训练,使计算机深度学习,达到有更准确的识别结果以及更广泛的识别对象的目的。

    展开全文
  • 基于OpenCV的运动目标跟踪及其实现李振伟1,2,陈翀1,2,赵有1【摘要】CAMSHIFT算法是一种基于颜色直方图的目标跟踪算法。在视频跟踪过程中,CAMSHIFT算法利用选定目标的颜色直方图模型得到每帧图像的颜色投影图,并...
  • 运动目标追踪实现(opencv3)(二)发布时间:2018-10-24 17:29,浏览次数:418, 标签:opencv运动目标的追踪最近刚开始做目标追踪,理解的还不成熟,博客有错处,欢迎在评论区指出。有许多博主实现追踪用的卡尔曼方法,...
  • 再进一步说作为公司、集团或组织如果设定了高目标并想动员全员实现目标那么大家拥有同样的愿望或想法就很重要。换句话说就是要统一思想团结一心。从公司规模还很小的时候开始我就经常会在一天的工作结束后把在场的...
  • FPGA实现实时运动目标检测verilog

    千次阅读 2021-11-15 20:18:30
    本文实现运动目标检测得方法是采用帧间差分法,使用verilog语言实现。 使用得平台是Altera开发板,前端摄像头使用OV7725或者OV7670,显示使用VGA或TFT显示在显示器上。使用FPGA实现帧间差分法得难点在于如何实现帧...
  • Qt+YOLOv4实现目标检测

    千次阅读 2021-10-22 15:28:24
    环境: 系统:win10 (显卡:NVIDIA GTX 1050) Yolo版本:V4 cuda:11.2 cudnn:8.1.1 opencv:3.4.15 ...1.2 安装cudacudnn 安装教程可以参考我这篇文章。 深度学习GPU环境CUDA安装教程 ...
  • 目标线性规划的若干解法及MATLAB 实现一.多目标线性规划模型多目标线性规划有着两个两个以上的目标函数,且目标函数约束条件全是线性函数,其数学模型表示为:11111221221122221122max n n n nr r r rn nz c x ...
  • 事实上,要达成一个工作目标,往往需要将目标清晰化,并且根据清晰的目标制定具体且合理的执行计划,这一过程可称为一次合理的目标管理。 而合理的目标管理,它往往能够帮助我们在职场中达到以下效果: 1、...
  • 在多个摄像头分别位于完全不同的位置进行拍摄这个前提下,我们可以采用简单的将不同摄像头画面进行逐帧拼接再进行目标检测,追踪来实现这个要求。 因为我们对视频、摄像头进行目标检测、每个对象添加id并不是对视频...
  • 这里就一步步来教一下大家如何用C++ OpenCV 实现视频目标检测(YOLOv4模型)。 1.实现思路 读取视频流,载入模型,执行推理,找出所有目标及其位置,最后绘制检测结果。 2.实现步骤 读取摄像头视频流或本地...
  • 目标检测任务超大图像的切图实现

    千次阅读 多人点赞 2021-04-17 19:55:02
    难点:图像分辨率大,样本中小目标居多的情况下,如果reshape成小图再送进网络训练的话,目标会变得非常小,识别难度大。直接大图训练GPU显存又顶不住,太大的原图会消耗太多的cpu时间,导致极度拖慢训练时间,而且...
  • 二、由于视频环境的复杂应用场景的复杂,很难使用单一技术应对所有的应用环境,各种相关算法不断涌现出来。 问题陈述及应用: 移动目标检测一般不单独构成应用,而是在作为系统的一个组件。 随着系统应用的不同...
  • 人们总是喜欢给自己设定目标,但是设定目标并不是就可以...对于任何问题,原则上都需要制定计划,技术还是保证目标实现最有利的武器 你要知道,目标只是一种理想状态,通常是短期的,是要努力才能到达的状态,而目标任
  • YOLOX+Deepsort 实现目标追踪

    千次阅读 2021-08-03 17:02:43
    使用YOLOX+Deepsort实现车辆行人追踪计数,代码封装成一个Detector类,更容易嵌入到自己的项目中。 代码地址(欢迎star): https://github.com/Sharpiless/yolox-deepsort 最终效果: 运行demo: python demo.py...
  • 目标检测中ROC的实现【1】

    千次阅读 2021-11-16 14:59:15
    评价目标检测中的各种标准,如map,ROC通常用于分类算法...这里参考python 实现目标检测中roc 该文中因为只有人脸一个类别,实现完在自己的检测结果的ROC曲线有点问题 : 2.1 数据预处理 需要从算法端的检测结果保存成
  • 目标偏差变量.PPT

    2021-04-21 08:48:51
    目标偏差变量精品课程《运筹学》 2、用图解法求解下列目标规划问题: 精品课程《运筹学》 3、用图解法解下列目标规划模型。 精品课程《运筹学》 第三节 目标规划问题的一些例子 精品课程《运筹学》 1.已知条件如...
  • 目标检测

    千次阅读 2021-12-14 10:22:48
    目标检测 参考论文:地址 小目标定义 相对尺度定义 从目标与图像的相对比对小目标进行定义。Chen等提出了一个针对小目标的数据集,对小目标进行定义:同一类别中,所有目标实例的相对面积,即边界框面积与图像...
  • 你是如何理解纵向目标和横向目标的?主持人:你如何理解总目标、年龄目标、活动目标?叶:总目标是整个幼儿园阶段数学领域的目标。年龄段的目标是小中大各不同年龄的目标,教育活动目标是某个具体活动的目标。主持人...
  • 用Matlab自带的FastRcnnNetwork工具箱实现深度学习目标检测 一.搭建训练数据集验证数据集 用的是Matlab2018a以上版本里的应用程序带的ImageLabeler来进行数据标记: 将标记好的数据以.groundTruth格式导入到工作...
  • weixu000/libtorch-yolov3-deepsort deepsort yolov3 c++版本 LibTorch、OpenCV、wxWidgetsCMake libtorch-yolov3-deepsort 196 作者本科毕设 bitzy/DeepSort deepsort c++版本 yolov2 opencv3 tensorflow 1.4 ...
  • 在Unity上实现目标识别

    千次阅读 2021-11-01 21:06:05
    5、创建文件夹上传识别图,注意格式大小 6、下载相应的SDK 7、下面是官方的一些示例一些功能介绍 8、导入资源包 目前高通在PC运行监测必须是32位unity 64位只能在android机上运行 把高通自带的预制体拖进去 ...
  • Yolov5—实现目标检测(win10)

    千次阅读 2021-02-03 23:12:07
    Yolov5—实现目标检测(win10)该方法可以在win10上实现Yolov5的目标检测,配置前需要安装Anaconda3一、环境配置源码下载地址:https://github.com/ultralytics/yolov5.git推荐使用B站up主修改好的文件配置Yolov5环境...
  • Python实现一个简单的目标检测

    千次阅读 2021-02-07 11:13:07
    Python实现一个简单的目标检测相关介绍实验环境基本思路代码实现输出结果 相关介绍 选择性搜索(Select Search)算法属于候选区域算法,用分割不同区域的办法来识别潜在的物体。在分割的时候,我们要合并那些在...
  • 使用MATLAB训练Faster R-CNN目标检测器,实现对车辆的检测
  • 实际上,IT部门需要根据预算、资源应用优先级来设置不同的恢复时间恢复点目标。  人们将这两个目标称为恢复时间目标(RTO)恢复点目标(RPO)。它们是相关的,并且这两者都是应用程序数据恢复所必需的。它们.....
  • %%对分法求解目标函数最优解函数function [t,y]=equation_extremum(x,~,a,b,epsional)%%=======================================%函数默认参数:%x为目标函数,输入字符串型,默认最优解求其最小值%a,b为其初始...
  • 文章目录前言一、Yolov3 Yolov3-tiny二、使用步骤1.引入库2.读入数据总结 前言 上一篇文章 神奇的目标检测 已经介绍了目标检测的基础啦。目标检测呢,就是在图片中定位出目标的位置,把它“框”出来就好了。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,262,676
精华内容 905,070
关键字:

如何制定目标和实现目标