18 객체 검출 (One-stage object detection)

  • SSD, YOLO
  • “부록3 매트플롯립 입문”에서 한글 폰트를 올바르게 출력하기 위한 설치 방법을 설명했다. 설치 방법은 다음과 같다.
!sudo apt-get install -y fonts-nanum* | tail -n 1
!sudo fc-cache -fv
!rm -rf ~/.cache/matplotlib
# 필요 라이브러리 설치
 
!pip install torchviz | tail -n 1
!pip install torchinfo | tail -n 1
# w = !apt install tree
# print(w[-2])
  • 모든 설치가 끝나면 한글 폰트를 바르게 출력하기 위해 [런타임] -> **[런타임 다시시작]**을 클릭한 다음, 아래 셀부터 코드를 실행해 주십시오.
# 라이브러리 임포트
 
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display
 
# 폰트 관련 용도
import matplotlib.font_manager as fm
 
# Colab, Linux
# 나눔 고딕 폰트의 경로 명시
path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf'
font_name = fm.FontProperties(fname=path, size=10).get_name()
 
# Window 
# font_name = "NanumBarunGothic"
 
# Mac
# font_name = "AppleGothic"
# warning 표시 끄기
import warnings
warnings.simplefilter('ignore')
 
import os
import numpy as np
import matplotlib.pyplot as plt
# 폰트 관련 용도
import matplotlib.font_manager as fm
import cv2
 
import torch
from torch import nn, optim
import torchvision.transforms.functional as F
from torch.utils.data import DataLoader
from torchvision.io import read_image
from torchvision import models, datasets, transforms
from torchinfo import summary
# 기본 폰트 설정
plt.rcParams['font.family'] = font_name
 
# 기본 폰트 사이즈 변경
plt.rcParams['font.size'] = 14
 
# 기본 그래프 사이즈 변경
plt.rcParams['figure.figsize'] = (6,6)
 
# 기본 그리드 표시
# 필요에 따라 설정할 때는, plt.grid()
plt.rcParams['axes.grid'] = True
plt.rcParams["grid.linestyle"] = ":"
 
# 마이너스 기호 정상 출력
plt.rcParams['axes.unicode_minus'] = False
 
# 넘파이 부동소수점 자릿수 표시
np.set_printoptions(suppress=True, precision=4)
# GPU 디바이스 할당
 
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
cuda:0

SSD 모델 사용하기

모델 불러 오기

## Pretrained object detection model list
dir(models.detection)
['FCOS',
 'FCOS_ResNet50_FPN_Weights',
 'FasterRCNN',
 'FasterRCNN_MobileNet_V3_Large_320_FPN_Weights',
 'FasterRCNN_MobileNet_V3_Large_FPN_Weights',
 'FasterRCNN_ResNet50_FPN_V2_Weights',
 'FasterRCNN_ResNet50_FPN_Weights',
 'KeypointRCNN',
 'KeypointRCNN_ResNet50_FPN_Weights',
 'MaskRCNN',
 'MaskRCNN_ResNet50_FPN_V2_Weights',
 'MaskRCNN_ResNet50_FPN_Weights',
 'RetinaNet',
 'RetinaNet_ResNet50_FPN_V2_Weights',
 'RetinaNet_ResNet50_FPN_Weights',
 'SSD300_VGG16_Weights',
 'SSDLite320_MobileNet_V3_Large_Weights',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 '_utils',
 'anchor_utils',
 'backbone_utils',
 'faster_rcnn',
 'fasterrcnn_mobilenet_v3_large_320_fpn',
 'fasterrcnn_mobilenet_v3_large_fpn',
 'fasterrcnn_resnet50_fpn',
 'fasterrcnn_resnet50_fpn_v2',
 'fcos',
 'fcos_resnet50_fpn',
 'generalized_rcnn',
 'image_list',
 'keypoint_rcnn',
 'keypointrcnn_resnet50_fpn',
 'mask_rcnn',
 'maskrcnn_resnet50_fpn',
 'maskrcnn_resnet50_fpn_v2',
 'retinanet',
 'retinanet_resnet50_fpn',
 'retinanet_resnet50_fpn_v2',
 'roi_heads',
 'rpn',
 'ssd',
 'ssd300_vgg16',
 'ssdlite',
 'ssdlite320_mobilenet_v3_large',
 'transform']
## load model
# from torchvision.models.detection import ssd300_vgg16 # input image 300x300, backbone vgg16
 
weights = models.detection.SSD300_VGG16_Weights.COCO_V1 # 2014
ssd300 = models.detection.ssd300_vgg16(weights = weights)
# weights.transforms()
 

모델 확인 하기

