精华内容
下载资源
问答
  • 使用PyTorch实现目标检测与跟踪

    千次阅读 多人点赞 2020-12-02 21:00:00
    欢迎关注“小白玩转Python”,发现更多 “有趣”引言在昨天的文章中,我们介绍了如何在PyTorch中使用您自己的图像来训练图像分类器,然后使用它来进行图像识别。本文将展示如何使用预...

    欢迎关注 “小白玩转Python”,发现更多 “有趣”

    引言

    在昨天的文章中,我们介绍了如何在PyTorch中使用您自己的图像来训练图像分类器,然后使用它来进行图像识别。本文将展示如何使用预训练的分类器检测图像中的多个对象,并在视频中跟踪它们。

    图像中的目标检测

    目标检测的算法有很多,YOLO跟SSD是现下最流行的算法。在本文中,我们将使用YOLOv3。在这里我们不会详细讨论YOLO,如果想对它有更多了解,可以参考下面的链接哦~(https://pjreddie.com/darknet/yolo/)

    下面让我们开始吧,依然从导入模块开始:

    from models import *
    from utils import *
    import os, sys, time, datetime, random
    import torch
    from torch.utils.data import DataLoader
    from torchvision import datasets, transforms
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    from PIL import Image
    

    然后加载预训练的配置和权重,以及一些预定义的值,包括:图像的尺寸、置信度阈值和非最大抑制阈值。

    config_path='config/yolov3.cfg'
    weights_path='config/yolov3.weights'
    class_path='config/coco.names'
    img_size=416
    conf_thres=0.8
    nms_thres=0.4
    # Load model and weights
    model = Darknet(config_path, img_size=img_size)
    model.load_weights(weights_path)
    model.cuda()
    model.eval()
    classes = utils.load_classes(class_path)
    Tensor = torch.cuda.FloatTensor
    

    下面的函数将返回对指定图像的检测结果。

    def detect_image(img):
        # scale and pad image
        ratio = min(img_size/img.size[0], img_size/img.size[1])
        imw = round(img.size[0] * ratio)
        imh = round(img.size[1] * ratio)
        img_transforms=transforms.Compose([transforms.Resize((imh,imw)),
             transforms.Pad((max(int((imh-imw)/2),0), 
                  max(int((imw-imh)/2),0), max(int((imh-imw)/2),0),
                  max(int((imw-imh)/2),0)), (128,128,128)),
             transforms.ToTensor(),
             ])
        # convert image to Tensor
        image_tensor = img_transforms(img).float()
        image_tensor = image_tensor.unsqueeze_(0)
        input_img = Variable(image_tensor.type(Tensor))
        # run inference on the model and get detections
        with torch.no_grad():
            detections = model(input_img)
            detections = utils.non_max_suppression(detections, 80, 
                            conf_thres, nms_thres)
        return detections[0]
    

    最后,让我们通过加载一个图像,获取检测结果,然后用检测到的对象周围的包围框来显示它。并为不同的类使用不同的颜色来区分。

    # load image and get detections
    img_path = "images/blueangels.jpg"
    prev_time = time.time()
    img = Image.open(img_path)
    detections = detect_image(img)
    inference_time = datetime.timedelta(seconds=time.time() - prev_time)
    print ('Inference Time: %s' % (inference_time))
    # Get bounding-box colors
    cmap = plt.get_cmap('tab20b')
    colors = [cmap(i) for i in np.linspace(0, 1, 20)]
    img = np.array(img)
    plt.figure()
    fig, ax = plt.subplots(1, figsize=(12,9))
    ax.imshow(img)
    pad_x = max(img.shape[0] - img.shape[1], 0) * (img_size / max(img.shape))
    pad_y = max(img.shape[1] - img.shape[0], 0) * (img_size / max(img.shape))
    unpad_h = img_size - pad_y
    unpad_w = img_size - pad_x
    if detections is not None:
        unique_labels = detections[:, -1].cpu().unique()
        n_cls_preds = len(unique_labels)
        bbox_colors = random.sample(colors, n_cls_preds)
        # browse detections and draw bounding boxes
        for x1, y1, x2, y2, conf, cls_conf, cls_pred in detections:
            box_h = ((y2 - y1) / unpad_h) * img.shape[0]
            box_w = ((x2 - x1) / unpad_w) * img.shape[1]
            y1 = ((y1 - pad_y // 2) / unpad_h) * img.shape[0]
            x1 = ((x1 - pad_x // 2) / unpad_w) * img.shape[1]
            color = bbox_colors[int(np.where(
                 unique_labels == int(cls_pred))[0])]
            bbox = patches.Rectangle((x1, y1), box_w, box_h,
                 linewidth=2, edgecolor=color, facecolor='none')
            ax.add_patch(bbox)
            plt.text(x1, y1, s=classes[int(cls_pred)], 
                    color='white', verticalalignment='top',
                    bbox={'color': color, 'pad': 0})
    plt.axis('off')
    # save image
    plt.savefig(img_path.replace(".jpg", "-det.jpg"),        
                      bbox_inches='tight', pad_inches=0.0)
    plt.show()
    

    下面是我们的一些检测结果:

    视频中的目标跟踪

    现在你知道了如何在图像中检测不同的物体。当你在一个视频中一帧一帧地看时,你会看到那些跟踪框在移动。但是如果这些视频帧中有多个对象,你如何知道一个帧中的对象是否与前一个帧中的对象相同?这被称为目标跟踪,它使用多次检测来识别一个特定的对象。

    有多种算法可以做到这一点,在本文中决定使用SORT(Simple Online and Realtime Tracking),它使用Kalman滤波器预测先前识别的目标的轨迹,并将其与新的检测结果进行匹配,非常方便且速度很快。

    现在开始编写代码,前3个代码段将与单幅图像检测中的代码段相同,因为它们处理的是在单帧上获得 YOLO 检测。差异在最后一部分出现,对于每个检测,我们调用 Sort 对象的 Update 函数,以获得对图像中对象的引用。因此,与前面示例中的常规检测(包括边界框的坐标和类预测)不同,我们将获得跟踪的对象,除了上面的参数,还包括一个对象 ID。并且需要使用OpenCV来读取视频并显示视频帧。

    videopath = 'video/interp.mp4'
    %pylab inline 
    import cv2
    from IPython.display import clear_output
    cmap = plt.get_cmap('tab20b')
    colors = [cmap(i)[:3] for i in np.linspace(0, 1, 20)]
    # initialize Sort object and video capture
    from sort import *
    vid = cv2.VideoCapture(videopath)
    mot_tracker = Sort()
    #while(True):
    for ii in range(40):
        ret, frame = vid.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pilimg = Image.fromarray(frame)
        detections = detect_image(pilimg)
        img = np.array(pilimg)
        pad_x = max(img.shape[0] - img.shape[1], 0) * 
                (img_size / max(img.shape))
        pad_y = max(img.shape[1] - img.shape[0], 0) * 
                (img_size / max(img.shape))
        unpad_h = img_size - pad_y
        unpad_w = img_size - pad_x
        if detections is not None:
            tracked_objects = mot_tracker.update(detections.cpu())
            unique_labels = detections[:, -1].cpu().unique()
            n_cls_preds = len(unique_labels)
            for x1, y1, x2, y2, obj_id, cls_pred in tracked_objects:
                box_h = int(((y2 - y1) / unpad_h) * img.shape[0])
                box_w = int(((x2 - x1) / unpad_w) * img.shape[1])
                y1 = int(((y1 - pad_y // 2) / unpad_h) * img.shape[0])
                x1 = int(((x1 - pad_x // 2) / unpad_w) * img.shape[1])
                color = colors[int(obj_id) % len(colors)]
                color = [i * 255 for i in color]
                cls = classes[int(cls_pred)]
                cv2.rectangle(frame, (x1, y1), (x1+box_w, y1+box_h),
                             color, 4)
                cv2.rectangle(frame, (x1, y1-35), (x1+len(cls)*19+60,
                             y1), color, -1)
                cv2.putText(frame, cls + "-" + str(int(obj_id)), 
                            (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 
                            1, (255,255,255), 3)
        fig=figure(figsize=(12, 8))
        title("Video Stream")
        imshow(frame)
        show()
        clear_output(wait=True)
    

    下面让我们来看一下处理的结果:

    ·  END  ·

    HAPPY LIFE

    展开全文
  • 将小黄人图片粘贴到自然图像上面,然后检测图片中的小黄人,下面是粘贴好的图片。实验中可以用一个较小的数据集进行训练,准备5000张自然图片,小黄人可以下载10 - 20 多张不同的,将其随机粘贴到5000张自然图像上...

    一、项目介绍

    该示例首先有两部分数据,第一部分准备小黄人数据集,第二部分准备自然图像数据集。将小黄人图片粘贴到自然图像上面,然后检测图片中的小黄人,下面是粘贴好的图片。实验中可以用一个较小的数据集进行训练,准备5000张自然图片,小黄人可以下载10 - 20 多张不同的,将其随机粘贴到5000张自然图像上即可。
    在这里插入图片描述在这里插入图片描述

    二、数据预处理

    import numpy as np
    from PIL import Image
    import os
    # 对收集的5000张自然图像进行处理,因为利用爬虫爬的图片大小,图片的模式都不相同,所以为了数据的统一先进行处理。
    def convertImage():
        listpath = os.listdir("path") # 这里path 表示你大自然图片的数据集路径。
        for path in listpath:
            img = Image.open(os.path.join("path",path))
            img = img.convert("RGB")   # 转化为RGB模式
            # 尺寸设置为224*224,采用细节增强缩放  ,
            img = img.resize((224,224),Image.ANTIALIAS) 
            img.save("")  # 保存处理好的图片
    
    def createDataset(dirimage):
        listpath = os.listdir(dirimage)
        for index , path in enumerate(listpath): # enumerate 这个函数的作用就是增加一个索引值(可以理解为加序号)
            img = Image.open(os.path.join(dirimage,path))
            “”“ 
            这里将数据集分为训练集4000张(2000张作为正样本,也就是贴上小黄人的样本,2000张作为负样),
            测试集1000张(500张作为正样本,500张作为负样本)。0-1999, 4000-4499这两个区间上的图片粘贴小黄人,其他的不粘贴。
            ”“”
            if index < 2000 or (index >= 4000 and index < 4500):
                """随机取出一张小黄人图片,这里还可以用np.random.choice(img_yellow),img_yellow 是一个列表,这是从列表中随机取一个值的方式"""
                minions=Image.open("yellow/{}.png".format(np.random.randint(1,21)))
                # 缩放
                h = w = np.random.randint(64,180) 
                # 将小黄人的尺寸随机缩放成64 - 180 的大小
                minions = minions.resize((h,w),Image.ANTIALIAS)
                # 旋转
                minions = minions.rotate(np.random.randint(-30,30))
                # 翻转,镜像翻转
                minions = minions.transpose(Image.FLIP_LEFT_RIGHT) if np.random.randint(0,2) == 1 else minions
                x,y = np.random.randint(0, 224 - w) , np.random.randint(0, 224 - h)
                # 掩码
                r,g,b,a = minions.split() # 分离通道小黄人是RGBA 的格式
                # mask 表示图像的一部分,或者说你感兴趣的部分。这里粘贴小黄人的a通道
                img.paste(minions,(x,y), mask=a)  
    
                # print(x,y)
                if not os.path.isdir("datasets"): # 判断文件夹是否存在
                    os.mkdir("datasets")   # 创建文件夹
                img.save("datasets/{}.{}.{}.{}.{}.{}.jpg".format(index,x,y,x+w,y+h,1))
            else:
                img.save("datasets/{}.0.0.0.0.0.jpg".format(index)
    
    
    if __name__ == '__main__':
        convertImage()
        createDataset(r"图片路径")
    
    

    三、制作数据集

    制作数据集基本的思路(结构),加载一个类,定义三个模块。具体看下面代码:

    # 数据集制作的基本框架
    from torch.utils.data import Dataset
    “”“`Dataset`代表Dataset的抽象类,这个模块请阅读torch底层代码“”“
    
    class MyDateSet(Dataset):
        # 该模块的作用是加载数据集 
        def __init__(self):
            super(MyDateSet, self).__init__()
            pass
        # 获取数据集的大小
        def __len__(self):
            pass
        # 根据索引取出数据,返回数据和数据的标签。
        def __getitem__(self, index):
            pass
    

    下面利用这个三个模块制作数据集。

    import torch
    from torch.utils.data import Dataset,DataLoader
    import os
    from PIL import Image
    import numpy as np
    import torchvision.transforms as trans
    
    
    class MyDataset(Dataset):
        # 计算mean 和std 的方法请看我的博客《pytorch 猫狗数据集识别(一)》这里面有详细的计算过程
        mean = torch.tensor([0.5708, 0.5661, 0.5395])
        std = torch.tensor([0.3128, 0.2978, 0.3172])
        
        def __init__(self,root=None,train=True,transforms=None):
            self.path = root
            self.transforms = transforms
            self.dataset = os.listdir(self.path)
            # index(".")查找第一个"."的位置,然后x[:x.index(".")]取出该值:
            “”“                                    序号 x1 y1 x2 y2 标签(1表示粘贴了小黄人)
            可能这样说不是很清楚,举个例子:图片的标签是a['12.35.67.68.97.1.jpg']
            a[0] = '12.35.67.68.97.1.jpg'
            a[0].index(".") == 2
            a[0][:a[0].index(".")] 即a[0][:2]==12     
            所以可以看出这个代码是为了取出图片的序号,也就是图片的第一项。
            ”“”
            self.dataset.sort(key=lambda x: int(x[:x.index(".")])) #根据图片的序号进行排序
            if train:
                 # train == True 0-3999为训练集 这里2000张正样本,2000张负样本
                self.dataset = self.dataset[:4000]  
            else:
                # train ==False 4000-4999为测试集,这里500张正样本,500张负样本
                self.dataset = self.dataset[4000:5000] 
        # 获取数集的大小
        def __len__(self):
            return len(self.dataset)
    
        def __getitem__(self, index):
            imgpath = self.dataset[index] # 跟据索引获取图片
            img = Image.open(os.path.join(self.path, imgpath))
            # transforms=trans.Compose([trans.ToTensor(), trans.Normalize(MyDataset.mean, MyDataset.std)])
            data = self.transforms(img) 
            labels = imgpath.split(".")
            # 这里取的是坐标,必须要将坐标转换为array,这样才能进行计算,并且除以224对其进行归一化处理
            axes = np.array(labels[1:5],dtype=np.float32) / 224 
            category = np.array(labels[5:6], dtype=np.float32) # 这里取的是标签,1 和 0 
            # 拼接列表,这里有先后顺序
            target = np.concatenate((axes,category))
            return data, target
    

    四、构建网络模型

    # 计算特征图大小的计算公式:
    “”“
    out_size = (输入图片的大小 - 卷积核大小 + 2 * padding) / 步长  + 1 
    ”“”
    
    import torch.nn as nn
    # import numpy as np
    import torch
    
    
    class MyNetWork(nn.Module):
        def __init__(self):
            super(MyNetWork, self).__init__()
            self.convlution_layer =nn.Sequential(
                """ 
                1、这里用卷积 激活 卷积 激活  池化,用了两层卷积目的是用小的卷积核代替大的卷积核
                2、还要注意一点,卷积的时候一般在最前面要用最大池化,网络后面用平均池化
                3、nn.Conv2d(输入通道,输出通道,卷积核大小,步长,padding)
                4、nn.MaxPool2d(卷积核大小,步长)
                5、nn.ReLu(inplace=True) # 
                利用in-place计算可以节省内(显)存,同时还可以省去反复申请和释放内存的时间。但是会对原变量覆盖。也即对从上层网络nn.Conv2d中传递下来的tensor直接进行修改,这样能够节省运算内存,不用多存储其他变量。具体的看这篇博客:https://blog.csdn.net/AugustMe/article/details/92589979
                """
                
                nn.Conv2d(3, 16, 3, 1),  # (224 - 3 + 2 * 0)/1+1 =222
                nn.ReLU(inplace=True),
                nn.Conv2d(16, 32, 3, 1), # (222 - 3 + 2*0)/1 +1 = 220
                nn.ReLU(inplace=True),
                nn.MaxPool2d(2, 2),  # (220 - 2 + 2*0) / 2 +1 = 110
                nn.Conv2d(32, 128, 3, 1), # (110 -3 + 2*0) /1 +1 =108
                nn.ReLU(inplace=True),
                # nn.Conv2d(64, 128, 3, 1), # (108 - 3 + 2*0 )/1 + 1 =106
                # nn.ReLU(inplace=True),
                nn.MaxPool2d(2, 2),   # (108 -2 + 2*0)/2 + 1 = 54
                nn.Conv2d(128, 256, 3, 1), # (54 - 3 + 2*0)/1 + 1 = 52
                nn.ReLU(inplace=True),
                # nn.Conv2d(256, 64, 3, 1), # (51 - 3 + 2*0)/1 + 1 = 49
                # nn.ReLU(inplace=True),
                nn.AvgPool2d(2, 2),    # (52 -2 + 2*0) /2 +1 =26
                nn.Conv2d(256, 64, 3, 1), # (26 - 3)/1 +1= 24
                nn.ReLU(inplace=True),
                nn.AvgPool2d(2, 2),  # (24 -2 )/2 +1 = 12
                nn.Conv2d(64, 32, 3, 1) # (12 - 3)/1 +1 = 10
            )
           # 利用全连接网络对特征进行拼接。其实是为了将特征组合后输出五个结果(坐标 + 标签)
            self.MLP_layer = nn.Sequential(
                nn.Linear(32*10*10, 128), # 输出了32个特征图,且特征图大小为10*10 
                nn.ReLU(),
                nn.Linear(128, 5)
            )
            # 或者利用全卷积对特征进行拼接,用卷积核大小为1*1的进行卷积
    	  #self.cnn_layer2 = nn.Sequential(
          #      nn.Conv2d(32,128,10,1),  # 这里用10*10 的卷积核,因为特征图是10*10大小的,进行卷积后就得到大小为1*1的特征图
          #      nn.ReLU(True),
          #      nn.Conv2d(128,5,1,1)   # 输出5个结果,用1*1大小的卷积核进行卷积
            )
        def forward(self, x):
            input = self.convlution_layer(x)
            x_out = torch.reshape(input, shape=(-1, 32*10*10))
            out = self.MLP_layer(x_out)
            category = torch.sigmoid(out[:, 4]) # 最后一个为标签0, 1,sigmoid表示概率,一般用于二分类,因为它的输出值只会偏向两边,softmax常用于多分类。(这里用sigmoid作分类)
            axes = torch.relu(out[:, :4]) #前四个为坐标 (这里作回归,因为坐标是正数,所以用relu来解决)
            return axes, category
    

    五、训练网络

    import torch
    from torch.utils.data import DataLoader
    import torch.nn as nn
    import torchvision.transforms as trans
    from MyNet import MyNet
    from MyData import MyDataset
    from PIL import Image, ImageDraw
    import matplotlib.pyplot as plt
    import numpy as np
    import os
    
    class Trainer:
    
        def __init__(self):
            transforms = trans.Compose([ 
                trans.ToTensor(),
                trans.Normalize(MyDataset.mean,MyDataset.std)
            ])
            self.train_dataset = MyDataset(root=r"/home/gwp/PycharmProjects/ObjectDetection/train_Image", train=True, transforms=transforms)
            self.test_dataset = MyDataset(root=r"/home/gwp/PycharmProjects/ObjectDetection/train_Image", train=False, transforms=transforms)
            self.net = MyNet()
            # 回归问题最常用的损失函数是均方误差MSELoss,定义如下:
            self.offset_lossfunc = nn.MSELoss().cuda()   
    
             # BCELoss(Binary Cross Entropy Loss),就是交叉熵应用于二分类时候的特殊形式,一般都和sigmoid一起用.
            self.category_lossfunc = nn.BCELoss().cuda()
            self.optimier = torch.optim.Adam((self.net.parameters()))
    
        def train(self):
           # 这里需要注意下,如果以后在训练的过程中出现了训练中断了,可以加载保存的网络模型继续接着训练。
            if os.path.exists("models/net2.pth"):
                self.net = torch.load("models/net2.pth")
                print("exists")
    
            trainloader = DataLoader(dataset=self.train_dataset, batch_size=108, shuffle=True)
            losses = []
            for i in range(20):
                print("epochs:{}".format(i))
                for j, (x , y) in enumerate(trainloader):
                    if torch.cuda.is_available():
                        x = x.cuda()
                        y = y.cuda()
                    category,axes = self.net(x)  # 前向传播输出坐标和标签
                    # (106,)   (106,)
                    loss1 = self.category_lossfunc(category, y[:,4])
                    loss2 = self.offset_lossfunc(axes, y[:,0:4])# (106,4)
                    loss = loss1 + loss2
                    if j % 5 == 0:
                        losses.append(loss.float())
                        print("{}/{},loss:{}".format(j, len(trainloader), loss.float()))
                        plt.clf()
                        plt.plot(losses)
                        plt.pause(0.1)
    
                    self.optimier.zero_grad()
                    loss.backward()
                    self.optimier.step()
                    del x,y, category,axes,loss1,loss2,loss
                torch.save(self.net, "models/net2.pth")
    
    展开全文
  • 在昨天的文章中,我们介绍了如何在PyTorch中使用您自己的图像来训练图像分类器,然后使用它来进行图像识别。本文将展示如何使用预训练的分类器检测图像中的多个对象,并在视频中跟踪它们。 图像中的目标检测 目标...

    引言

    在昨天的文章中,我们介绍了如何在PyTorch中使用您自己的图像来训练图像分类器,然后使用它来进行图像识别。本文将展示如何使用预训练的分类器检测图像中的多个对象,并在视频中跟踪它们。

    图像中的目标检测

    目标检测的算法有很多,YOLO跟SSD是现下最流行的算法。在本文中,我们将使用YOLOv3。在这里我们不会详细讨论YOLO,如果想对它有更多了解,可以参考下面的链接哦~(https://pjreddie.com/darknet/yolo/)

    下面让我们开始吧,依然从导入模块开始:

    
     
    
     

     

    1. from models import *

    2. from utils import *

    3. import os, sys, time, datetime, random

    4. import torch

    5. from torch.utils.data import DataLoader

    6. from torchvision import datasets, transforms

    7. from torch.autograd import Variable

    8. import matplotlib.pyplot as plt

    9. import matplotlib.patches as patches

    10. from PIL import Image

     

    然后加载预训练的配置和权重,以及一些预定义的值,包括:图像的尺寸、置信度阈值和非最大抑制阈值。

    
     
    
     

     

    1. config_path='config/yolov3.cfg'

    2. weights_path='config/yolov3.weights'

    3. class_path='config/coco.names'

    4. img_size=416

    5. conf_thres=0.8

    6. nms_thres=0.4

    7. # Load model and weights

    8. model = Darknet(config_path, img_size=img_size)

    9. model.load_weights(weights_path)

    10. model.cuda()

    11. model.eval()

    12. classes = utils.load_classes(class_path)

    13. Tensor = torch.cuda.FloatTensor

     

    下面的函数将返回对指定图像的检测结果。

    
     
    
     

     

    1. def detect_image(img):

    2. # scale and pad image

    3. ratio = min(img_size/img.size[0], img_size/img.size[1])

    4. imw = round(img.size[0] * ratio)

    5. imh = round(img.size[1] * ratio)

    6. img_transforms=transforms.Compose([transforms.Resize((imh,imw)),

    7. transforms.Pad((max(int((imh-imw)/2),0),

    8. max(int((imw-imh)/2),0), max(int((imh-imw)/2),0),

    9. max(int((imw-imh)/2),0)), (128,128,128)),

    10. transforms.ToTensor(),

    11. ])

    12. # convert image to Tensor

    13. image_tensor = img_transforms(img).float()

    14. image_tensor = image_tensor.unsqueeze_(0)

    15. input_img = Variable(image_tensor.type(Tensor))

    16. # run inference on the model and get detections

    17. with torch.no_grad():

    18. detections = model(input_img)

    19. detections = utils.non_max_suppression(detections, 80,

    20. conf_thres, nms_thres)

    21. return detections[0]

     

    最后,让我们通过加载一个图像,获取检测结果,然后用检测到的对象周围的包围框来显示它。并为不同的类使用不同的颜色来区分。

    
     
    
     

     

    1. # load image and get detections

    2. img_path = "images/blueangels.jpg"

    3. prev_time = time.time()

    4. img = Image.open(img_path)

    5. detections = detect_image(img)

    6. inference_time = datetime.timedelta(seconds=time.time() - prev_time)

    7. print ('Inference Time: %s' % (inference_time))

    8. # Get bounding-box colors

    9. cmap = plt.get_cmap('tab20b')

    10. colors = [cmap(i) for i in np.linspace(0, 1, 20)]

    11. img = np.array(img)

    12. plt.figure()

    13. fig, ax = plt.subplots(1, figsize=(12,9))

    14. ax.imshow(img)

    15. pad_x = max(img.shape[0] - img.shape[1], 0) * (img_size / max(img.shape))

    16. pad_y = max(img.shape[1] - img.shape[0], 0) * (img_size / max(img.shape))

    17. unpad_h = img_size - pad_y

    18. unpad_w = img_size - pad_x

    19. if detections is not None:

    20. unique_labels = detections[:, -1].cpu().unique()

    21. n_cls_preds = len(unique_labels)

    22. bbox_colors = random.sample(colors, n_cls_preds)

    23. # browse detections and draw bounding boxes

    24. for x1, y1, x2, y2, conf, cls_conf, cls_pred in detections:

    25. box_h = ((y2 - y1) / unpad_h) * img.shape[0]

    26. box_w = ((x2 - x1) / unpad_w) * img.shape[1]

    27. y1 = ((y1 - pad_y // 2) / unpad_h) * img.shape[0]

    28. x1 = ((x1 - pad_x // 2) / unpad_w) * img.shape[1]

    29. color = bbox_colors[int(np.where(

    30. unique_labels == int(cls_pred))[0])]

    31. bbox = patches.Rectangle((x1, y1), box_w, box_h,

    32. linewidth=2, edgecolor=color, facecolor='none')

    33. ax.add_patch(bbox)

    34. plt.text(x1, y1, s=classes[int(cls_pred)],

    35. color='white', verticalalignment='top',

    36. bbox={'color': color, 'pad': 0})

    37. plt.axis('off')

    38. # save image

    39. plt.savefig(img_path.replace(".jpg", "-det.jpg"),

    40. bbox_inches='tight', pad_inches=0.0)

    41. plt.show()

     

    下面是我们的一些检测结果:

     

     

     

     

     

     

    视频中的目标跟踪

    现在你知道了如何在图像中检测不同的物体。当你在一个视频中一帧一帧地看时,你会看到那些跟踪框在移动。但是如果这些视频帧中有多个对象,你如何知道一个帧中的对象是否与前一个帧中的对象相同?这被称为目标跟踪,它使用多次检测来识别一个特定的对象。

    有多种算法可以做到这一点,在本文中决定使用SORT(Simple Online and Realtime Tracking),它使用Kalman滤波器预测先前识别的目标的轨迹,并将其与新的检测结果进行匹配,非常方便且速度很快。

    现在开始编写代码,前3个代码段将与单幅图像检测中的代码段相同,因为它们处理的是在单帧上获得 YOLO 检测。差异在最后一部分出现,对于每个检测,我们调用 Sort 对象的 Update 函数,以获得对图像中对象的引用。因此,与前面示例中的常规检测(包括边界框的坐标和类预测)不同,我们将获得跟踪的对象,除了上面的参数,还包括一个对象 ID。并且需要使用OpenCV来读取视频并显示视频帧。

    
     
    
     

     

    1. videopath = 'video/interp.mp4'

    2. %pylab inline

    3. import cv2

    4. from IPython.display import clear_output

    5. cmap = plt.get_cmap('tab20b')

    6. colors = [cmap(i)[:3] for i in np.linspace(0, 1, 20)]

    7. # initialize Sort object and video capture

    8. from sort import *

    9. vid = cv2.VideoCapture(videopath)

    10. mot_tracker = Sort()

    11. #while(True):

    12. for ii in range(40):

    13. ret, frame = vid.read()

    14. frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    15. pilimg = Image.fromarray(frame)

    16. detections = detect_image(pilimg)

    17. img = np.array(pilimg)

    18. pad_x = max(img.shape[0] - img.shape[1], 0) *

    19. (img_size / max(img.shape))

    20. pad_y = max(img.shape[1] - img.shape[0], 0) *

    21. (img_size / max(img.shape))

    22. unpad_h = img_size - pad_y

    23. unpad_w = img_size - pad_x

    24. if detections is not None:

    25. tracked_objects = mot_tracker.update(detections.cpu())

    26. unique_labels = detections[:, -1].cpu().unique()

    27. n_cls_preds = len(unique_labels)

    28. for x1, y1, x2, y2, obj_id, cls_pred in tracked_objects:

    29. box_h = int(((y2 - y1) / unpad_h) * img.shape[0])

    30. box_w = int(((x2 - x1) / unpad_w) * img.shape[1])

    31. y1 = int(((y1 - pad_y // 2) / unpad_h) * img.shape[0])

    32. x1 = int(((x1 - pad_x // 2) / unpad_w) * img.shape[1])

    33. color = colors[int(obj_id) % len(colors)]

    34. color = [i * 255 for i in color]

    35. cls = classes[int(cls_pred)]

    36. cv2.rectangle(frame, (x1, y1), (x1+box_w, y1+box_h),

    37. color, 4)

    38. cv2.rectangle(frame, (x1, y1-35), (x1+len(cls)*19+60,

    39. y1), color, -1)

    40. cv2.putText(frame, cls + "-" + str(int(obj_id)),

    41. (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX,

    42. 1, (255,255,255), 3)

    43. fig=figure(figsize=(12, 8))

    44. title("Video Stream")

    45. imshow(frame)

    46. show()

    47. clear_output(wait=True)

    PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

    python免费学习资料以及群交流解答点击即可加入

    下面让我们来看一下处理的结果:

    展开全文
  • 深度学习Pytorch实现的CenterNet目标检测图像处理要点 图片调整大小: resized_image = cv2.resize(image, (new_width, new_height)) 图片归一化: inp_image = ((inp_image / 255. - self.mean) / self.std...

    深度学习Pytorch实现的CenterNet目标检测图像处理要点

    图片调整大小:

    resized_image = cv2.resize(image, (new_width, new_height))

     

    图片归一化:

    inp_image = ((inp_image / 255. - self.mean) / self.std).astype(np.float32)
    
    images = inp_image.transpose(2, 0, 1).reshape(1, 3, inp_height, inp_width)

     

    其中标准化和均值
     

    self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
    self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)
    展开全文
  • resnet图像分类pytorch实现

    千次阅读 2019-12-22 20:32:34
    resnet图像分类pytorch实现 必要说明 此程序为本人以学习pytorch为目的写的第一个练习程序。 在Ubuntu16.04.5的服务器上。 pytorch版本为0.4.1。 数据集是AI_challenger大赛2018年农作物病虫害检测赛道的数据集,...
  • fpn.pytorch用于对象检测的功能金字塔网络(FPN)的Pytorch实现简介此项目继承了我们的r-cnn更快的pytorch实现的属性。 因此,它还具有以下特征专长fpn.pytorch:用于对象检测的功能金字塔网络(FPN)的Pytorch实现...
  • Repo for most of CV problems, such as image classification, object detection, pose estimation, segmentation, and so on.
  • DeepForest模型的pytorch实现,用于RGB图像中的单个树冠检测。 DeepForest是一个Python软件包,用于从机载RGB图像中训练和预测单个树冠。 DeepForest带有一个预先构建的模型,该模型是根据国家生态观测站网络的数据...
  • Pytorch实现ResNet

    2021-04-17 15:00:55
    Pytorch实现ResNet 一、ResNet网络介绍 ResNet在2015年被提出,在ImageNet比赛classification任务上获得第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。由于它“简单与实用”并存,...
  • 该项目是检测跟踪和跟踪检测pytorch实现。 该存储库受以下实现的影响: ,基于Pytorch ,基于Pycaffe + Numpy ,基于Pytorch + Numpy ,基于TensorFlow + Numpy ,Pytorch + TensorFlow + numpy 在我们的实现过程...
  • 目录 摘要 导入所需的库 下载数据集并解压缩 设置下载数据集的目录 下载数据集并解压 ...切分训练集、验证集和测试集 ...定义一个可视化图像及其标签的函数 ...定义一个PyTorch数据集... 任务是检测图像是否包含猫或狗。 .
  • pytorch实现交叉验证

    2020-12-21 20:19:43
    pytorch实现交叉验证 一般的交叉验证是对神经网络回归分类的代码 我这里是针对图像分类来的,对于目标检测这些的话,把对应读取数据的函数修改一下就行了 实现交叉验证的Dataset import torch import torch.nn as nn...
  • 目标检测算法SSD-detector(pytorch实现) 一批图像输入SSD深度神经网络之后,输出的是预测的bboxes的偏移量和每一个类别的置信度,需要对这些输出进行处理才能得到最终的预测结果。 对每一张图片的预测值分别进行...
  • 预处理:在pano.py和pano_lsd_align.py中,将线段检测器的实现和全景图像对齐方式从matlab转换为python。 后处理:没有3D布局优化。 或者,此回购协议可实现优化相似损失的梯度上升。 (有关更多详细信息,请参见...
  • yolo是图像检测领域最常用的框架,关于yolo的知识点相信有很多优秀的讲解,今天我们就来聊一下基于pytorch实现yolo。 项目框架 首先,一个完整的yolo系列至少包含了几个部分 cfg 文件: 用于记录网络的结构,包括...
  • 该文件是对Superpoint模型的pytorch实现和评估,如。 我们在RémiPautrat的tensorflow实现中找到了很大的帮助: : 。 在兴趣点检测中,我们的模型似乎未完全收敛: 但是,同形加法与我们的模型相结合的结果看...
  • 本人在读研期间的研究方向是图像处理以及深度学习(主要是图像分类和目标检测)。在做深度学习时使用的是tensorflow深度学习框架,学习全是自学,很多资源都是在Github上找的。我发现现在Github上很多深度学习的开源...
  • 原始存储库中的代码已被重写为PyTorch 1.4.0实现。 最困难的部分是重写从高分辨率图像中提取补丁的功能。 原始版本为此使用了特殊的C / C ++文件,我已经在本地Python中完成了此操作。 由于可能需要嵌套的for循环,...
  • pytorch实现线性回归 1. 实现线性回归前的准备 线性回归输出是一个连续值,因此适用于回归问题。回归问题在实际中很常见,如预测房屋价格、气温、销售额等连续值的问题。 与回归问题不同,分类问题中模型的最终输出...
  • 本文基于YOLOv4的PyTorch实现: 特征 基于YOLOv4的实时3D对象检测 支持 张量板 镶嵌/切口增强训练 使用旋转框的损失进行优化。 更新2020.08.26 : 更快的训练,更快的推理 无锚的方法 无需非最大抑制 示范(在GTX ...
  • pytorch实现mnist分类

    千次阅读 2018-05-30 21:57:01
    torchvision包 包含了目前流行的数据集,模型结构和常用的图片转换...COCO(用于图像标注和目标检测)(Captioning and Detection) LSUN Classification ImageFolder Imagenet-12 CIFAR10 and CIFAR100 STL10 ...
  • 1,首先下载yolov4模型文件 2,准备数据集 在下载好的yolov4文件夹的同级目录下创建projects/...train.txt和val.txt存放了训练集图像路径和验证集图像路径,二个txt文件下的内容均类似这样: 3,修改配置文件 修改data
  • 构造一个输入图像X,如何设计卷积核K来检测图像中对角方向的边缘? 检测图像中物体的边缘,即找到像素变化的位置。 构造一个6*6大小由黑到白过渡的图像,0黑,1白。 代码: x=torch.zeros(6,6) for i in range(6): ...
  • COCO(用于图像标注和目标检测)(Captioning and Detection) LSUN Classification ImageFolder Imagenet-12 CIFAR10 and CIFAR100 STL10 torchvision.models torchvision.models模块的 子模块中包含以下模型结构。 ...
  • RTM3D 是第一个用于单目图像 3D 检测的实时系统 (FPS>24),同时在 KITTI 基准测试中实现了最先进的性能。 KM3D 将几何约束重新制定为可微版本,并将其嵌入网络以减少运行时间,同时以端到端的方式保持模型输出的...
  • SegNet网络的Pytorch实现

    千次阅读 2019-05-23 15:46:00
    1.文章原文地址 SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation 2.文章摘要 语义分割具有非常广泛的...特别是最近的深度学习在手写数字识别、语音、图像中的分类和目标检测...
  • 论文的PyTorch实现: (ECCV 2020) 示范 特征 基于单眼RGB图像的实时3D对象检测 支持 张量板 RESNET基于ķeypoint˚Feature P yramidÑetwork(KFPN)(通过设置使用--arch fpn_resnet_18 ) 使用左右摄像机...
  • 基于3D LiDAR点云的超快速,准确的3D对象检测 特征 基于LiDAR的超快速,准确的3D对象检测 快速训练,快速推理 无锚的方法 没有非最大抑制 支持 发布预训练的模型 ... 对象数据集的左侧彩色图像(12
  • Contents0 摘要1 Intorduction2 基于空间金字塔池化的深度网络2.1 卷积层和特征图2.2 空间金字塔池化层2.3 训练网络3 用于图像分类的SPP-NET3.1 ImageNet 2012分类实验3.2 Experiments on VOC 2007 Classification...
  • 实现Pytorch中自动生成图像字幕的算法。 单发检测用于从图像中提取特征,这些特征将传递给LSTM进行字幕生成。 SSD实现的灵感来自杰里米·霍华德(Jeremy Howard)的深度学习第2部分。 single_object_pascal....

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 243
精华内容 97
关键字:

pytorch实现图像检测