您的位置:

探索Market1501——视觉监测领域的重要数据集

一、介绍Market1501

Market1501是一个用于人类重识别领域的数据集,由清华大学研究员李康等人在2015年发布。其由1501个行人的12936张图像组成,采集自天津市的市中心地区。每个行人都有至少2张图像,图像的摄像头视角和姿态也是多样的。Market1501提供了一个广泛的训练和测试的基础,可以用于开发和评估各种人类重识别算法。

Market1501数据集除了提供标注的图像数据外,还提供了行人身份、行人出现的日期和摄像头信息等元数据。这对于研究员和开发者来说是十分有用的,因为他们可以使用这些元数据来构建算法,帮助解决多摄像头和多日期的人类重识别问题。

下面是获取Market1501数据集的代码:

import os 
from torchvision.datasets.utils import download_url
from torchvision.datasets import VisionDataset
import pandas as pd
from PIL import Image 

class Market1501(VisionDataset):
    def __init__(self, root, transform=None, target_transform=None):
        
        super(Market1501, self).__init__(root, transform=transform,
                                         target_transform=target_transform)
        
        self.root = root
        self.img_folder_path = os.path.join(self.root, 'Market-1501', 'bounding_box_train')
        self.img_names = sorted(os.listdir(self.img_folder_path))
        self.targets = [int((img_name.split('_')[0])) for img_name in self.img_names]
        
    def __getitem__(self, index):
        
        img_name = self.img_names[index]
        img_path = os.path.join(self.img_folder_path, img_name)
        img = Image.open(img_path).convert('RGB')
        
        if self.transform is not None:
            img = self.transform(img)

        target = self.targets[index]

        if self.target_transform is not None:
            target = self.target_transform(target)

        return img, target

    def __len__(self):
        return len(self.img_names)

二、Market1501的挑战性问题

Market1501数据集被广泛应用于人类重识别领域,因为其中包含了多种挑战性问题。

1.视角变化问题

由于监测摄像头的位置和姿态是随机的,因此行人的外观和姿势会随着视角的变化而发生明显的变化。同一个行人在不同的摄像头下可能具有不同的行为和外观,这是人类重识别所需要突破的问题之一。

2.遮挡问题

由于人群密集或者周围环境等原因,行人可能会被其他物体或者人挡住。这会导致行人的可见程度降低,从而增加了人类重识别的复杂度。

3.光照变化问题

由于不同的摄像头可能在不同的时间和地点下拍摄,因此图像的光照情况也会有所不同,这会导致行人的外观发生明显的变化。这也是一个需要解决的问题。

三、Market1501以及人类重识别领域的研究趋势

Market1501数据集和人类重识别领域的研究目前已经发展到非常成熟的阶段。目前,研究者们已经提出了各种各样的特征提取和降维方法,比如基于卷积神经网络的深度学习方法,以及在特征层面或者空间层面进行注意力聚焦的注意力机制方法。

下面是一个使用ResNet50和注意力机制的人类重识别模型的示例。具体来说,该模型使用ResNet50作为特征提取器,然后使用自适应空间注意力层来聚焦于行人图像中的关键区域:

import torch.nn as nn
import torch.utils.model_zoo as model_zoo
import torch.nn.functional as F

__all__ = ['ResNet50_IBN_a', 'resnet50_ibn_a', 'init_pretrained_weights']

model_urls = {
    'resnet50_ibn_a': 'https://github.com/XingangPan/IBN-Net/releases/download/v1.0/resnet50_ibn_a-3c6afb43.pth',
}

class AdaAvgPool2d(nn.Module):
    def __init__(self):
        super(AdaAvgPool2d, self).__init__()

    def forward(self, x):
        return F.adaptive_avg_pool2d(x, 1).view(x.size(0), -1)

class Adaptive(nn.Module):
    def __init__(self, in_channels=2048, reduction_ratio=16):
        super(Adaptive, self).__init__()
        self.in_channels = in_channels
        self.reduction_ratio = reduction_ratio
        self.layers = nn.Sequential(
            nn.Conv2d(self.in_channels, self.in_channels // self.reduction_ratio, kernel_size=1, stride=1, padding=0),
            nn.ReLU(),
            nn.Conv2d(self.in_channels // self.reduction_ratio, self.in_channels, kernel_size=1, stride=1, padding=0),
            nn.Sigmoid()
        )

    def forward(self, x):
        y = F.avg_pool2d(x, kernel_size=x.size()[2:])
        y = self.layers(y)
        return x * y

class ResNet_IBN_a(nn.Module):
    def __init__(self, last_stride=2):
        self.inplanes = 64
        super(ResNet_IBN_a, self).__init__()

        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 = self._make_layer(block=Bottleneck_IBN_A, planes=64, blocks=3, stride=1, norm_layer=nn.BatchNorm2d)
        self.layer2 = self._make_layer(block=Bottleneck_IBN_A, planes=128, blocks=4, stride=2, norm_layer=nn.BatchNorm2d)
        self.layer3 = self._make_layer(block=Bottleneck_IBN_A, planes=256, blocks=6, stride=2, norm_layer=nn.BatchNorm2d)
        self.layer4 = self._make_layer(block=Bottleneck_IBN_A, planes=512, blocks=3, stride=last_stride, norm_layer=nn.BatchNorm2d)
        self.global_avgpool = AdaAvgPool2d()
        self.reid = nn.Sequential(
            nn.Linear(self.inplanes, 256),
            nn.BatchNorm1d(256),
            nn.ReLU(),
            nn.Linear(256, 256),
            nn.BatchNorm1d(256)
        )
        self.classifier = nn.Linear(256, 751)
        self.adaptive = Adaptive()

    def _make_layer(self, block, planes, blocks, stride=1, norm_layer=None):
        if norm_layer is None:
            norm_layer = nn.BatchNorm2d
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * block.expansion, stride),
                nn.BatchNorm2d(planes * block.expansion),
            )

        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample, norm_layer))
        self.inplanes = planes * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.inplanes, planes, norm_layer=norm_layer))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.adaptive(x)
        x = self.global_avgpool(x)
        x = self.reid(x)
        x = self.classifier(x)
        return x

def init_pretrained_weights(model, key=''):
    pretrain_dict = model_zoo.load_url(model_urls[key])
    model_dict = {}

    state_dict = model.state_dict()
    for k, v in pretrain_dict.items():
        if k in state_dict and state_dict[k].shape == v.shape:
            model_dict[k] = v
    state_dict.update(model_dict)
    model.load_state_dict(state_dict)

def resnet50_ibn_a(**kwargs):
    model = ResNet_IBN_a(**kwargs)
    init_pretrained_weights(model, 'resnet50_ibn_a')
    return model

四、Market1501的开发者社区

在人类重识别领域,Market1501已经成为了一个十分重要的数据集。因此,市面上涌现了很多以Market1501为基础的算法和研究方向。同时,由于其开源的特性,很多开源社区也涌现出来,提供各种各样的解决方案和创新性的想法。

下面是一个专门针对人类重识别领域的开源社区,该社区提供从数据预处理到算法实现等各个方面的支持:

https://github.com/michuanhaohao/reid-strong-baseline

五、总结

本文详细介绍了人类重识别领域的重要数据集Market1501。通过对Market1501的介绍,我们了解了其提供的重要元数据以及其中包含的挑战性问题。同时,我们还介绍了当前人类重识别领域中的研究趋势和开发者社区,以及一个使用ResNet50和注意力机制的人类重识别模型实现示例。