Ensembles de données couramment utilisés et idées de traitement dans la segmentation d'images (y compris le code)
- Ensembles de données couramment utilisés
- Voici un ensemble de codes universels pour votre référence. Voici le code :
-
- Importez d’abord les modules dont nous avons besoin
- La deuxième pièce est un peu inutile, vous pouvez simplement sauter cette étape.
- Prenons l'exemple de ADE20K. Tout d'abord, vous devez réécrire le jeu de données. C'est une étape très importante pour utiliser votre propre jeu de données.
- Voici une autre façon de traiter les étiquettes à l’aide du mappage de hachage, qui peut être plus rapide et est utilisée pour les étiquettes colorées :
Ensembles de données couramment utilisés
1.1 Paysages urbains
La scène routière contient 2 975 images d'entraînement, 500 images de vérification et 1 525 images de test réparties en 30 catégories. Au total, 5 000 images
se concentrent sur la compréhension sémantique des scènes de rue urbaines. Elles conviennent à une variété de tâches visuelles. Les données proviennent de plus de 50 villes, plusieurs saisons et du beau temps pendant la journée.Conditions
Sélection manuelle des images,
5 000 normes précises pour divers arrière-plans, 20 000 normes approximatives
sota
Segmentation régulière
Segmentation en temps réel
1.2 CamVidéo
Il s'agit de la première collection de vidéos avec des balises sémantiques et comprend des métadonnées. La base de données contient un total de 32 catégories.
sota
Algorithme de segmentation conventionnel
Algorithme de segmentation en temps réel
1.3 ADE20K
ADE20k comprend plus de 27 000 images, couvrant plus de 3 000 catégories d'objets, et la version actuelle de l'ensemble de données contient :
27 574 images (25 574 pour la formation et 2 000 pour la validation), couvrant 365 scènes différentes.
sota
1.4 PASCAL COV 2012
Cet ensemble de données contient 20 catégories d'objets. Chaque image de cet ensemble de données comporte des annotations de segmentation au niveau des pixels, des annotations de cadre de délimitation et des annotations d'objets. Cet ensemble de données a été largement utilisé pour les tâches de détection d'objets, de segmentation sémantique et de classification.
sota
1.5 Trucs COCO
Cet ensemble de données est utilisé pour des tâches de compréhension de scène telles que la segmentation sémantique, la détection d'objets et le sous-titrage d'images. Il y a 164 000 images dans cet ensemble de données, couvrant 172 catégories.
sota
1.6 SOLEIL RVB
Les images et les informations de profondeur sont collectées via quatre caméras 3D. Les quatre caméras contiennent des capteurs de couleur, des émetteurs infrarouges et des récepteurs infrarouges. Le capteur de couleur obtient des informations RVB, et l'émetteur infrarouge et le récepteur infrarouge obtiennent des informations de profondeur. Contient 10 335 images RVB-D réelles de scènes de pièce. Chaque image RVB possède une carte de profondeur et de segmentation correspondante. Il existe jusqu'à 700 catégories d'objets étiquetées. L'ensemble d'entraînement et l'ensemble de test contiennent respectivement 5 285 et 5 050 images.
1.7 NYUDv2
Composé de séquences vidéo de diverses scènes d'intérieur, enregistrées avec des caméras RVB et profondeur de Microsoft Kinect, il présente :
- 1449 images RVB et profondeur alignées de manière dense
- 464 nouvelles scènes de 3 villes
- 407024 nouveaux cadres non étiquetés
- Chaque objet est étiqueté avec une classe et un numéro d'instance
Voici un ensemble de codes universels pour votre référence. Voici le code :
Importez d’abord les modules dont nous avons besoin
import os
import torch
import torch.utils.data as data
from PIL import Image
import torchvision.transforms.functional as F
import torchvision.transforms as transforms
import albumentations as A
import numpy as np
import random
Parmi elles albumentations
se trouve la bibliothèque d'amélioration des données. Dans la tâche de détection et de segmentation, cette bibliothèque d'amélioration d'image est plus rapide que les autres bibliothèques. Il y aura un article sur l'amélioration des données plus tard.
La deuxième pièce est un peu inutile, vous pouvez simplement sauter cette étape.
class ExtRandomCrop(object):
def __init__(self, size, pad_if_needed=True):
self.size = size
self.pad_if_needed = pad_if_needed
@staticmethod
def get_params(img, output_size):
"""Get parameters for ``crop`` for a random crop.
Args:
img (PIL Image): Image to be cropped.
output_size (tuple): Expected output size of the crop.
Returns:
tuple: params (i, j, h, w) to be passed to ``crop`` for random crop.
"""
w, h = img.size
th, tw = output_size
if w == tw and h == th:
return 0, 0, h, w
i = random.randint(0, h - th)
j = random.randint(0, w - tw)
return i, j, th, tw
def crop(self, img, lbl):
"""
Args:
img (PIL Image): Image to be cropped.
lbl (PIL Image): Label to be cropped.
Returns:
PIL Image: Cropped image.
PIL Image: Cropped label.
"""
assert img.size == lbl.size, 'size of img and lbl should be the same. %s, %s' % (
img.size, lbl.size)
# pad the width if needed
if self.pad_if_needed and img.size[0] < self.size[1]:
img = F.pad(img, padding=int((1 + self.size[1] - img.size[0]) / 2))
lbl = F.pad(lbl, padding=int((1 + self.size[1] - lbl.size[0]) / 2))
# pad the height if needed
if self.pad_if_needed and img.size[1] < self.size[0]:
img = F.pad(img, padding=int((1 + self.size[0] - img.size[1]) / 2))
lbl = F.pad(lbl, padding=int((1 + self.size[0] - lbl.size[1]) / 2))
i, j, h, w = self.get_params(img, self.size)
return F.crop(img, i, j, h, w), F.crop(lbl, i, j, h, w)
Prenons l'exemple de ADE20K. Tout d'abord, vous devez réécrire le jeu de données. C'est une étape très importante pour utiliser votre propre jeu de données.
class ADE20K(data.Dataset)
fonction d'initialisation
def __init__(self, root, mode='train', crop_size=(512, 512)):
self.root = root
self.crop_size = crop_size
self.random_crop = ExtRandomCrop(self.crop_size, pad_if_needed=True)
if mode == 'train':
self.mode = mode + 'ing'
elif mode == 'val':
self.mode = mode + 'idation'
self.images, self.mask = self.read_file(self.root, self.mode)
self.crop_size = crop_size
fonction pour lire le fichier
def read_file(self, path, mode):
image_path = os.path.join(path, "images", mode)
mask_path = os.path.join(path, "annotations", mode)
image_files_list = os.listdir(image_path)
mask_files_list = os.listdir(mask_path)
image_list = [os.path.join(image_path, img) for img in image_files_list]
mask_list = [os.path.join(mask_path, mask) for mask in mask_files_list]
image_list.sort()
mask_list.sort()
return image_list, mask_list
Fonctions pour le traitement des données
def transform(self, image, mask):
image = np.array(image)
mask = np.array(mask)
trans = A.Compose([
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.OneOf([
A.MotionBlur(p=0.5), # 使用随机大小的内核将运动模糊应用于输入图像。
A.MedianBlur(blur_limit=3, p=0.5), # 中值滤波
A.Blur(blur_limit=3, p=0.2), # 使用随机大小的内核模糊输入图像。
], p=1),
A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.5),
# 随机应用仿射变换:平移,缩放和旋转输入
A.RandomBrightnessContrast(p=0.5), # 随机明亮对比度
])
trans_results = trans(image=image, mask=mask)
return trans_results
Ensuite, il y a getitem et len
def __len__(self):
return len(self.images)
def __getitem__(self, index):
image = Image.open(self.images[index]).convert('RGB')
mask = Image.open(self.mask[index])
image, mask = self.random_crop.crop(image, mask)
mask = np.array(mask)
if self.mode == "train":
trans_results = self.transform(image, mask)
image = trans_results['image']
mask = trans_results['mask']
transform_img = transforms.Compose(
[
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]
)
image = transform_img(image)
mask = torch.from_numpy(mask)
return image, mask
Voici une autre façon de traiter les étiquettes à l’aide du mappage de hachage, qui peut être plus rapide et est utilisée pour les étiquettes colorées :
class LabelProcessor:
def __init__(self, file_path):
self.colormap = self.read_color_map(file_path)
self.cm2lbl = self.encode_label_pix(self.colormap)
@staticmethod
def read_color_map(file_path):
pd_label_color = pd.read_csv(file_path, sep=',')
colormap = []
for i in range(len(pd_label_color.index)):
tmp = pd_label_color.iloc[i]
color = [tmp['r'], tmp['g'], tmp['b']]
colormap.append(color)
return colormap
@staticmethod
def encode_label_pix(colormap):
cm2lbl = np.zeros(256 ** 3)
for i, cm in enumerate(colormap):
cm2lbl[(cm[0] * 256 + cm[1]) * 256 + cm[2]] = i
return cm2lbl
def encode_label_img(self, img):
data = np.array(img, dtype='int32')
idx = (data[:, :, 0] * 256 + data[:, :, 1]) * 256 + data[:, :, 2]
return np.array(self.cm2lbl[idx], dtype='int64')