[PYTHON] Allgemeine Objekterkennung mit dem von Google vorab trainierten Modell (über TensorFlow Hub)

Überblick

Verwenden Sie TensorFlow Hub, um ** ein vorab trainiertes Modell der allgemeinen Objekterkennung (erstellt von Google) ** zu erstellen und damit eine allgemeine Objekterkennung (allgemeine Objekterkennung) für jedes Bild durchzuführen. Es ist der Inhalt.

Grundsätzlich verweise ich auf https://github.com/tensorflow/hub/blob/master/examples/colab/object_detection.ipynb.

ダウンロード (2).png

Die Ausführungsumgebung ist ** Google Colab. ** und unterstützt TensorFlow ** 2.x **.

Vorbereitung

Ändern Sie die GPU für die Berechnung. Wählen Sie "Runtime" - "Change Runtime Type" aus dem Menü oben und ändern Sie den Hardwarebeschleuniger in "** GPU **".

2020-01-23_13h41_09.png

Fügen Sie als Nächstes eine Umgebungsvariable hinzu, die das Verzeichnis angibt, in dem Sie die Module (trainierte Modelle), die Sie von TensorFlow Hub mitbringen, vorübergehend speichern möchten. Dieser Vorgang ist nur erforderlich, wenn Sie überprüfen möchten, welche Art von Modul heruntergeladen wird. Er kann weggelassen werden.

Umgebungsvariable hinzufügen


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

Überprüfen Sie die Umgebungsvariablen


!printenv TFHUB_CACHE_DIR

Wechseln Sie zu TensorFlow 2.x.

TensorFlow2.Wechseln Sie zu x


%tensorflow_version 2.x

Laden Sie außerdem das Bild, das Sie als Objekt erkennen möchten, in Google Colab hoch. (Sie können es hochladen, indem Sie die Seitenleiste erweitern, die Registerkarte Datei aktivieren und die Datei ziehen und ablegen.) Hier wird die JPG-Formatdatei verwendet, aber auch das PNG-Format ist in Ordnung.

2020-01-22_20h21_38.png

Holen Sie sich das allgemeine Objekterkennungsmodul (trainiertes Modell) vom Hub

Holen Sie sich das allgemeine Objekterkennungsmodul (trainiertes Modell) von TensorFlow Hub.

Detektor wird geladen


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']

Das obige Modul ist "* SSD-basiertes Objekterkennungsmodell, das auf Open Images V4 mit ImageNet vorab trainiertem MobileNet V2 als Bildfeaturextraktor trainiert wurde. *". Darüber hinaus gibt es verschiedene Module für die "Bildobjekterkennung" auf dem Hub.

Wenn die Umgebungsvariable TFHUB_CACHE_DIR gesetzt ist, wird das erfasste Modul dort gespeichert (wenn es nicht angegeben ist, wird es irgendwo in / tmp gespeichert?).

TFHUB_CACHE_DIR.png

Objekterkennung durchführen

Schreiben Sie eine Funktion "run_detector (...)", die den oben geladenen "Detektor" und "Bilddateipfad" als Argumente verwendet, die Objekterkennung ausführt und das Ergebnis als Text ausgibt.

Die in der letzten Zeile aufgerufene Funktion "showImage (...)" wird später erstellt, daher werde ich sie hier auskommentieren.

Die Hauptpunkte sind wie folgt.

Funktionsdefinition zur Objekterkennung


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

def run_detector(detector, path):

  #Importieren Sie das Bild und konvertieren Sie es in ein Format, das in den Detektor eingegeben werden kann
  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) #Auf Eingabegröße reduzieren
  converted_img = np.array(converted_img, dtype=np.float32)     # np.In Array konvertieren
  converted_img = converted_img / 255. # 0.0 ~ 1.Normalisiert auf 0
  converted_img = converted_img.reshape([1,227,227,3])
  converted_img = tf.constant(converted_img)

  t1 = time.time()
  result = detector(converted_img) #Allgemeine Objekterkennung (Hauptkörper)
  t2 = time.time()
  print(f'Erkennungszeit: {t2-t1:.3f}Sekunden' )

  #Vorbereitung zur Ausgabe des Ergebnisses als Text
  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'] )

  #Punktzahl ist 0.Textausgabe für mehr als 25 Ergebnisse (n)
  print(f'Erkennungsobjekt' )
  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) #Überlagern Sie das Erkennungsergebnis auf dem Bild

Der obige "run_detector (...)" wird wie folgt aufgerufen:

Führen Sie dies aus, indem Sie den Bildpfad angeben


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

Hier habe ich das folgende Foto (kostenloses Material) für sample1.jpg verwendet.

sample8.jpg

Das Ausführungsergebnis ist wie folgt. Die Zahlen in Klammern sind die oberen linken und unteren rechten Koordinaten des Rechtecks, das das Objekt umgibt.

Erkennungszeit: 0.251 Sekunden
Erkennungsobjekt
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)

Mit einem solchen Text ist das Ergebnis schwer zu verstehen, daher werde ich es dem Bild überlagern.

Überlagern Sie das Erkennungsergebnis auf dem Bild

Schreiben Sie eine Funktion "showImage (...)", um das Erkennungsergebnis auf das Bild zu legen.

Überlagern Sie das Erkennungsergebnis auf dem Bild


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_Farbvorbereitung entsprechend Namen
  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)

  #Zeichnen Sie ein Rechteck Zeichnen Sie das Rechteck mit der niedrigsten Punktzahl
  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

    #Rahmen
    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: Text
    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: Hintergrund
    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 )

Entfernen Sie dann das auskommentierte in der letzten Zeile der Definition von "run_detector (...)" und führen Sie "run_detector (detector, img_path)" erneut aus.

Das folgende Ausführungsergebnis (Bild) wird erhalten. ダウンロード (1).png

Bonus

Wechseln Sie zu einem anderen Modul (Detektor) und versuchen Sie die Objekterkennung für dasselbe Bild (dies nimmt viel Zeit in Anspruch).

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']

Das Ausführungsergebnis ist wie folgt. Es dauert viele Male länger als zuvor, aber wir können mehr erkennen. ダウンロード (2).png

Erkennungszeit: 1.379 Sekunden
Erkennungsobjekt
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

Allgemeine Objekterkennung mit dem von Google vorab trainierten Modell (über TensorFlow Hub)
Logoerkennung mit der TensorFlow-Objekterkennungs-API
[Zusammenfassung] Objekterkennungsmodell "End-to-End-Objekterkennung mit Transformatoren" mit Transformer
[Für Anfänger] Ich habe versucht, die Tensorflow-Objekterkennungs-API zu verwenden
So erstellen Sie mit YOLO in 3 Stunden ein Modell für die Objekterkennung
Objekterkennung mit Jetson Nano (YOLOv3) - (1) Jetson Nano-Einstellungen-
Versuchen Sie die Objekterkennung in Echtzeit mit YOLOv2 (TensorFlow).