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.

L'environnement d'exécution est ** Google Colab. ** et il prend en charge TensorFlow ** 2.x **.
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 **".

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.

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?).

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.
 ici, mais le changer en ʻImage.NEAREST changera le score de détection.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.
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.
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.

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.

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