[PYTHON] Détection générale des objets à l'aide du modèle pré-entraîné de Google (via TensorFlow Hub)

Aperçu

Utilisez TensorFlow Hub pour apporter ** un modèle pré-entraîné de reconnaissance générale d'objets (fabriqué par Google) ** et utilisez-le pour effectuer une reconnaissance générale d'objets (détection générale d'objets) pour n'importe quelle image. C'est le contenu.

Fondamentalement, je me réfère à https://github.com/tensorflow/hub/blob/master/examples/colab/object_detection.ipynb.

ダウンロード (2).png

L'environnement d'exécution est ** Google Colab. ** et il prend en charge TensorFlow ** 2.x **.

Préparation

Changez pour utiliser le GPU pour le calcul. Sélectionnez "Runtime" - "Change Runtime Type" dans le menu en haut et changez l'accélérateur matériel en "** GPU **".

2020-01-23_13h41_09.png

Ensuite, ajoutez une variable d'environnement qui spécifie le répertoire dans lequel vous souhaitez stocker temporairement les modules (modèles entraînés) que vous importez de TensorFlow Hub. Ce processus n'est nécessaire que lorsque vous souhaitez cocher "Quel type de module sera téléchargé?" Et peut être omis.

Ajouter une variable d'environnement


import os
os.environ['TFHUB_CACHE_DIR'] ='/content/tfhub'

Vérifier les variables d'environnement


!printenv TFHUB_CACHE_DIR

Passez à l'utilisation de TensorFlow 2.x.

TensorFlow2.Passer à x


%tensorflow_version 2.x

Téléchargez également l'image que vous souhaitez reconnaître comme objet dans Google Colab (vous pouvez la télécharger en développant la barre latérale, en activant l'onglet Fichier et en faisant glisser et déposer le fichier). Ici, le fichier au format jpg est utilisé, mais le format png est également OK.

2020-01-22_20h21_38.png

Obtenez le module de détection d'objet général (modèle entraîné) du hub

Obtenez le module de détection d'objet général (modèle entraîné) à partir de TensorFlow Hub.

Chargement du détecteur


import tensorflow as tf
import tensorflow_hub as hub

module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'
#module_handle = 'https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1'

detector = hub.load(module_handle).signatures['default']

Le module ci-dessus est "* Modèle de détection d'objet basé sur SSD formé sur Open Images V4 avec MobileNet V2 pré-formé ImageNet comme extracteur de caractéristiques d'image. *". En plus de cela, il y a divers modules pour la "détection d'objet image" sur le hub.

Si la variable d'environnement TFHUB_CACHE_DIR est définie, le module acquis y sera stocké (s'il n'est pas spécifié, il sera stocké quelque part dans / tmp?).

TFHUB_CACHE_DIR.png

Effectuer la détection d'objets

Ecrivez une fonction run_detector (...) qui prend le "détecteur" et le "chemin du fichier image" chargés ci-dessus comme arguments, exécute la détection d'objet et produit le résultat sous forme de texte.

La fonction showImage (...) appelée dans la dernière ligne sera créée plus tard, je vais donc la commenter ici.

Les principaux points sont les suivants.

Définition de fonction pour effectuer la détection d'objets


import time
import numpy as np
import PIL.Image as Image

def run_detector(detector, path):

  #Importez l'image et convertissez-la dans un format pouvant être entré dans le détecteur
  img = Image.open(path) # Pillow(PIL)
  if img.mode == 'RGBA' :
    img = img.convert('RGB')
  converted_img = img.copy()
  converted_img = converted_img.resize((227,227),Image.LANCZOS) #Réduire à la taille d'entrée
  converted_img = np.array(converted_img, dtype=np.float32)     # np.Convertir en tableau
  converted_img = converted_img / 255. # 0.0 ~ 1.Normalisé à 0
  converted_img = converted_img.reshape([1,227,227,3])
  converted_img = tf.constant(converted_img)

  t1 = time.time()
  result = detector(converted_img) #Détection générale des objets (corps principal)
  t2 = time.time()
  print(f'Temps de détection: {t2-t1:.3f}Secondes' )

  #Préparation à la sortie du résultat sous forme de texte
  r = {key:value.numpy() for key,value in result.items()}
  boxes =       r['detection_boxes']
  scores =      r['detection_scores']
  decode = np.frompyfunc( lambda p : p.decode('ascii'), 1, 1)
  class_names = decode( r['detection_class_entities'] )

  #Le score est de 0.Sortie texte pour plus de 25 résultats (n)
  print(f'Objet de découverte' )
  n = np.count_nonzero(scores >= 0.25 )
  for i in range(n):
    y1, x1, y2, x2 = tuple(boxes[i])
    x1, x2 = int(x1*img.width), int(x2*img.width)
    y1, y2 = int(y1*img.height),int(y2*img.height)
    t = f'{class_names[i]:10} {100*scores[i]:3.0f}%  '
    t += f'({x1:>4},{y1:>4}) - ({x2:>4},{y2:>4})'
    print(t)

  # showImage(np.array(img), r, min_score=0.25) #Superposer le résultat de la détection sur l'image

Le run_detector (...) ci-dessus est appelé comme suit:

Exécuter en spécifiant le chemin de l'image


img_path = '/content/sample1.jpg'
run_detector(detector, img_path)

Ici, j'ai utilisé la photo suivante (matériel gratuit) pour sample1.jpg.

sample8.jpg