print(ssd300)
SSD(
  (backbone): SSDFeatureExtractorVGG(
    (features): Sequential(
      (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (1): ReLU(inplace=True)
      (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (3): ReLU(inplace=True)
      (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (6): ReLU(inplace=True)
      (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (8): ReLU(inplace=True)
      (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (11): ReLU(inplace=True)
      (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (13): ReLU(inplace=True)
      (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (15): ReLU(inplace=True)
      (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (18): ReLU(inplace=True)
      (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (20): ReLU(inplace=True)
      (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (22): ReLU(inplace=True)
    )
    (extra): ModuleList(
      (0): Sequential(
        (0): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
        (1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): ReLU(inplace=True)
        (3): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (4): ReLU(inplace=True)
        (5): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (6): ReLU(inplace=True)
        (7): Sequential(
          (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=False)
          (1): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(6, 6), dilation=(6, 6))
          (2): ReLU(inplace=True)
          (3): Conv2d(1024, 1024, kernel_size=(1, 1), stride=(1, 1))
          (4): ReLU(inplace=True)
        )
      )
      (1): Sequential(
        (0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))
        (1): ReLU(inplace=True)
        (2): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (3): ReLU(inplace=True)
      )
      (2): Sequential(
        (0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1))
        (1): ReLU(inplace=True)
        (2): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (3): ReLU(inplace=True)
      )
      (3-4): 2 x Sequential(
        (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
        (1): ReLU(inplace=True)
        (2): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1))
        (3): ReLU(inplace=True)
      )
    )
  )
  (anchor_generator): DefaultBoxGenerator(aspect_ratios=[[2], [2, 3], [2, 3], [2, 3], [2], [2]], clip=True, scales=[0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05], steps=[8, 16, 32, 64, 100, 300])
  (head): SSDHead(
    (classification_head): SSDClassificationHead(
      (module_list): ModuleList(
        (0): Conv2d(512, 364, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): Conv2d(1024, 546, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): Conv2d(512, 546, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (3): Conv2d(256, 546, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (4-5): 2 x Conv2d(256, 364, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
    )
    (regression_head): SSDRegressionHead(
      (module_list): ModuleList(
        (0): Conv2d(512, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): Conv2d(1024, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): Conv2d(512, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (3): Conv2d(256, 24, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (4-5): 2 x Conv2d(256, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
    )
  )
  (transform): GeneralizedRCNNTransform(
      Normalize(mean=[0.48235, 0.45882, 0.40784], std=[0.00392156862745098, 0.00392156862745098, 0.00392156862745098])
      Resize(min_size=(300,), max_size=300, mode='bilinear')
  )
)
summary(ssd300, (1, 3, 300, 300))
==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
SSD                                      [97, 4]                   --
├─GeneralizedRCNNTransform: 1-1          [1, 3, 300, 300]          --
├─SSDFeatureExtractorVGG: 1-2            [1, 256, 1, 1]            512
│    └─Sequential: 2-1                   [1, 512, 38, 38]          --
│    │    └─Conv2d: 3-1                  [1, 64, 300, 300]         (1,792)
│    │    └─ReLU: 3-2                    [1, 64, 300, 300]         --
│    │    └─Conv2d: 3-3                  [1, 64, 300, 300]         (36,928)
│    │    └─ReLU: 3-4                    [1, 64, 300, 300]         --
│    │    └─MaxPool2d: 3-5               [1, 64, 150, 150]         --
│    │    └─Conv2d: 3-6                  [1, 128, 150, 150]        73,856
│    │    └─ReLU: 3-7                    [1, 128, 150, 150]        --
│    │    └─Conv2d: 3-8                  [1, 128, 150, 150]        147,584
│    │    └─ReLU: 3-9                    [1, 128, 150, 150]        --
│    │    └─MaxPool2d: 3-10              [1, 128, 75, 75]          --
│    │    └─Conv2d: 3-11                 [1, 256, 75, 75]          295,168
│    │    └─ReLU: 3-12                   [1, 256, 75, 75]          --
│    │    └─Conv2d: 3-13                 [1, 256, 75, 75]          590,080
│    │    └─ReLU: 3-14                   [1, 256, 75, 75]          --
│    │    └─Conv2d: 3-15                 [1, 256, 75, 75]          590,080
│    │    └─ReLU: 3-16                   [1, 256, 75, 75]          --
│    │    └─MaxPool2d: 3-17              [1, 256, 38, 38]          --
│    │    └─Conv2d: 3-18                 [1, 512, 38, 38]          1,180,160
│    │    └─ReLU: 3-19                   [1, 512, 38, 38]          --
│    │    └─Conv2d: 3-20                 [1, 512, 38, 38]          2,359,808
│    │    └─ReLU: 3-21                   [1, 512, 38, 38]          --
│    │    └─Conv2d: 3-22                 [1, 512, 38, 38]          2,359,808
│    │    └─ReLU: 3-23                   [1, 512, 38, 38]          --
│    └─ModuleList: 2-2                   --                        --
│    │    └─Sequential: 3-24             [1, 1024, 19, 19]         12,848,640
│    │    └─Sequential: 3-25             [1, 512, 10, 10]          1,442,560
│    │    └─Sequential: 3-26             [1, 256, 5, 5]            360,832
│    │    └─Sequential: 3-27             [1, 256, 3, 3]            328,064
│    │    └─Sequential: 3-28             [1, 256, 1, 1]            328,064
├─SSDHead: 1-3                           [1, 8732, 91]             --
│    └─SSDRegressionHead: 2-3            [1, 8732, 4]              --
│    │    └─ModuleList: 3-29             --                        534,648
│    └─SSDClassificationHead: 2-4        [1, 8732, 91]             --
│    │    └─ModuleList: 3-30             --                        12,163,242
├─DefaultBoxGenerator: 1-4               [8732, 4]                 --
==========================================================================================
Total params: 35,641,826
Trainable params: 35,603,106
Non-trainable params: 38,720
Total mult-adds (G): 34.88
==========================================================================================
Input size (MB): 1.08
Forward/backward pass size (MB): 208.89
Params size (MB): 142.57
Estimated Total Size (MB): 352.53
==========================================================================================

데이터 준비

## Image preprocessing
transform = transforms.Compose([
    transforms.Resize((300, 300)),
    transforms.ToTensor()
])
 
# transform = transforms.Compose([
#     transforms.Resize((300, 300)),
#     transforms.ToTensor(),
#     transforms.Normalize(
#         mean=[0.48235, 0.45882, 0.40784],  # Mean values for COCO (normalized to [0, 1])
#         std=[0.00392156862745098, 0.00392156862745098, 0.00392156862745098]  # Scale pixel values to [0, 1]
#     )
# ])
# VOCDetection 데이터셋 불러오기
dataset = datasets.VOCDetection(root = "./VOC_dataset/VOC2012", 
                                year = "2012",
                                image_set = "val", # Use "train", "val", or "trainval"
                                download=True,
                                transform = transform # Apply preprocessing pipeline
                                )  
 
# data_loader = DataLoader(dataset, batch_size=1, shuffle=False)
Using downloaded and verified file: ./VOC_dataset/VOC2012\VOCtrainval_11-May-2012.tar
Extracting ./VOC_dataset/VOC2012\VOCtrainval_11-May-2012.tar to ./VOC_dataset/VOC2012

입력 영상 확인하기

idx = torch.randint(len(dataset), size = (1, ))
image, annotation = dataset[idx.item()]
 
 
plt.imshow(image.permute(1, 2, 0))
plt.grid(None)
plt.axis("off")
plt.show()

png

모델 예측

import time
 
idx = torch.randint(len(dataset), size = (1, ))
image_jpg, annotation = dataset[idx.item()]
image = image_jpg.unsqueeze(0).to(device)
 
ssd300.eval()
start = time.time()
with torch.no_grad():
    prediction = ssd300(image)
stop = time.time()
print(f"estimation time = {(stop - start)*1000:.3f}ms")
prediction = prediction[0] # batch remove
prediction
estimation time = 185.503ms





{'boxes': tensor([[1.1262e+02, 6.5100e+01, 2.1513e+02, 1.8358e+02],
         [8.8847e+01, 6.2713e+01, 2.4138e+02, 2.5318e+02],
         [8.2444e+00, 1.4865e+02, 2.9779e+02, 2.9904e+02],
         [2.4332e+02, 3.4011e+00, 2.9987e+02, 1.3884e+02],
         [1.8608e+01, 2.8053e+01, 6.6836e+01, 2.1345e+02],
         [6.5991e+00, 1.7761e+02, 1.5280e+02, 2.9850e+02],
         [1.1509e+02, 6.3359e+01, 1.7068e+02, 1.6076e+02],
         [1.5691e+02, 8.5306e+01, 2.3508e+02, 1.8724e+02],
         [7.1447e+01, 7.7665e+01, 1.6359e+02, 2.0069e+02],
         [2.5747e+02, 3.0218e+01, 2.9824e+02, 8.5727e+01],
         [2.4039e+01, 2.4206e+02, 5.2521e+01, 2.7752e+02],
         [2.7608e+01, 2.5449e+02, 4.7232e+01, 2.7788e+02],
         [1.2059e+02, 1.0803e+02, 1.5563e+02, 1.8187e+02],
         [1.4902e+02, 1.0802e+02, 1.9267e+02, 1.8077e+02],
         [1.3566e+01, 5.9837e+01, 2.9061e+02, 2.9515e+02],
         [1.3296e+02, 1.4723e+02, 2.0539e+02, 1.8141e+02],
         [1.2713e+02, 1.3802e+02, 2.1133e+02, 2.0558e+02],
         [3.2951e+01, 2.3434e+02, 2.3441e+02, 2.9992e+02],
         [1.3268e+02, 1.2623e+02, 1.7042e+02, 1.8729e+02],
         [1.1654e+02, 6.5065e+01, 1.6978e+02, 1.0808e+02],
         [2.6553e+01, 4.5842e+01, 5.2569e+01, 1.5028e+02],
         [1.8091e+02, 0.0000e+00, 3.0000e+02, 1.2458e+02],
         [2.0823e+00, 2.0143e+01, 4.6297e+01, 2.0735e+02],
         [2.4797e+02, 3.4914e+01, 2.8237e+02, 9.8553e+01],
         [2.4879e+01, 1.4781e+02, 5.2215e+01, 1.9713e+02],
         [1.5745e+02, 9.3629e+01, 2.0591e+02, 1.6235e+02],
         [2.7077e+01, 9.3283e+01, 5.0884e+01, 1.9975e+02],
         [1.1815e+02, 1.3531e+02, 1.9542e+02, 1.7165e+02],
         [2.3157e+02, 1.2944e+02, 2.6351e+02, 1.9811e+02],
         [2.0102e+01, 2.4127e+02, 6.5305e+01, 2.9298e+02],
         [1.7710e+02, 1.0589e+02, 2.1826e+02, 1.6936e+02],
         [2.2639e+02, 1.2053e+02, 2.9165e+02, 2.0699e+02],
         [1.6301e+02, 1.2347e+02, 2.0437e+02, 1.8570e+02],
         [1.3836e+02, 8.3384e+01, 1.9517e+02, 1.2312e+02],
         [1.1054e+02, 8.4607e+01, 1.7236e+02, 1.1847e+02],
         [2.0724e+02, 6.5498e+01, 2.8422e+02, 2.0185e+02],
         [2.6934e+00, 2.0977e+02, 3.9960e+01, 2.8771e+02],
         [2.6683e+02, 1.4120e+02, 2.9494e+02, 2.2982e+02],
         [1.2180e+02, 9.9138e+01, 1.7816e+02, 1.4173e+02],
         [2.0152e+02, 1.0903e+02, 2.3390e+02, 1.8048e+02],
         [0.0000e+00, 2.2842e+02, 1.1478e+02, 3.0000e+02],
         [2.6364e+02, 0.0000e+00, 2.9973e+02, 7.6078e+01],
         [2.4596e+02, 1.2570e+02, 2.7778e+02, 2.0292e+02],
         [1.9314e+01, 2.5186e+02, 3.6432e+01, 2.7902e+02],
         [1.4996e+02, 1.4922e+02, 1.8758e+02, 2.0706e+02],
         [1.2033e+01, 6.2718e+01, 2.9159e+02, 2.9673e+02],
         [1.1332e+02, 1.1368e+02, 1.6910e+02, 1.5642e+02],
         [1.3049e+02, 1.6908e+02, 2.0806e+02, 1.9631e+02],
         [9.2237e+01, 4.6891e+01, 2.1070e+02, 1.2619e+02],
         [2.0608e+02, 1.1134e+02, 2.3711e+02, 1.4633e+02],
         [1.6260e+02, 1.1726e+02, 2.2606e+02, 1.5392e+02],
         [2.1294e+02, 1.0853e+02, 2.5202e+02, 1.7428e+02],
         [2.3360e+02, 7.7548e+01, 2.9801e+02, 2.5035e+02],
         [7.2506e+00, 4.1083e+01, 3.4351e+01, 1.3887e+02],
         [9.9559e+01, 1.0104e+02, 1.5327e+02, 1.3836e+02],
         [1.0502e+02, 7.4723e+01, 1.4589e+02, 1.2955e+02],
         [2.0783e+02, 3.6051e+01, 2.9338e+02, 1.9183e+02],
         [1.6495e+02, 1.0280e+02, 2.2831e+02, 1.3913e+02],
         [1.0848e+02, 9.8211e+01, 1.3508e+02, 1.7177e+02],
         [5.5352e+01, 7.2755e+01, 1.9565e+02, 1.4870e+02],
         [2.4863e+01, 3.7728e+01, 5.6120e+01, 1.0224e+02],
         [1.4976e+02, 7.4522e+01, 1.8808e+02, 1.4709e+02],
         [1.6498e+02, 1.1065e+02, 2.5745e+02, 2.1685e+02],
         [1.5889e+02, 1.3491e+02, 2.2578e+02, 1.6964e+02],
         [1.9150e+02, 1.0100e+02, 2.4268e+02, 1.4255e+02],
         [3.4547e+01, 2.6295e+02, 5.0502e+01, 2.8572e+02],
         [2.6314e+01, 1.4489e+02, 5.1329e+01, 2.1413e+02],
         [0.0000e+00, 1.3025e+02, 2.6878e+01, 1.7329e+02],
         [6.5246e+01, 1.0600e+00, 1.4453e+02, 5.3497e+01],
         [1.7806e+02, 7.2294e+01, 3.0000e+02, 1.5203e+02],
         [2.2755e+02, 7.5259e-01, 2.9246e+02, 8.6693e+01],
         [4.9127e+01, 0.0000e+00, 1.1652e+02, 8.1133e+01],
         [1.6532e+02, 1.4815e+02, 2.0229e+02, 2.0515e+02],
         [1.7039e+02, 8.4908e+01, 2.2574e+02, 1.2609e+02],
         [4.1368e+01, 4.8671e+01, 7.0007e+01, 1.4585e+02],
         [2.2277e+02, 1.0083e+02, 2.7534e+02, 1.4145e+02],
         [2.6426e+02, 1.1098e+02, 2.9474e+02, 1.9126e+02],
         [3.4430e+00, 2.6317e+02, 3.3318e+01, 3.0000e+02],
         [2.3276e+02, 9.4717e+01, 2.6556e+02, 1.6255e+02],
         [4.3765e+01, 1.6596e+02, 1.1121e+02, 2.9378e+02],
         [1.3776e+02, 1.3873e+02, 1.6569e+02, 2.2108e+02],
         [5.3676e+01, 1.0546e+02, 2.0609e+02, 1.8247e+02],
         [2.2202e+01, 2.5698e+02, 5.1517e+01, 2.9284e+02],
         [9.3237e+01, 2.8046e+02, 1.0717e+02, 3.0000e+02],
         [1.2574e+02, 1.6765e+02, 2.0966e+02, 2.3383e+02],
         [0.0000e+00, 7.6399e+01, 7.8534e+01, 3.0000e+02],
         [3.8097e+01, 4.0502e+01, 7.4172e+01, 9.4964e+01],
         [2.0467e+02, 1.3025e+02, 3.0000e+02, 2.8190e+02],
         [1.7996e+02, 1.4716e+02, 2.1229e+02, 1.8205e+02],
         [2.4392e+01, 2.7371e+02, 5.7802e+01, 3.0000e+02],
         [1.9919e+02, 8.7053e+01, 2.9711e+02, 2.4591e+02],
         [1.2975e+02, 4.3949e+01, 2.7434e+02, 1.2061e+02],
         [6.1990e+00, 7.5520e+01, 3.5306e+01, 1.7568e+02],
         [1.8482e+02, 0.0000e+00, 3.0000e+02, 4.4032e+01],
         [5.2050e+00, 9.1122e+01, 3.6830e+01, 1.7597e+02],
         [1.0655e+02, 1.3738e+02, 1.7566e+02, 2.1477e+02],
         [1.1943e+02, 1.4556e+02, 1.5214e+02, 2.0964e+02],
         [2.2517e+02, 8.4079e+01, 2.7898e+02, 1.2491e+02],
         [2.6137e+02, 5.0318e+01, 2.9895e+02, 1.1613e+02],
         [2.7024e+02, 4.6286e+01, 2.9800e+02, 8.2859e+01],
         [8.6794e+01, 2.8234e+02, 9.8415e+01, 3.0000e+02],
         [7.7143e+01, 2.8459e+02, 8.8786e+01, 3.0000e+02],
         [1.3975e+02, 4.1382e+01, 2.9931e+02, 2.7759e+02],
         [3.4274e+00, 1.8143e+02, 3.7327e+01, 2.5543e+02],
         [2.1211e+02, 1.0421e+02, 2.4400e+02, 1.3496e+02],
         [1.6164e+02, 3.0446e+01, 2.9376e+02, 2.8220e+02],
         [9.7141e+01, 0.0000e+00, 3.0000e+02, 7.2839e+01],
         [9.0797e+00, 2.0628e+02, 1.4903e+02, 3.0000e+02],
         [2.8739e+01, 2.6654e+02, 4.7588e+01, 2.8149e+02],
         [7.6200e+01, 1.9732e+02, 1.4245e+02, 3.0000e+02],
         [1.8015e+02, 1.5688e+02, 1.9724e+02, 1.7510e+02],
         [1.0035e+02, 1.3206e+02, 1.5161e+02, 1.7284e+02],
         [1.2896e+02, 1.8451e+02, 2.0478e+02, 2.1493e+02],
         [1.5009e+02, 1.6989e+02, 1.8568e+02, 2.3226e+02],
         [2.0381e+02, 1.1824e+02, 2.6472e+02, 1.5338e+02],
         [4.5271e+01, 4.8017e+01, 5.9255e+01, 7.5684e+01],
         [2.4736e+02, 1.5845e+02, 2.7825e+02, 2.3631e+02],
         [0.0000e+00, 2.6236e-01, 3.9252e+01, 8.3543e+01],
         [1.8883e+02, 1.4010e+02, 2.0275e+02, 1.6926e+02],
         [2.3475e+02, 6.9016e+01, 2.6614e+02, 1.3673e+02],
         [0.0000e+00, 1.2234e+02, 2.6402e+02, 2.9557e+02],
         [9.0739e+01, 3.4670e+01, 1.5800e+02, 1.0362e+02],
         [7.0053e-01, 1.9191e+02, 2.5623e+01, 2.7361e+02],
         [0.0000e+00, 2.6236e-01, 3.9252e+01, 8.3543e+01],
         [1.8613e+02, 1.5526e+02, 2.0546e+02, 1.7521e+02],
         [1.4005e+01, 0.0000e+00, 8.4360e+01, 6.2809e+01],
         [2.0693e+02, 1.1127e+02, 2.8560e+02, 2.7764e+02],
         [2.1205e+01, 2.5996e+02, 3.5240e+01, 2.8987e+02],
         [3.4355e+01, 4.6169e+01, 5.0254e+01, 7.4532e+01],
         [2.3790e+02, 2.7117e+01, 2.6618e+02, 9.5413e+01],
         [2.1104e+02, 1.1435e+02, 2.3033e+02, 1.3614e+02],
         [2.3719e+01, 2.6946e+02, 3.4947e+01, 2.9880e+02],
         [5.4845e+01, 3.0641e+00, 8.4185e+01, 4.3762e+01],
         [1.2977e+02, 2.6673e+02, 1.6623e+02, 2.9949e+02],
         [7.7951e+01, 0.0000e+00, 1.4502e+02, 7.8170e+01],
         [4.4531e+01, 2.5518e+02, 5.9404e+01, 2.7930e+02],
         [2.7620e+01, 2.7103e+02, 4.5167e+01, 2.9764e+02],
         [2.1352e+02, 8.0281e+01, 2.5375e+02, 1.3187e+02],
         [2.4486e+01, 8.5836e+01, 5.1876e+01, 1.8861e+02],
         [0.0000e+00, 5.5516e+01, 1.0116e+01, 9.3727e+01],
         [1.3284e+00, 1.6610e+02, 5.0052e+01, 3.0000e+02],
         [1.3115e+01, 2.6681e+02, 2.7784e+01, 2.9891e+02],
         [2.7369e+00, 2.0024e+02, 3.1214e+01, 2.4118e+02],
         [1.6958e+02, 1.3649e+02, 2.0467e+02, 1.7422e+02],
         [3.4733e+01, 2.7246e+02, 5.2063e+01, 2.9659e+02],
         [1.1108e+02, 1.6895e+02, 1.7180e+02, 1.9890e+02],
         [2.2348e+01, 2.0286e+02, 5.5345e+01, 2.6822e+02],
         [2.1609e+02, 1.2373e+02, 2.4961e+02, 1.9544e+02],
         [1.8280e+02, 1.4747e+02, 1.9556e+02, 1.6378e+02],
         [4.8337e-01, 2.6548e+02, 1.8968e+01, 3.0000e+02],
         [8.0369e+01, 1.7715e+02, 2.9349e+02, 2.9746e+02],
         [3.6577e+01, 1.0696e+02, 5.1737e+01, 1.4984e+02],
         [0.0000e+00, 1.5419e+02, 2.8511e+01, 1.8973e+02],
         [1.1500e+00, 8.0133e+01, 2.2933e+01, 1.6802e+02],
         [1.2527e+01, 6.0236e+01, 2.8842e+02, 2.9003e+02],
         [9.2530e+00, 1.9297e+01, 3.1482e+01, 7.1072e+01],
         [2.6988e+02, 5.5862e+01, 2.9933e+02, 9.7382e+01],
         [1.6196e+01, 2.6468e+02, 4.6781e+01, 2.9977e+02],
         [1.0586e+00, 2.3826e+02, 6.0510e+01, 3.0000e+02],
         [2.2275e+02, 1.1363e+02, 2.3515e+02, 1.4041e+02],
         [1.4553e+01, 0.0000e+00, 1.4937e+02, 9.3181e+01],
         [1.8520e+01, 2.3740e+02, 3.6157e+01, 2.6781e+02],
         [1.9543e+00, 7.3124e+01, 4.0074e+01, 1.3744e+02],
         [2.5311e+01, 2.7842e+02, 3.4296e+01, 3.0000e+02],
         [6.5246e+01, 1.0600e+00, 1.4453e+02, 5.3497e+01],
         [6.2167e+00, 7.3394e+01, 6.4603e+01, 1.7249e+02],
         [4.3474e+01, 1.1921e+02, 6.7450e+01, 2.1057e+02],
         [0.0000e+00, 4.3247e+01, 1.6312e+02, 2.9152e+02],
         [2.9164e+01, 6.7715e+01, 5.5653e+01, 1.1601e+02],
         [6.0237e+00, 6.0450e+01, 1.9032e+01, 9.1025e+01],
         [2.8704e+02, 5.2506e+01, 2.9997e+02, 8.1833e+01],
         [6.1451e+00, 3.0641e+01, 1.7065e+01, 7.5105e+01],
         [1.0072e+02, 2.7757e+02, 1.1564e+02, 3.0000e+02],
         [2.7481e+02, 4.9030e+01, 2.9209e+02, 7.9942e+01],
         [2.8040e+02, 0.0000e+00, 3.0000e+02, 1.3579e+02],
         [2.6483e+02, 4.1991e+01, 2.9167e+02, 8.4969e+01],
         [1.4296e+02, 7.8226e+00, 2.6265e+02, 9.8022e+01],
         [2.5156e+02, 3.6799e+01, 2.8027e+02, 9.1022e+01],
         [1.1677e+01, 2.0524e+02, 2.7458e+01, 2.3653e+02],
         [2.8534e+02, 1.1165e+02, 2.9798e+02, 1.6020e+02],
         [2.3253e+02, 1.6188e+02, 2.8907e+02, 2.0202e+02],
         [1.4264e+01, 2.3510e+02, 8.2463e+01, 2.9864e+02],
         [2.1017e+00, 0.0000e+00, 3.4675e+01, 8.8614e+01],
         [1.7790e+00, 4.1898e+01, 2.2267e+01, 1.3345e+02],
         [1.1363e+02, 2.6574e+02, 1.4332e+02, 2.9985e+02],
         [2.8704e+02, 5.2506e+01, 2.9997e+02, 8.1833e+01],
         [2.5011e+02, 6.3502e-01, 2.8413e+02, 7.0594e+01],
         [7.0394e+01, 2.7544e+02, 9.9670e+01, 3.0000e+02],
         [1.6091e+02, 1.7158e+02, 2.5516e+02, 2.9511e+02],
         [2.8069e+01, 2.7779e+02, 4.3785e+01, 3.0000e+02],
         [9.8555e+00, 1.1961e+02, 6.6770e+01, 2.0918e+02],
         [2.2301e+02, 1.1039e+02, 2.4986e+02, 1.4078e+02],
         [3.9344e+00, 2.5360e+02, 4.8506e+01, 2.9934e+02],
         [2.7471e+02, 6.5201e+01, 2.9317e+02, 8.5715e+01],
         [2.1740e+01, 1.9924e+02, 3.3347e+01, 2.3876e+02],
         [0.0000e+00, 1.8690e+02, 2.6029e+01, 2.3328e+02],
         [3.4590e+01, 2.2481e+02, 7.2581e+01, 2.8204e+02],
         [0.0000e+00, 2.3549e+02, 2.8934e+01, 2.9230e+02],
         [1.1500e+00, 8.0133e+01, 2.2933e+01, 1.6802e+02],
         [2.9411e+02, 1.1617e+02, 3.0000e+02, 1.3939e+02]], device='cuda:0'),
 'scores': tensor([0.9462, 0.1989, 0.1664, 0.1032, 0.0894, 0.0836, 0.0830, 0.0819, 0.0794,
         0.0723, 0.0723, 0.0720, 0.0700, 0.0675, 0.0648, 0.0641, 0.0613, 0.0606,
         0.0600, 0.0597, 0.0590, 0.0560, 0.0547, 0.0541, 0.0538, 0.0532, 0.0518,
         0.0517, 0.0501, 0.0501, 0.0498, 0.0497, 0.0493, 0.0491, 0.0490, 0.0475,
         0.0475, 0.0471, 0.0465, 0.0463, 0.0462, 0.0459, 0.0454, 0.0445, 0.0434,
         0.0433, 0.0432, 0.0425, 0.0419, 0.0419, 0.0419, 0.0416, 0.0416, 0.0409,
         0.0404, 0.0398, 0.0398, 0.0397, 0.0396, 0.0395, 0.0387, 0.0385, 0.0382,
         0.0369, 0.0369, 0.0366, 0.0363, 0.0354, 0.0352, 0.0350, 0.0349, 0.0345,
         0.0343, 0.0341, 0.0339, 0.0331, 0.0327, 0.0324, 0.0323, 0.0320, 0.0320,
         0.0318, 0.0317, 0.0317, 0.0316, 0.0315, 0.0313, 0.0308, 0.0308, 0.0307,
         0.0304, 0.0302, 0.0302, 0.0301, 0.0300, 0.0297, 0.0297, 0.0297, 0.0297,
         0.0297, 0.0295, 0.0294, 0.0294, 0.0293, 0.0293, 0.0293, 0.0292, 0.0291,
         0.0291, 0.0289, 0.0284, 0.0282, 0.0282, 0.0281, 0.0279, 0.0277, 0.0277,
         0.0277, 0.0276, 0.0273, 0.0272, 0.0272, 0.0271, 0.0271, 0.0270, 0.0270,
         0.0268, 0.0267, 0.0265, 0.0265, 0.0264, 0.0262, 0.0261, 0.0259, 0.0259,
         0.0258, 0.0258, 0.0257, 0.0256, 0.0255, 0.0255, 0.0254, 0.0254, 0.0252,
         0.0251, 0.0251, 0.0250, 0.0249, 0.0249, 0.0247, 0.0245, 0.0243, 0.0241,
         0.0240, 0.0238, 0.0237, 0.0236, 0.0235, 0.0231, 0.0229, 0.0229, 0.0229,
         0.0228, 0.0228, 0.0228, 0.0227, 0.0225, 0.0224, 0.0221, 0.0220, 0.0220,
         0.0220, 0.0220, 0.0219, 0.0218, 0.0217, 0.0216, 0.0216, 0.0216, 0.0214,
         0.0212, 0.0211, 0.0211, 0.0211, 0.0210, 0.0210, 0.0208, 0.0207, 0.0207,
         0.0206, 0.0205, 0.0205, 0.0205, 0.0203, 0.0203, 0.0203, 0.0202, 0.0202,
         0.0201, 0.0201], device='cuda:0'),
 'labels': tensor([16, 16,  2, 64, 44,  2, 16, 16, 16, 86, 44, 44, 16, 16, 64, 16, 16,  2,
         16, 16, 44, 64, 44, 86, 47, 16, 44, 16, 86, 44, 16, 86, 16, 16, 16, 16,
         44, 86, 16, 16,  2, 64, 86, 44, 16, 61, 16, 16, 16, 62, 16, 16, 86, 44,
         16, 16, 64, 16, 16, 16, 44, 16, 16, 16, 16, 44, 44, 62, 31, 16, 64,  1,
         16, 16, 44, 16, 86, 62, 16,  2, 16, 16, 44,  1, 16,  2, 44, 86, 52, 62,
         64, 16, 44, 64, 47, 16, 16, 16, 86, 31,  1,  1, 16, 44, 62, 64, 64,  4,
         44,  2, 52, 16, 16, 16, 16, 44, 86, 31, 52, 16,  4, 16, 44, 27, 52,  1,
         62, 44, 44, 86, 62, 44,  1, 47,  1, 44, 44, 16, 47,  1,  2, 62, 62, 52,
         44, 16, 44, 86, 52, 62, 62, 44, 62, 47, 86,  1, 62, 62,  2, 62,  1, 44,
         47, 62, 27, 47, 44,  2, 47,  1, 62,  1,  1, 62, 64, 62, 64, 62, 62,  1,
         86,  4, 44, 44, 47, 31, 64,  1, 62, 62, 47, 62, 44, 31, 62,  1, 44, 44,
         44,  1], device='cuda:0')}

Bounding box 그리기

 
image = image.cpu().data[0]
image = transforms.functional.to_pil_image(image)
image = np.array(image)
 
threshold=0.5
 
for box, label, score in zip(prediction["boxes"], prediction["labels"], prediction["scores"]):
    if score > threshold:
        box = list(map(int, box))
        print(box)
        cv2.rectangle(image, (box[0], box[1]), (box[2], box[3]), (255, 0, 0), 2, cv2.LINE_AA)
 
fig, axs = plt.subplots(1, 2, figsize = (10, 5))
 
axs[0].imshow(image_jpg.permute(1, 2, 0))
axs[0].grid(None)
axs[1].imshow(image)
axs[1].grid(None)
plt.show()
 
[112, 65, 215, 183]



png

SSD + CV DNN 얼굴검출

import numpy as np
import sys
import cv2
import pandas as pd
img = cv2.imread('./figure/king_face.png')
 
if img is None:
    print('image read failed')
    sys.exit()
 
## tensorflow model   
model = './opencv_face_detector/opencv_face_detector_uint8.pb'
config = './opencv_face_detector/opencv_face_detector.pbtxt'
 
face_net = cv2.dnn.readNet(model, config)
# face_net.getLayerNames()
 
if face_net.empty():
    print('Net open failed')
    sys.exit()
 
# blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]]) -> retval
blob = cv2.dnn.blobFromImage(img, 1, (300, 300), (104, 177, 123),
                            swapRB=False)
 
face_net.setInput(blob)
out = face_net.forward()
 
labels = ["img_id", "is_face", "confidence", "left", "top", "right", "bottom"]
out_df = pd.DataFrame(out[0][0], columns = labels)
print(out_df)
 
     img_id  is_face  confidence      left       top     right    bottom
0       0.0      1.0    0.989431  0.825202  0.502988  0.893821  0.658601
1       0.0      1.0    0.950553  0.147596  0.511079  0.215222  0.681570
2       0.0      1.0    0.947276  0.288199  0.444965  0.359195  0.628823
3       0.0      1.0    0.920967  0.499137  0.392986  0.589955  0.570557
4       0.0      1.0    0.835135  0.642767  0.463616  0.720524  0.659535
..      ...      ...         ...       ...       ...       ...       ...
195     0.0      0.0    0.000000  0.000000  0.000000  0.000000  0.000000
196     0.0      0.0    0.000000  0.000000  0.000000  0.000000  0.000000
197     0.0      0.0    0.000000  0.000000  0.000000  0.000000  0.000000
198     0.0      0.0    0.000000  0.000000  0.000000  0.000000  0.000000
199     0.0      0.0    0.000000  0.000000  0.000000  0.000000  0.000000

[200 rows x 7 columns]
 
detect = out[0, 0, :, :]
h, w = img.shape[:2]
 
for i in range(detect.shape[0]):
    confidence = detect[i, 2] # (0, 1, confidence, x1, y1, x2, y2)
    
    if confidence > 0.15:
        # out matrix에서 x1, y1, x2, y2 값이 0 ~1로 normalize 되어 있음
        
        x1 = int(detect[i, 3]*w)
        y1 = int(detect[i, 4]*h)
        x2 = int(detect[i, 5]*w)
        y2 = int(detect[i, 6]*h)
        
        cv2.rectangle(img, (x1, y1), (x2, y2),
                     (0, 0, 255), 2)
        
        text = 'Face: {}%'.format(round(confidence*100, 2))
        cv2.putText(img, text, (x1, y1-1), cv2.FONT_HERSHEY_SIMPLEX,
                   0.8, (0, 0, 255), 1, cv2.LINE_AA)
        
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
plt.figure(figsize = (8,8))
plt.imshow(img)
plt.grid(None)
plt.axis("off")
plt.show()

png

Yolo v3 객체검출 with opencv dnn

# https://pjreddie.com/darknet/yolo/
 
# NMSBoxes(bboxes, scores, score_threshold, nms_threshold) -> indices
# nms_threshold: nms_threshold a threshold used in non maximum suppression
 
# getPerfProfile() -> retval, timings
# .   @brief Returns overall time for inference and timings (in ticks) for layers.
 
# https://github.com/pjreddie/darknet/blob/master/data/coco.names
## Automating with K-Means in Python
 
import numpy as np
from sklearn.cluster import KMeans
 
# Example bounding boxes (width, height)
bboxes = np.array([[32, 32], [64, 64], 
                   [128, 128], [256, 256], 
                   [512, 512], [128, 64], 
                   [64, 128], [256, 128]])
 
# Perform K-means clustering with k=9
kmeans = KMeans(n_clusters=3, random_state=0)
kmeans.fit(bboxes)
 
# Output anchor boxes
anchors = kmeans.cluster_centers_
print("Anchors:", anchors)
 
Anchors: [[512.  512. ]
 [ 83.2  83.2]
 [256.  192. ]]
import sys
import numpy as np
import cv2
 
# 모델 & 설정 파일
model = './yolo_v3_pb/yolov3.weights'
config = './yolo_v3_pb/yolov3.cfg'
class_labels = './yolo_v3_pb/coco.names'
 
# 테스트 이미지 파일
img_files = ['./figure/dog.jpg', 
             './figure/person.jpg', 
             './figure/sheep.jpg', 
             './figure/kite.jpg']
 
 
# 네트워크 생성
net = cv2.dnn.readNet(model, config)
 
if net.empty():
    print('Net open failed!')
    sys.exit()
 
# 클래스 이름 불러오기
classes = []
with open(class_labels, 'rt') as f:
    classes = f.read().rstrip('\n').split('\n')
 
# colors = np.random.uniform(0, 255, size=(len(classes), 3))
# colors = np.array([[0, 0, 255], 
#                    [255, 0, 0],
#                    [0, 255, 0],
#                    [0, 255, 255],
#                    [255, 255, 0],
#                    [255, 0, 255]])
 
# 출력 레이어 이름 받아오기
net.getUnconnectedOutLayers()
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
print(output_layers)
['yolo_82', 'yolo_94', 'yolo_106']
# outs는 3개의 ndarray 리스트.
# output_layers = ['yolo_82', 'yolo_94', 'yolo_106']
# output_layers[0].shape = (507, 85), 13*13*3
# output_layers[1].shape = (2028, 85), 26*26*3
# output_layers[2].shape = (8112, 85), 52*52*3
import time
 
confThreshold = 0.5
nmsThreshold = 0.4
 
# 실행
print(img_files)
for i in img_files:
    img = cv2.imread(i)
 
    if img is None:
        continue
 
    # 블롭 생성 & 추론
    blob = cv2.dnn.blobFromImage(img, 1/255., (320, 320), swapRB=True)
    # blob = cv2.dnn.blobFromImage(img, 1/255., (416, 416), swapRB=True)
    # blob = cv2.dnn.blobFromImage(img, 1/255., (608, 608), swapRB=True)
 
    net.setInput(blob)
    outs = net.forward(output_layers) 
 
    # outs[0].shape=(507, 85), 13*13*3=507
    # outs[1].shape=(2028, 85), 26*26*3=2028
    # outs[2].shape=(8112, 85), 52*52*3=8112
 
    h, w = img.shape[:2]
 
    class_ids = []
    confidences = []
    boxes = []
 
    for out in outs:
        for detection in out:
            # detection: 4(bounding box) + 1(objectness_score) + 80(class confidence)
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > confThreshold:
                # 바운딩 박스 중심 좌표 & 박스 크기
                cx = int(detection[0] * w)
                cy = int(detection[1] * h)
                bw = int(detection[2] * w)
                bh = int(detection[3] * h)
 
                # 바운딩 박스 좌상단 좌표
                sx = int(cx - bw / 2)
                sy = int(cy - bh / 2)
 
                boxes.append([sx, sy, bw, bh])
                confidences.append(float(confidence))
                class_ids.append(int(class_id))
 
    # 비최대 억제, Non Max Suppression
# https://deep-learning-study.tistory.com/403
# nmsThreshold: Determines the IoU (Intersection over Union) threshold
# A higher value results in more boxes being retained.
    indices = cv2.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
 
    for i in indices:
#         i = i[0]
        sx, sy, bw, bh = boxes[i]
        label = f'{classes[class_ids[i]]}: {confidences[i]:.2}'
        # color = colors[class_ids[i]]
        color = (0, 0, 255)
        cv2.rectangle(img, (sx, sy, bw, bh), color, 2)
        cv2.putText(img, label, (sx, sy - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2, cv2.LINE_AA)
 
    t, _ = net.getPerfProfile() # Total number of ticks spent during the last forward() call.
    label = 'Inference time: %.2f ms' % (t * 1000.0 / cv2.getTickFrequency())
    
    cv2.putText(img, label, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
                1, (0, 0, 255), 1, cv2.LINE_AA)
    
    img  = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.grid(None)
    plt.axis("off")
    plt.show()
['./figure/dog.jpg', './figure/person.jpg', './figure/sheep.jpg', './figure/kite.jpg']



png

png

png

png

Yolo v10 객체검출 with pytorch

!pip install ultralytics
from ultralytics import YOLO
## coco dataset
# 클래스 이름 불러오기
# classNames = []
with open(class_labels, 'rt') as f:
    classNames = f.read().rstrip('\n').split('\n')
 
# classNames = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", "boat",
#               "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
#               "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
#               "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat",
#               "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup",
#               "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli",
#               "carrot", "hot dog", "pizza", "donut", "cake", "chair", "sofa", "pottedplant", "bed",
#               "diningtable", "toilet", "tvmonitor", "laptop", "mouse", "remote", "keyboard", "cell phone",
#               "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors",
#               "teddy bear", "hair drier", "toothbrush"
#               ]
import time
 
data_dir = "./figure"
 
img_path = os.path.join(data_dir, "peoples.jpg")
img = cv2.imread(img_path)
 
if img is None:
    print("Image read failed")
    sys.exit()
 
model = YOLO("yolo11x.pt")  # load a pretrained model (recommended for training)
 
start = time.time()
detection = model(img, verbose=False)[0]
stop = time.time()
on_time = (stop - start)*1000
print(f"estimation time = {on_time:.3f}ms")
fps = f'{1000 / on_time:.4f} fps'
CONFIDENCE_THRESHOLD = 0.6
 
for data in detection.boxes.data.tolist():
        confidence = data[4]
        if confidence < CONFIDENCE_THRESHOLD:
            continue
        
        xmin, ymin, xmax, ymax = int(data[0]), int(data[1]), int(data[2]), int(data[3])
        label = int(data[5])
        cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)
        cv2.putText(img, classNames[label]+ ' ' +str(round(confidence, 2))+'%', 
        (xmin, ymin-5), cv2.FONT_ITALIC, 0.7, (0, 0, 255), 1)        
 
    
        cv2.putText(img, fps, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 1)
 
 
img  = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.grid(None)
plt.axis("off")
plt.show()
estimation time = 701.129ms



png