Upload 5 files
Browse files- detection.py +157 -0
- image_processing.py +27 -0
- notacion.py +30 -0
- utils.py +118 -0
- yolo_classes.txt +80 -0
detection.py
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from ultralytics import YOLOv10
|
| 3 |
+
import os
|
| 4 |
+
import torch
|
| 5 |
+
|
| 6 |
+
def yolov10_inference(image, model_id, image_size, conf_threshold):
|
| 7 |
+
model = YOLOv10.from_pretrained(f'jameslahm/{model_id}')
|
| 8 |
+
results = model.predict(source=image, imgsz=image_size, conf=conf_threshold)
|
| 9 |
+
detections = []
|
| 10 |
+
if results and len(results) > 0:
|
| 11 |
+
for result in results:
|
| 12 |
+
for box in result.boxes:
|
| 13 |
+
detections.append({
|
| 14 |
+
"coords": box.xyxy.cpu().numpy(),
|
| 15 |
+
"class": result.names[int(box.cls.cpu())],
|
| 16 |
+
"conf": box.conf.cpu().numpy()
|
| 17 |
+
#"bbox": box.xyxy.cpu().numpy().tolist()
|
| 18 |
+
})
|
| 19 |
+
return results[0].plot() if results and len(results) > 0 else image, detections
|
| 20 |
+
|
| 21 |
+
def calculate_iou(boxA, boxB):
|
| 22 |
+
xA = max(boxA[0], boxB[0])
|
| 23 |
+
yA = max(boxA[1], boxB[1])
|
| 24 |
+
xB = min(boxA[2], boxB[2])
|
| 25 |
+
yB = min(boxA[3], boxB[3])
|
| 26 |
+
interArea = max(0, xB - xA) * max(0, yB - yA)
|
| 27 |
+
boxAArea = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1])
|
| 28 |
+
boxBArea = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1])
|
| 29 |
+
iou = interArea / float(boxAArea + boxBArea - interArea)
|
| 30 |
+
return iou
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def calculate_detection_metrics(detections_true, detections_pred):
|
| 35 |
+
true_positives = 0
|
| 36 |
+
pred_positives = len(detections_pred)
|
| 37 |
+
real_positives = len(detections_true)
|
| 38 |
+
ious = []
|
| 39 |
+
for pred in detections_pred:
|
| 40 |
+
for real in detections_true:
|
| 41 |
+
if pred['class'] == real['class']:
|
| 42 |
+
iou = calculate_iou(pred['coords'].flatten(), real['coords'].flatten())
|
| 43 |
+
if iou >= 0.5:
|
| 44 |
+
true_positives += 1
|
| 45 |
+
ious.append(iou)
|
| 46 |
+
break
|
| 47 |
+
precision = true_positives / pred_positives if pred_positives > 0 else 0
|
| 48 |
+
recall = true_positives / real_positives if real_positives > 0 else 0
|
| 49 |
+
f1_score = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
|
| 50 |
+
average_iou = sum(ious) / len(ious) if ious else 0
|
| 51 |
+
return {"Precision": precision, "Recall": recall, "F1-Score": f1_score, "IOU": average_iou}
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def read_kitti_annotations(file_path):
|
| 57 |
+
ground_truths = []
|
| 58 |
+
with open(file_path, 'r') as file:
|
| 59 |
+
for line in file:
|
| 60 |
+
parts = line.strip().split()
|
| 61 |
+
if parts[0] != 'DontCare': # Ignorar 'DontCare'
|
| 62 |
+
class_label = parts[0].lower() # Clase en minúscula
|
| 63 |
+
bbox = [float(parts[4]), float(parts[5]), float(parts[6]), float(parts[7])]
|
| 64 |
+
ground_truths.append({'class': class_label, 'bbox': bbox})
|
| 65 |
+
return ground_truths
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def save_detections(detections, output_dir, filename='detections.txt'):
|
| 69 |
+
if not os.path.exists(output_dir):
|
| 70 |
+
os.makedirs(output_dir)
|
| 71 |
+
with open(os.path.join(output_dir, filename), 'w') as file:
|
| 72 |
+
for detection in detections:
|
| 73 |
+
class_label = detection['class']
|
| 74 |
+
bbox = ','.join(map(str, detection['bbox']))
|
| 75 |
+
file.write(f"{class_label},[{bbox}]\n")
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def yolov10_inference_1(image, model_id, image_size, conf_threshold):
|
| 92 |
+
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
| 93 |
+
model = YOLOv10.from_pretrained(f'jameslahm/{model_id}').to(device)
|
| 94 |
+
results = model.predict(source=image, imgsz=image_size, conf=conf_threshold)
|
| 95 |
+
detections = []
|
| 96 |
+
if results and len(results) > 0:
|
| 97 |
+
for result in results:
|
| 98 |
+
for box in result.boxes:
|
| 99 |
+
detections.append({
|
| 100 |
+
#"coords": box.xyxy.cpu().numpy(),
|
| 101 |
+
"class": result.names[int(box.cls.cpu())],
|
| 102 |
+
#"conf": box.conf.cpu().numpy()
|
| 103 |
+
|
| 104 |
+
"bbox": box.xyxy.cpu().numpy().tolist()
|
| 105 |
+
})
|
| 106 |
+
return results[0].plot() if results and len(results) > 0 else image, detections
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def calculate_iou_1(boxA, boxB):
|
| 110 |
+
# Asegúrate de que boxA y boxB son listas planas de flotantes
|
| 111 |
+
# Esto es necesario porque la función max() y min() requieren comparar elementos directamente
|
| 112 |
+
boxA = [float(num) for sublist in boxA for num in sublist] if isinstance(boxA[0], list) else [float(num) for num in boxA]
|
| 113 |
+
boxB = [float(num) for sublist in boxB for num in sublist] if isinstance(boxB[0], list) else [float(num) for num in boxB]
|
| 114 |
+
|
| 115 |
+
# Determina las coordenadas de la intersección
|
| 116 |
+
xA = max(boxA[0], boxB[0])
|
| 117 |
+
yA = max(boxA[1], boxB[1])
|
| 118 |
+
xB = min(boxA[2], boxB[2])
|
| 119 |
+
yB = min(boxA[3], boxB[3])
|
| 120 |
+
|
| 121 |
+
# Calcula el área de la intersección
|
| 122 |
+
interArea = max(0, xB - xA) * max(0, yB - yA)
|
| 123 |
+
|
| 124 |
+
# Calcula el área de cada cuadro delimitador y la unión
|
| 125 |
+
boxAArea = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1])
|
| 126 |
+
boxBArea = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1])
|
| 127 |
+
unionArea = boxAArea + boxBArea - interArea
|
| 128 |
+
|
| 129 |
+
# Calcula el IoU
|
| 130 |
+
iou = interArea / float(unionArea)
|
| 131 |
+
return iou
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def calculate_detection_metrics_1(detections_true, detections_pred):
|
| 135 |
+
true_positives = 0
|
| 136 |
+
pred_positives = len(detections_pred)
|
| 137 |
+
real_positives = len(detections_true)
|
| 138 |
+
ious = []
|
| 139 |
+
for pred in detections_pred:
|
| 140 |
+
pred_bbox = pred['bbox']
|
| 141 |
+
pred_class = pred['class']
|
| 142 |
+
for real in detections_true:
|
| 143 |
+
real_bbox = real['bbox']
|
| 144 |
+
real_class = real['class']
|
| 145 |
+
if pred_class == real_class:
|
| 146 |
+
iou = calculate_iou_1(pred_bbox, real_bbox)
|
| 147 |
+
if iou >= 0.5:
|
| 148 |
+
true_positives += 1
|
| 149 |
+
ious.append(iou)
|
| 150 |
+
break
|
| 151 |
+
precision = true_positives / pred_positives if pred_positives > 0 else 0
|
| 152 |
+
recall = true_positives / real_positives if real_positives > 0 else 0
|
| 153 |
+
f1_score = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
|
| 154 |
+
average_iou = sum(ious) / len(ious) if ious else 0
|
| 155 |
+
return {"Precision": precision, "Recall": recall, "F1-Score": f1_score, "IOU": average_iou}
|
| 156 |
+
|
| 157 |
+
|
image_processing.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import cv2
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
def modulo(x, L):
|
| 6 |
+
positive = x > 0
|
| 7 |
+
x = x % L
|
| 8 |
+
x = np.where( ( x == 0) & positive, L, x)
|
| 9 |
+
return x
|
| 10 |
+
|
| 11 |
+
def apply_blur(image, kernel_size):
|
| 12 |
+
"""Aplica desenfoque gaussiano a la imagen."""
|
| 13 |
+
return cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)
|
| 14 |
+
|
| 15 |
+
def clip_image(image, correction, sat_factor):
|
| 16 |
+
"""Clips image with saturation factor and correction."""
|
| 17 |
+
processed_image = np.power(image, correction) * sat_factor
|
| 18 |
+
clipped_image = np.clip(processed_image, 0, 1)
|
| 19 |
+
return clipped_image
|
| 20 |
+
|
| 21 |
+
def wrap_image(image, correction, sat_factor):
|
| 22 |
+
"""Wraps image with saturation factor and correction."""
|
| 23 |
+
processed_image = np.power(image, 1.0) * sat_factor
|
| 24 |
+
wrapped_image = modulo(processed_image, 1.0)
|
| 25 |
+
return wrapped_image
|
| 26 |
+
|
| 27 |
+
|
notacion.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
from PIL import Image
|
| 3 |
+
import torch
|
| 4 |
+
from torchvision import transforms
|
| 5 |
+
|
| 6 |
+
# Mapeo de clases de YOLOv10 a las clases de tu base de datos
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def map_yolo_classes_to_db(yolo_detections):
|
| 10 |
+
"""
|
| 11 |
+
Ajusta las clases detectadas por YOLO a las clases de la base de datos según el mapeo proporcionado.
|
| 12 |
+
"""
|
| 13 |
+
mapping = {
|
| 14 |
+
'person': 'pedestrian',
|
| 15 |
+
'bicycle': 'cyclist',
|
| 16 |
+
'car': 'car',
|
| 17 |
+
'motorbike': 'cisc',
|
| 18 |
+
'aeroplane': 'cisc',
|
| 19 |
+
'bus': 'cisc',
|
| 20 |
+
'train': 'tram',
|
| 21 |
+
'truck': 'truck',
|
| 22 |
+
'van': 'van'
|
| 23 |
+
}
|
| 24 |
+
mapped_detections = []
|
| 25 |
+
for det in yolo_detections:
|
| 26 |
+
if det['class'] in mapping:
|
| 27 |
+
det['class'] = mapping[det['class']]
|
| 28 |
+
mapped_detections.append(det)
|
| 29 |
+
return mapped_detections
|
| 30 |
+
|
utils.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch_dct as dct
|
| 3 |
+
|
| 4 |
+
from torchvision.transforms import functional as F
|
| 5 |
+
|
| 6 |
+
def flip_odd_lines(matrix):
|
| 7 |
+
"""
|
| 8 |
+
Flip odd lines of a matrix
|
| 9 |
+
"""
|
| 10 |
+
matrix = matrix.clone()
|
| 11 |
+
|
| 12 |
+
matrix[..., 1::2, :] = matrix[..., 1::2, :].flip(-1)
|
| 13 |
+
|
| 14 |
+
return matrix
|
| 15 |
+
|
| 16 |
+
rotate = lambda m, r: torch.rot90(m, r, [-2, -1])
|
| 17 |
+
sequency_vec = lambda m: flip_odd_lines(rotate(m, 0)).flatten(start_dim= m.dim()-2)
|
| 18 |
+
sequency_mat = lambda v, s: rotate(flip_odd_lines(v.unflatten(-1, s)), 0)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def modulo(x, L):
|
| 22 |
+
positive = x > 0
|
| 23 |
+
x = x % L
|
| 24 |
+
x = torch.where( ( x == 0) & positive, L, x)
|
| 25 |
+
return x
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def center_modulo(x, L):
|
| 29 |
+
return modulo(x + L/2, L) - L/2
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def unmodulo(psi):
|
| 33 |
+
|
| 34 |
+
psi = torch.nn.functional.pad(psi, (1,1), mode='constant', value=0)
|
| 35 |
+
psi = torch.diff(psi, 1)
|
| 36 |
+
psi = dct.dct(psi, norm='ortho')
|
| 37 |
+
N = psi.shape[-1]
|
| 38 |
+
k = torch.arange(0, N)
|
| 39 |
+
denom = 2*( torch.cos( torch.pi * k / N ) - 1 )
|
| 40 |
+
denom[0] = 1.0
|
| 41 |
+
denom = denom.unsqueeze(0).unsqueeze(0) + 1e-7
|
| 42 |
+
psi = psi / denom
|
| 43 |
+
psi[..., 0] = 0.0
|
| 44 |
+
psi = dct.idct(psi, norm='ortho')
|
| 45 |
+
return psi
|
| 46 |
+
|
| 47 |
+
RD = lambda x, L: torch.round( x / L) * L
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def hard_thresholding(x, t):
|
| 51 |
+
return x * (torch.abs(x) > t)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def stripe_estimation(psi, t=0.15):
|
| 55 |
+
|
| 56 |
+
dx = torch.diff(psi, 1, dim=-1)
|
| 57 |
+
dy = torch.diff(psi, 1, dim=-2)
|
| 58 |
+
|
| 59 |
+
dx = hard_thresholding(dx, t)
|
| 60 |
+
dy = hard_thresholding(dy, t)
|
| 61 |
+
|
| 62 |
+
dx = F.pad(dx, (1, 0, 1, 0))
|
| 63 |
+
dy = F.pad(dy, (0, 1, 0, 1))
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
rho = torch.diff(dx, 1, dim=-1) + torch.diff(dy, 1, dim=-2)
|
| 67 |
+
dct_rho = dct.dct_2d(rho, norm='ortho')
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
MX = rho.shape[-2]
|
| 71 |
+
NX = rho.shape[-1]
|
| 72 |
+
|
| 73 |
+
I, J = torch.meshgrid(torch.arange(0, MX), torch.arange(0, NX), indexing="ij")
|
| 74 |
+
I = I.to(rho.device)
|
| 75 |
+
J = J.to(rho.device)
|
| 76 |
+
denom = 2 * (torch.cos(torch.pi * I / MX ) + torch.cos(torch.pi * J / NX ) - 2)
|
| 77 |
+
denom = denom.unsqueeze(0).unsqueeze(0)
|
| 78 |
+
denom = denom.to(rho.device)
|
| 79 |
+
dct_phi = dct_rho / denom
|
| 80 |
+
dct_phi[..., 0, 0] = 0
|
| 81 |
+
phi = dct.idct_2d(dct_phi, norm='ortho')
|
| 82 |
+
phi = phi - torch.min(phi)
|
| 83 |
+
# phi = phi - torch.amin(phi, dim=(-1, -2), keepdim=True)
|
| 84 |
+
# phi = RD(phi, 1.0)
|
| 85 |
+
return phi
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def recons(m_t, DO=1, L=1.0, vertical=False, t=0.3):
|
| 89 |
+
|
| 90 |
+
if vertical:
|
| 91 |
+
m_t = m_t.permute(0, 1, 3, 2)
|
| 92 |
+
|
| 93 |
+
shape = m_t.shape[-2:]
|
| 94 |
+
|
| 95 |
+
modulo_vec = sequency_vec(m_t)
|
| 96 |
+
res = center_modulo( torch.diff(modulo_vec, n=DO), L) - torch.diff(modulo_vec, n=DO)
|
| 97 |
+
bl = res
|
| 98 |
+
|
| 99 |
+
for i in range(DO):
|
| 100 |
+
bl = unmodulo(bl)
|
| 101 |
+
bl = RD(bl, L)
|
| 102 |
+
|
| 103 |
+
x_est = bl
|
| 104 |
+
|
| 105 |
+
x_est = sequency_mat(x_est, shape)
|
| 106 |
+
x_est = x_est + m_t
|
| 107 |
+
|
| 108 |
+
if vertical:
|
| 109 |
+
x_est = x_est.permute(0, 1, 3, 2)
|
| 110 |
+
|
| 111 |
+
stripes = stripe_estimation(x_est, t=t)
|
| 112 |
+
x_est = x_est - stripes
|
| 113 |
+
|
| 114 |
+
# if vertical:
|
| 115 |
+
# x_est = x_est.permute(0, 1, 3, 2)
|
| 116 |
+
x_est = x_est - x_est.min()
|
| 117 |
+
x_est = x_est / x_est.max()
|
| 118 |
+
return x_est
|
yolo_classes.txt
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
person
|
| 2 |
+
bicycle
|
| 3 |
+
car
|
| 4 |
+
motorbike
|
| 5 |
+
aeroplane
|
| 6 |
+
bus
|
| 7 |
+
train
|
| 8 |
+
truck
|
| 9 |
+
boat
|
| 10 |
+
traffic light
|
| 11 |
+
fire hydrant
|
| 12 |
+
stop sign
|
| 13 |
+
parking meter
|
| 14 |
+
bench
|
| 15 |
+
bird
|
| 16 |
+
cat
|
| 17 |
+
dog
|
| 18 |
+
horse
|
| 19 |
+
sheep
|
| 20 |
+
cow
|
| 21 |
+
elephant
|
| 22 |
+
bear
|
| 23 |
+
zebra
|
| 24 |
+
giraffe
|
| 25 |
+
backpack
|
| 26 |
+
umbrella
|
| 27 |
+
handbag
|
| 28 |
+
tie
|
| 29 |
+
suitcase
|
| 30 |
+
frisbee
|
| 31 |
+
skis
|
| 32 |
+
snowboard
|
| 33 |
+
sports ball
|
| 34 |
+
kite
|
| 35 |
+
baseball bat
|
| 36 |
+
baseball glove
|
| 37 |
+
skateboard
|
| 38 |
+
surfboard
|
| 39 |
+
tennis racket
|
| 40 |
+
bottle
|
| 41 |
+
wine glass
|
| 42 |
+
cup
|
| 43 |
+
fork
|
| 44 |
+
knife
|
| 45 |
+
spoon
|
| 46 |
+
bowl
|
| 47 |
+
banana
|
| 48 |
+
apple
|
| 49 |
+
sandwich
|
| 50 |
+
orange
|
| 51 |
+
broccoli
|
| 52 |
+
carrot
|
| 53 |
+
hot dog
|
| 54 |
+
pizza
|
| 55 |
+
donut
|
| 56 |
+
cake
|
| 57 |
+
chair
|
| 58 |
+
sofa
|
| 59 |
+
pottedplant
|
| 60 |
+
bed
|
| 61 |
+
diningtable
|
| 62 |
+
toilet
|
| 63 |
+
tvmonitor
|
| 64 |
+
laptop
|
| 65 |
+
mouse
|
| 66 |
+
remote
|
| 67 |
+
keyboard
|
| 68 |
+
cell phone
|
| 69 |
+
microwave
|
| 70 |
+
oven
|
| 71 |
+
toaster
|
| 72 |
+
sink
|
| 73 |
+
refrigerator
|
| 74 |
+
book
|
| 75 |
+
clock
|
| 76 |
+
vase
|
| 77 |
+
scissors
|
| 78 |
+
teddy bear
|
| 79 |
+
hair drier
|
| 80 |
+
toothbrush
|