Le résultat de l'exécution est le suivant. Les nombres entre parenthèses correspondent aux coordonnées supérieure gauche et inférieure droite du rectangle qui entoure l'objet.

Temps de détection: 0.251 secondes
Objet de découverte
Human face  57%  ( 522, 156) - ( 636, 276)
Clothing    57%  ( 403, 203) - ( 757, 577)
Clothing    57%  ( 144, 211) - ( 481, 583)
Girl        41%  ( 393, 104) - ( 763, 595)
Girl        34%  ( 214,  81) - ( 619, 614)

Avec un tel texte, le résultat est difficile à comprendre, je vais donc le superposer sur l'image.

Superposer le résultat de la détection sur l'image

Ecrivez une fonction showImage (...) pour superposer le résultat de la détection sur l'image.

Superposer le résultat de la détection sur l'image


import matplotlib.pyplot as plt
import matplotlib.patheffects as pe 

def showImage(img, r, min_score=0.1):
  fig = plt.figure(dpi=150,figsize=(8,8))
  ax = plt.gca()
  ax.tick_params(axis='both', which='both', left=False, 
                 labelleft=False, bottom=False, labelbottom=False)
  ax.imshow(img)

  decode = np.frompyfunc( lambda p : p.decode("ascii"), 1, 1)

  boxes =       r['detection_boxes']
  scores =      r['detection_scores']
  class_names = decode( r['detection_class_entities'] )

  n = np.count_nonzero(scores >= min_score)
  
  # class_Préparation de la couleur correspondant aux noms
  class_set = np.unique(class_names[:n])
  colors = dict()
  cmap = plt.get_cmap('tab10')
  for i, v in enumerate(class_set):
    colors[v] =cmap(i)

  #Dessinez un rectangle Dessinez celui avec le score le plus bas
  img_w = img.shape[1]
  img_h = img.shape[0]
  for i in reversed(range(n)):
    text = f'{class_names[i]} {100*scores[i]:.0f}%'
    color = colors[class_names[i]]
    y1, x1, y2, x2 = tuple(boxes[i])
    y1, y2 = y1*img_h, y2*img_h
    x1, x2 = x1*img_w, x2*img_w

    #Cadre
    r = plt.Rectangle(xy=(x1, y1), width=(x2-x1), height=(y2-y1),
                      fill=False, edgecolor=color, joinstyle='round', 
                      clip_on=False, zorder=8+(n-i) )
    ax.add_patch( r )

    #Tags: texte
    t = ax.text(x1+img_w/200, y1-img_h/300, text, va='bottom', fontsize=6, color=color,zorder=8+(n-i))
    t.set_path_effects([pe.Stroke(linewidth=1.5,foreground='white'), pe.Normal()])
    fig.canvas.draw()
    r = fig.canvas.get_renderer()
    coords = ax.transData.inverted().transform(t.get_window_extent(renderer=r))
    tag_w = abs(coords[0,0]-coords[1,0])+img_w/100
    tag_h = abs(coords[0,1]-coords[1,1])+img_h/120

    #Tags: arrière-plan
    r = plt.Rectangle(xy=(x1, y1-tag_h), width=tag_w, height=tag_h,
                      edgecolor=color, facecolor=color,
                      joinstyle='round', clip_on=False, zorder=8+(n-i))
    ax.add_patch( r )

Ensuite, supprimez le commentaire dans la dernière ligne de la définition de run_detector (...) et exécutez à nouveau run_detector (detecteur, img_path).

Le résultat d'exécution suivant (image) est obtenu. ダウンロード (1).png

prime

Passez à un autre module (détecteur) et essayez la reconnaissance d'objets pour la même image (cela prend beaucoup de temps).

python


import tensorflow as tf
import tensorflow_hub as hub

#module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'
module_handle = 'https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1'

detector = hub.load(module_handle).signatures['default']

Le résultat de l'exécution est le suivant. Cela prend beaucoup plus de temps qu'auparavant, mais nous pouvons en détecter davantage. ダウンロード (2).png

Temps de détection: 1.379 secondes
Objet de découverte
Human face  94%  ( 524, 147) - ( 625, 272)
Human face  86%  ( 266, 149) - ( 351, 270)
Clothing    75%  ( 383, 234) - ( 750, 565)
Footwear    70%  ( 154, 511) - ( 306, 598)
Boy         65%  ( 351,  93) - ( 759, 606)
Footwear    59%  ( 311, 521) - ( 477, 600)
Clothing    53%  ( 152, 225) - ( 438, 565)
Girl        53%  ( 144,  88) - ( 481, 598)
Boy         49%  ( 225,  88) - ( 618, 592)
Boy         45%  ( 145,  90) - ( 464, 603)
Girl        37%  ( 324,  85) - ( 771, 587)
Sun hat     29%  ( 479,  78) - ( 701, 279)

Recommended Posts

Détection générale des objets à l'aide du modèle pré-entraîné de Google (via TensorFlow Hub)
Détection de logo à l'aide de l'API de détection d'objets TensorFlow
[Résumé] Modèle de détection d'objets utilisant Transformer "Détection d'objets de bout en bout avec des transformateurs"
[Pour les débutants] J'ai essayé d'utiliser l'API Tensorflow Object Detection
Comment faire un modèle pour la détection d'objets avec YOLO en 3 heures
Détection d'objets à l'aide de Jetson Nano (YOLOv3) - (1) Paramètres Jetson Nano-
Essayez la reconnaissance d'objets en temps réel avec YOLOv2 (TensorFlow)